/********************************************************** ASCII 8N2 50baud RTTY(T) v1.00 2016.11.30 /**********************************************************/ #include <LiquidCrystal.h> #include <TimerOne.h> #include <FlexiTimer2.h> #include <PS2Keyboard.h> LiquidCrystal lcd(4,5,6,7,8,9,10); /* #define MARK 294 // 294 = (500000 / 1700 Hz) #define SPACE 392 // 392 = (500000 / 1275 Hz) */ #define MARK 346 // 346 = (500000 / 1445 Hz) #define SPACE 392 // 392 = (500000 / 1275 Hz) PS2Keyboard keyboard; const int DataPin = 2; //PS/2 DATA const int IRQpin = 3; //PS/2 CLOCK boolean snd; boolean org; int ti; int x; byte y; char ch; char c[33]; void setup() { Serial.begin(9600); lcd.begin(16, 2); 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); } //8BIT ASCII GENERATOR void timer2_interrupt(void) { static boolean bit1; static boolean bit2; static boolean bit3; static boolean bit4; static boolean bit5; static boolean bit6; static boolean bit7; static boolean bit8; if(snd == 1) { switch(ti) { case 0: digitalWrite(13, 0); Timer1.setPeriod(SPACE); bit1 = ch & B00000001; bit2 = ch & B00000010; bit3 = ch & B00000100; bit4 = ch & B00001000; bit5 = ch & B00010000; bit6 = ch & B00100000; bit7 = ch & B01000000; bit8 = ch & B10000000; break; case 20: digitalWrite(13, bit1); if(bit1){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 40: digitalWrite(13, bit2); if(bit2){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 60: digitalWrite(13, bit3); if(bit3){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 80: digitalWrite(13, bit4); if(bit4){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 100: digitalWrite(13, bit5); if(bit5){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 120: digitalWrite(13, bit6); if(bit6){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 140: digitalWrite(13, bit7); if(bit7){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 160: digitalWrite(13, bit8); if(bit8){Timer1.setPeriod(MARK);} else{Timer1.setPeriod(SPACE);} break; case 180: digitalWrite(13, 1); Timer1.setPeriod(MARK); break; case 220: snd = 0; break; } ti++; } } //DISPLAYS CHARACTER void lcdOut() { int i; lcd.print(ch); c[16 * y + x] = ch; x++; if(x == 16 && y == 0) { x = 0; y = 1; } else if(x == 16 && y == 1) { for(i = 0; i < 16; i++) { c[i] = c[16 + i]; } for(i = 0; i < 16; i++) { c[16 + i] = '\0'; } lcd.clear(); lcd.noCursor(); for(i = 0; i < 16; i++) { lcd.print(c[i]); } lcd.cursor(); x = 0; y = 1; } lcd.setCursor(x, y); } //HANDLES BACKSPACE void lcdBs() { int i; if(x == 0 && y == 0) { org = true; } else { org = false; x--; if(x == -1 && y == 1) { x = 15; y = 0; while(c[x] == '\0') { x--; } lcd.noCursor(); lcd.setCursor(x, y); lcd.print(" "); lcd.setCursor(x, y); lcd.cursor(); c[x] = '\0'; } else { lcd.noCursor(); lcd.setCursor(x, y); lcd.print(" "); lcd.setCursor(x, y); lcd.cursor(); c[16 * y + x] = '\0'; } } } //HANDLES CRLF void lcdCrLf() { byte skip = (16 - x); int i; lcd.noCursor(); for(i = 0; i < skip; i++) { if(i == 0) { c[16 * y + x] = '\r'; } else { c[16 * y + x] = '\0'; } x++; } if(y == 0) { x = 0; y = 1; } else { for(i = 0; i < 16; i++) { c[i] = c[16 + i]; } for(i = 0; i < 16; i++) { c[16 + i] = '\0'; } lcd.clear(); for(i = 0; i < 16; i++) { if(c[i] == '\r' || c[i] == '\0') { lcd.print(' '); } else { lcd.print(c[i]); } } x = 0; y = 1; } lcd.setCursor(x, y); lcd.cursor(); } void chIgnore() { if(ch == PS2_TAB ){ch = '\0';} //IGNORE THESE KEYS else if(ch == PS2_ESC ){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';} } void loop() { static boolean crLf; if(snd == 0) { if(crLf == 1) { crLf = 0; lcdCrLf(); ch = '\n'; ti = 0; snd = 1; //2nd byte } else if (keyboard.available()) { ch = keyboard.read(); chIgnore(); if(ch != '\0') { if(ch == PS2_BACKSPACE || ch == PS2_DELETE) { lcdBs(); if(org == false) { ch = 0x08; //BS ti = 0; snd = 1; //1st byte } } else if(ch == '\r') { crLf = 1; ti = 0; snd = 1; //1st byte } else { lcdOut(); ti = 0; snd = 1; //1st byte } } } } delay(5); }