/********************************************************** JI3BNB RTTY ENCODER for ARDUINO UNO <Simple Version> 2016.06.25 v3.1 5BIT-BAUDOT-CODE, 45.45baud LCD 16x2 (SC1602BBWB-XA-GB-G) or 20x4 (UC-204) /**********************************************************/ #include <LiquidCrystal.h> #include <TimerOne.h> #include <FlexiTimer2.h> #include <PS2Keyboard.h> LiquidCrystal lcd(4,5,6,7,8,9,10); const boolean lcdType = 0; // ***** 16x2: 0 / 20x4: 1 ***** #define MARK 346 // 346 = (500000 / 1445 Hz) #define SPACE 392 // 392 = (500000 / 1275 Hz) /* #define MARK 218 // 218 = (500000 / 2295 Hz) #define SPACE 235 // 235 = (500000 / 2125 Hz) */ PS2Keyboard keyboard; const int DataPin = 2; //PS/2 DATA const int IRQpin = 3; //PS/2 CLOCK boolean ddl = 1; //DIDDLE ENABLE boolean space; boolean crLf; boolean snd; int fig_2; int ti; byte x; char ch; uint8_t baudot; void setup() { if(lcdType == 0) { lcd.begin(16, 2); } else { lcd.begin(20, 4); } lcd.cursor(); lcd.setCursor(0, 0); keyboard.begin(DataPin, IRQpin); pinMode(12, OUTPUT); //--AFSK AUDIO OUTPUT pinMode(13, OUTPUT); //--TTL LEVEL OUTPUT digitalWrite(13, 1); Timer1.initialize(); Timer1.attachInterrupt(timer1_interrupt, MARK); FlexiTimer2::set(1, timer2_interrupt); FlexiTimer2::start(); } //AFSK TONE GENERATOR void timer1_interrupt(void) { static boolean toggle; toggle = toggle ^ 1; digitalWrite(12, toggle); } //5BIT BAUDOT GENERATOR void timer2_interrupt(void) { static boolean bit1; static boolean bit2; static boolean bit3; static boolean bit4; static boolean bit5; if(snd == 1) { switch(ti) { case 0: digitalWrite(13, 0); Timer1.setPeriod(SPACE); bit1 = baudot & B00001; bit2 = baudot & B00010; bit3 = baudot & B00100; bit4 = baudot & B01000; bit5 = baudot & B10000; break; case 22: digitalWrite(13, bit1); if(bit1){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 44: digitalWrite(13, bit2); if(bit2){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 66: digitalWrite(13, bit3); if(bit3){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 88: digitalWrite(13, bit4); if(bit4){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 110: digitalWrite(13, bit5); if(bit5){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 132: digitalWrite(13, 1); Timer1.setPeriod(MARK); break; case 165: snd = 0; break; } ti++; } } //CONTROLS 16x2 or 20x4 LCD DISPLAY void lcdOut() { static byte y; int i; if(lcdType == 0) //16x2 { static char c[17]; lcd.print(ch); c[x] = ch; x++; if(x == 16 && y == 0) { x = 0; y = 1; } else if(x == 16 && y == 1) { lcd.clear(); lcd.noCursor(); for(i = 0; i < 16; i++) { lcd.print(c[i]); } lcd.cursor(); x = 0; y = 1; } lcd.setCursor(x, y); } else //20x4 { static char c[61]; lcd.print(ch); if(y == 1){c[ x] = ch;} else if(y == 2){c[20 + x] = ch;} else if(y == 3){c[40 + x] = ch;} x++; if(x == 20 && y == 0){x = 0, y = 1;} else if(x == 20 && y == 1){x = 0, y = 2;} else if(x == 20 && y == 2){x = 0, y = 3;} else if(x == 20 && y == 3) { lcd.clear(); lcd.setCursor(0, 0); for(i = 0; i < 20; i++){lcd.print(c[ i]);} lcd.setCursor(0, 1); for(i = 0; i < 20; i++){lcd.print(c[20 + i]);} lcd.setCursor(0, 2); for(i = 0; i < 20; i++){lcd.print(c[40 + i]);} x = 0, y = 3; for(i = 0; i < 20; i++){c[ i] = c[20 + i];} for(i = 0; i < 20; i++){c[20 + i] = c[40 + i];} } lcd.setCursor(x, y); } } void lcdCrLf() { byte rest; if(lcdType == 0) { rest = (16 - x); } else { rest = (20 - x); } ch = ' '; for(int i = 0; i < rest; i++) //FILL THE LINE WITH SPACES, INSTEAD OF CR&LF { lcdOut(); } } //LOOK UP TABLE void chTable() { fig_2 = -1; switch(ch) { case 'A': baudot = B00011; fig_2 = 0; break; case 'B': baudot = B11001; fig_2 = 0; break; case 'C': baudot = B01110; fig_2 = 0; break; case 'D': baudot = B01001; fig_2 = 0; break; case 'E': baudot = B00001; fig_2 = 0; break; case 'F': baudot = B01101; fig_2 = 0; break; case 'G': baudot = B11010; fig_2 = 0; break; case 'H': baudot = B10100; fig_2 = 0; break; case 'I': baudot = B00110; fig_2 = 0; break; case 'J': baudot = B01011; fig_2 = 0; break; case 'K': baudot = B01111; fig_2 = 0; break; case 'L': baudot = B10010; fig_2 = 0; break; case 'M': baudot = B11100; fig_2 = 0; break; case 'N': baudot = B01100; fig_2 = 0; break; case 'O': baudot = B11000; fig_2 = 0; break; case 'P': baudot = B10110; fig_2 = 0; break; case 'Q': baudot = B10111; fig_2 = 0; break; case 'R': baudot = B01010; fig_2 = 0; break; case 'S': baudot = B00101; fig_2 = 0; break; case 'T': baudot = B10000; fig_2 = 0; break; case 'U': baudot = B00111; fig_2 = 0; break; case 'V': baudot = B11110; fig_2 = 0; break; case 'W': baudot = B10011; fig_2 = 0; break; case 'X': baudot = B11101; fig_2 = 0; break; case 'Y': baudot = B10101; fig_2 = 0; break; case 'Z': baudot = B10001; fig_2 = 0; break; case '0': baudot = B10110; fig_2 = 1; break; case '1': baudot = B10111; fig_2 = 1; break; case '2': baudot = B10011; fig_2 = 1; break; case '3': baudot = B00001; fig_2 = 1; break; case '4': baudot = B01010; fig_2 = 1; break; case '5': baudot = B10000; fig_2 = 1; break; case '6': baudot = B10101; fig_2 = 1; break; case '7': baudot = B00111; fig_2 = 1; break; case '8': baudot = B00110; fig_2 = 1; break; case '9': baudot = B11000; fig_2 = 1; break; case '-': baudot = B00011; fig_2 = 1; break; case '?': baudot = B11001; fig_2 = 1; break; case ':': baudot = B01110; fig_2 = 1; break; case '(': baudot = B01111; fig_2 = 1; break; case ')': baudot = B10010; fig_2 = 1; break; case '.': baudot = B11100; fig_2 = 1; break; case ',': baudot = B01100; fig_2 = 1; break; case '/': baudot = B11101; fig_2 = 1; break; case '\r': baudot = B01000; //CR crLf = 1; break; case ' ': baudot = B00100; //SPACE space = 1; break; default: ch = ' '; baudot = B00100; //SPACE space = 1; break; } } void chConvt() { if(ch >= 97 && ch <= 122) //CONVERT LOWER CASE TO UPPER CASE { ch = ch - 32; } else if(ch == PS2_TAB ){ch = '\0';} //IGNORE THESE KEYS else if(ch == PS2_BACKSPACE ){ch = '\0';} else if(ch == PS2_ESC ){ch = '\0';} else if(ch == PS2_DELETE ){ch = '\0';} else if(ch == PS2_PAGEUP ){ch = '\0';} else if(ch == PS2_PAGEDOWN ){ch = '\0';} else if(ch == PS2_UPARROW ){ch = '\0';} else if(ch == PS2_LEFTARROW ){ch = '\0';} else if(ch == PS2_DOWNARROW ){ch = '\0';} else if(ch == PS2_RIGHTARROW){ch = '\0';} else if(ch == '!' ){ch = '\0';} else if(ch == '"' ){ch = '\0';} else if(ch == '#' ){ch = '\0';} else if(ch == '$' ){ch = '\0';} else if(ch == '%' ){ch = '\0';} else if(ch == '&' ){ch = '\0';} else if(ch == '\'' ){ch = '\0';} else if(ch == '=' ){ch = '\0';} else if(ch == '^' ){ch = '\0';} else if(ch == '~' ){ch = '\0';} else if(ch == '|' ){ch = '\0';} else if(ch == '@' ){ch = '\0';} else if(ch == '`' ){ch = '\0';} else if(ch == '[' ){ch = '\0';} else if(ch == '{' ){ch = '\0';} else if(ch == ';' ){ch = '\0';} else if(ch == '+' ){ch = '\0';} else if(ch == '*' ){ch = '\0';} else if(ch == ']' ){ch = '\0';} else if(ch == '}' ){ch = '\0';} else if(ch == '<' ){ch = '\0';} else if(ch == '>' ){ch = '\0';} else if(ch == '\\' ){ch = '\0';} else if(ch == '_' ){ch = '\0';} } void loop() { static boolean shift; static boolean fig_1; static uint8_t baudot_; if(snd == 0) { if(shift == 1) //2ND BYTE AFTER SENDING SHIFT CODE { baudot = baudot_; //RESTORE lcdOut(); shift = 0; ti = 0; snd = 1; //SEND(2) } else if(crLf == 1) //2ND BYTE AFTER SENDING "CR" { baudot = B00010; //LF lcdCrLf(); crLf = 0; ti = 0; snd = 1; //SEND(2) } else //SENDING 2ND BYTE DONE { if (keyboard.available()) //KEYBOARD IS TYPED { ch = keyboard.read(); chConvt(); if(ch != '\0') { chTable(); if(fig_1 == 0 && fig_2 == 1) //SHIFT "UP" { baudot_ = baudot; //EVACUATE baudot = B11011; //SEND FIGURE CODE FIRST shift = 1; } else if(fig_1 == 1 && fig_2 == 0) //SHIFT "DOWN" { baudot_ = baudot; //EVACUATE baudot = B11111; //SEND LETTER CODE FIRST shift = 1; } else if(space == 1 && fig_2 == 1) //FIGURE AFTER SPACE (TX_UOS) { baudot_ = baudot; //EVACUATE baudot = B11011; //SEND FIGURE CODE FIRST shift = 1; } if(shift != 1 && crLf != 1) { lcdOut(); } if(fig_2 == 0 || fig_2 == 1) { space = 0; fig_1 = fig_2; //REGISTER LAST STATE (EXCEPT SPACE, CR&LF) } ti = 0; snd = 1; //SEND(1) } } else //NOTHING TO PROCESS, DIDDLE { if(ddl == 1) { baudot = B11111; //LTR(DIDDLE) fig_1 = 0; ti = 0; snd = 1; } } } } delay(5); }