//Arduino PS/2 keyboard dvorak conversion
//now with added LCD (which does almost nothing..)
//moar infos: http://http://elektrickery.blogspot.com/
//keyboard device code from the PS2Dev library
//keyboard reading code credit goes to clackmannan from the old forums
#define VERSIONTEXT "SuperKeyboard1"
//for windows
#include "I:\Sketchbook\superkeyboard1\scancodes.h"
#include "I:\Sketchbook\libraries\ps2dev\ps2dev.cpp"
//for linux
//#include "/media/keyboard/sketchbook/libraries/ps2dev/ps2dev.cpp"
//#include "/media/keyboard/Sketchbook/superkeyboard1/scancodes.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(10, 11, 12, 13, 14, 15);
PS2dev kbd_pc(5,6); // 5 clock 6 data
int kbd_power = 2; // yellow wire - keyboard needs delayed powerup
int kbd_clock = 3; // white wire - interrupt 1
int synchdata = 4; // green wire - no interrupt
int pc_clock = 5; // white wire
int pc_data = 6; // green wire
int button = 7; // front pannel
int toggle = 8; // front pannel
int led = 9; // front pannel
/*
* LCD RS pin to digital pin 10
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 12
* LCD D5 pin to digital pin 13
* LCD D6 pin to digital pin 14 //this is ain0
* LCD D7 pin to digital pin 15 //this is ain1
*/
volatile int kbd_data;
volatile byte kbd_ptr;
byte scan;
byte scan_buffer[5];
void setup()
{
pinMode(kbd_clock,INPUT);
pinMode(synchdata,INPUT);
attachInterrupt(1,fallingclock,FALLING);
pinMode(toggle,INPUT);
digitalWrite(toggle, HIGH);
pinMode(button,INPUT);
digitalWrite(button, HIGH);
randomSeed(analogRead(0));
Serial.begin(115200);
lcd.begin(16, 2);
pinMode(led, OUTPUT);
pinMode(kbd_power, OUTPUT);
digitalWrite(kbd_power, HIGH);
Serial.println(VERSIONTEXT);
lcd.print(VERSIONTEXT);
lcd.setCursor(0, 1);
lcd.print(__DATE__);
}
void loop()
{
kbd_ptr = 0;
kbd_data = 0;
while(true)
{
if (digitalRead(toggle) == 0) digitalWrite(led, LOW);
else digitalWrite(led, HIGH);
//if we've captured a complete keystroke then send it to the host
if (11 == kbd_ptr)
{
scan_buffer_advance();
scan = (kbd_data >> 1) & 0xFF;
scan_buffer[0] = scan;
if (digitalRead(toggle) == 0) dvorak();
Serial.println(scan,HEX);
kbd_pc.write(scan);
kbd_ptr = 0;
kbd_data = 0;
}
// if (digitalRead(button) == 0)
}
}
void scan_buffer_clear()
{
scan_buffer[0] = 0;
scan_buffer[1] = 0;
scan_buffer[2] = 0;
scan_buffer[3] = 0;
scan_buffer[4] = 0;
}
void scan_buffer_advance()
{ //there has got to be a better way of doing this
scan_buffer[4]=scan_buffer[3];
scan_buffer[3]=scan_buffer[2];
scan_buffer[2]=scan_buffer[1];
scan_buffer[1]=scan_buffer[0];
}
void fallingclock()
{
// clock line falling, so kbd->host data
kbd_data = kbd_data | (digitalRead(synchdata) << kbd_ptr);
kbd_ptr ++ ;
}
void dvorak()
{
switch (scan)
{
case scan_q:
scan = scan_fslash; // /
scan_buffer_clear();
break;
case scan_w:
scan = scan_comma; //,
scan_buffer_clear();
break;
case scan_e:
scan = scan_fullstop; //.
scan_buffer_clear();
break;
case scan_r: //R
scan = scan_p; //P
scan_buffer_clear();
break;
case scan_t: //T
scan = scan_y; //Y
scan_buffer_clear();
break;
case scan_y: //Y
scan = scan_f; //F
scan_buffer_clear();
break;
case scan_u: //U
scan = scan_g; //G
scan_buffer_clear();
break;
case scan_i: //I
scan = scan_c; //C
scan_buffer_clear();
break;
case scan_o: //O
scan = scan_r; //R
scan_buffer_clear();
break;
case scan_p: //P
scan = scan_l; //L
scan_buffer_clear();
break;
case scan_a: //A
//scan = scan_a; //A
scan_buffer_clear();
break;
case scan_s: //S
scan = scan_o; //O
scan_buffer_clear();
break;
case scan_d: //D
scan = scan_e; //E
scan_buffer_clear();
break;
case scan_f: //F
scan = scan_u; //U
scan_buffer_clear();
break;
case scan_g: //G
scan = scan_i; //I
scan_buffer_clear();
break;
case scan_h: //H
scan = scan_d; //D
scan_buffer_clear();
break;
case scan_j: //J
scan = scan_h; //H
scan_buffer_clear();
break;
case scan_k: //K
scan = scan_t; //T
scan_buffer_clear();
break;
case scan_l: //L
scan = scan_n; //N
scan_buffer_clear();
break;
case scan_semic: //;
scan = scan_s; //S
scan_buffer_clear();
break;
case scan_bslash: // \
//scan = scan_bslash; // \
scan_buffer_clear();
break;
case scan_z: //Z
scan = scan_semic; //;
scan_buffer_clear();
break;
case scan_x: //X
scan = scan_q; //Q
scan_buffer_clear();
break;
case scan_c: //C
scan = scan_j; //J
scan_buffer_clear();
break;
case scan_v: //V
scan = scan_k; //K
scan_buffer_clear();
break;
case scan_b: //B
scan = scan_x; //X
scan_buffer_clear();
break;
case scan_n: //N
scan = scan_b; //B
scan_buffer_clear();
break;
case scan_m: //M
//scan = scan_m; //M
scan_buffer_clear();
break;
case scan_comma: //,
scan = scan_w; //W
scan_buffer_clear();
break;
case scan_fullstop: //.
scan = scan_v; //V
scan_buffer_clear();
break;
case scan_fslash: // /
if ((scan_buffer[1] != scan_extended)&&(scan_buffer[2] != scan_extended)) // to ignore num /
{
scan = scan_z; //Z
scan_buffer_clear();
break;
}
case scan_space:
case scan_ctrl:
case scan_alt:
case scan_lshift:
case scan_rshift:
case scan_caps:
case scan_tab:
case scan_return:
case scan_tilde:
case scan_1:
case scan_2:
case scan_3:
case scan_4:
case scan_5:
case scan_6:
case scan_7:
case scan_8:
case scan_9:
case scan_0:
case scan_minus:
case scan_equals:
case scan_backspace:
case scan_backslash:
case scan_f1:
case scan_f2:
case scan_f3:
case scan_f4:
case scan_f5:
case scan_f6:
case scan_f7:
case scan_f8:
case scan_f9:
case scan_f10:
case scan_f11:
case scan_f12:
case scan_scroll:
case scan_brk:
case scan_ins:
case scan_del:
case scan_home:
case scan_end:
case scan_pageup:
case scan_pagedown:
case scan_left:
case scan_right:
case scan_up:
case scan_down:
//case scan_numlock:
case scan_numstar:
case scan_numminus:
case scan_numplus:
//case scan_numenter:
//case scan_numpoint:
//case scan_num0:
//case scan_num1:
//case scan_num2:
//case scan_num3:
//case scan_num4:
case scan_num5:
//case scan_num6:
//case scan_num7:
//case scan_num8:
//case scan_num9:
scan_buffer_clear();
break;
}
}