Hello,
I had an old Palm portable keyboard lying around my house and I have been trying to modify it to work over USB so that I can use it with my phone.
Instead of writing a driver which I do not have the expertise to do, I am trying to build an Arduino interface to go between the keyboard and phone.
I am having an issue getting the keyboard to send it's initiation pulse, saying that it is powered. I do not even know if I am reading the data properly. I have everything wired as stated on page six of this manual.http://www.splorp.com/pdf/stowawayhwref.pdf
This document also describes the base requirements for the keyboard interface.
Can you guys please help me figure out what I am doing wrong?
I have been working on this for over a year and would really like to get it working before September!
Code written for Arduino Micro but tested on Arduino Uno (No keyboard emulation)
#include <SoftwareSerial.h>;
#include <Keyboard.h>;
char KEY_LEFT_CTRL =128;
char KEY_LEFT_SHIFT =129;
char KEY_LEFT_ALT =130;
char KEY_LEFT_GUI =131;
char KEY_RIGHT_CTRL =132;
char KEY_RIGHT_SHIFT =133;
char KEY_RIGHT_ALT =134;
char KEY_RIGHT_GUI =135;
char KEY_UP_ARROW =218;
char KEY_DOWN_ARROW =217;
char KEY_LEFT_ARROW =216;
char KEY_RIGHT_ARROW =215;
char KEY_BACKSPACE =178;
char KEY_TAB =179;
char KEY_RETURN =176;
char KEY_ESC =177;
char KEY_INSERT =209;
char KEY_DELETE =212;
char KEY_PAGE_UP =211;
char KEY_PAGE_DOWN =214;
char KEY_HOME =210;
char KEY_END =213;
char KEY_CAPS_LOCK =193;
char KEY_F1 =194;
char KEY_F2 =195;
char KEY_F3 =196;
char KEY_F4 =197;
char KEY_F5 =198;
char KEY_F6 =199;
char KEY_F7 =200;
char KEY_F8 =201;
char KEY_F9 =202;
char KEY_F10 =203;
char keys[8][12] = {{'1',KEY_LEFT_GUI,'x',KEY_CAPS_LOCK,0,0,'-','[','\\',0,KEY_DELETE,KEY_LEFT_SHIFT},
{'2','q','a',KEY_TAB,0,0,'=',']',KEY_RETURN,KEY_UP_ARROW,KEY_LEFT_ARROW,KEY_RIGHT_SHIFT},
{'3','w','s',KEY_LEFT_CTRL,0,0,KEY_BACKSPACE,'/',0,0,KEY_DOWN_ARROW,0},
{'z','e','d',0,KEY_LEFT_ALT,0,0,0,0,0,KEY_RIGHT_ARROW,0},
{'4','r','f',0,0,'c','8','u','j','m',0,0},
{'5','t','g',0,0,'v','9','i','k',',',0},
{'6','y','h',0,0,'b','0','o','l','.',0,0},
{'7','`',' ',0,0,'n',' ','p',';',0,0,0}}; //This is the full keymatrix from the manufacturer.
/*char capitolKeys[8][12] = {{'!',KEY_LEFT_GUI,'X',KEY_CAPS_LOCK,0,0,'_','{','\"','?',KEY_DELETE,KEY_LEFT_SHIFT},
{'@','Q','A',KEY_TAB,0,0,'+','}',KEY_RETURN,KEY_UP_ARROW,KEY_LEFT_ARROW,KEY_TRIGHT_SHIFT},
{'#','W','S',KEY_LEFT_CTRL,0,0,KEY_BACKSPACE,'|',0,0,KEY_DOWN_ARROW,0},
{'Z','E','D',0,KEY_LEFT_ALT,0,0,0,0,0,KEY_RIGHT_ARROW,0},
{'
,'R','F',0,0,'C','8','U','J','M',0,0},
{'%','T','G',0,0,'V','9','I','K','<',0,0},
{'^','Y','H',0,0,'B','0','O','L','>',0,0},
{'&','~',' ',0,0,'N',' ','P',':',0,0,0}}; //capitols unused at the moment because I think that sending shift and a key in conjunction will cover that, and this was causing other errors.*/
//const int VCC = 0; //power //wired to 5v out instead
const int RXD = 4; //output signal of keyboard (RX)
const int RTS = 5; //input signal to keyboard (TX)
const int HotSync = 2;//output used for handshake (bi directional?)(NOT BIDIRECTOIONAL)
const int VCC = 3; //power line for keyboard;
SoftwareSerial softSerial = SoftwareSerial(RXD, RTS);
boolean on = false;
boolean isLast = false;
int keyCount = 0;
int LSB = 0;
int YADD = 0;
int XADD = 0;
int lastKey = 0;
int data[2];
char buffer[8];
int RTSState = LOW;
void setup(){
pinMode(RXD, INPUT);
pinMode(RTS, OUTPUT);
pinMode(HotSync, INPUT);
pinMode(VCC, OUTPUT);
Serial.begin(9600);
softSerial.begin(9600);
//Keyboard.begin();
keyCount=0;
}
void loop(){
while(!on){ //on preboot
Serial.println("Checking for initiation pulse");
digitalWrite(VCC, HIGH); //poke it for sync
while(digitalRead(HotSync)==LOW){}//wait for initiation pulse
Serial.println("Pulse recieved");
Serial.println("Checking for keyboard");
checkForKeyboard();
}
//start detecting key presses
if(keyCount==10){
Serial.println("10 keys, checking for keyboard");
checkForKeyboard();//safety, check for keyboard every 10 keys
keyCount=0;
}
Serial.print("reading next byte: ");
if(softSerial.available()){
int data = softSerial.read(); //this reads ONLY the next byte
Serial.println(data);
LSB=0; //last bit
YADD=0; //four bits after first three
XADD=0;//first three bits
sprintf(buffer, "%03i", data);
LSB = buffer[7]; //split all the bits into their respective chunks
for(int x=3;x<7;x++)
YADD =+ buffer[x];
for(int x=0;x<3;x++)
XADD =+ buffer[x];
Serial.print("LSB: ");Serial.println(LSB,BIN);
Serial.print("YADD: ");Serial.println(YADD,BIN);
Serial.print("XADD: ");Serial.println(XADD,BIN);
if(lastKey==data){ //double release is keyboard code for last key in stream, this is when you are supposed to kill all modifiers
Serial.println("Last key, releasing all keys");
//Keyboard.releaseAll();
}
if(LSB==0){//if the key state is pressed
Serial.print("Press: ");
Serial.println(keys[XADD][YADD]);
//Keyboard.release(keys[XADD][YADD]); //press the key
}else{ //if key state is released
Serial.print("Release: ");
Serial.println(keys[XADD][YADD]);
//Keyboard.press(keys[XADD][YADD]); //release the key
}
lastKey=data; //store current key for last key check
keyCount++;//add until 10 keys for keyboard check
}else{Serial.println("overflow/not available");}
}
void checkForKeyboard(){ //this is hardware spec
if(RTSState==LOW){ //if board is is sleep state
digitalWrite(RTS, HIGH); //send wake pulse
RTSState=HIGH;
}else{
digitalWrite(RTS, LOW);
digitalWrite(RTS, HIGH);//if you see low (keyboard went into low power mode) wake it up with a high
RTSState=HIGH;
}
while(softSerial.available()>0){
int x=0;
data[x] = softSerial.read(); //read the return message
x++;
}
Serial.print(data[0], HEX);Serial.println(data[1], HEX);
if((data[0] == (int)0xFA) &&(data[1] == (int)0xFD)){ //identify return key (ID), if it is the keyboard, allow key read operations
on=true;
Serial.println("Found it!");
}else{
digitalWrite(RTS, LOW); //if it does not return a valid ID, shut everything down, the board is disconnected.
RTSState=LOW;
//Keyboard.end();
Serial.println("no keyboard, shutting down");
}
//delay(1000); //no idea why I need this, I think it is for buffer overload or board catchup. (seems to help)
delay(1000);
}
[/code]
