Mini Portable Arduino Laptop
I finally figured out how to decode PS/2 keyboard signals through the Arduino, and so I made a little device that read the values of a keyboard, and then piped them back up through the TouchShield, to display text. It’s kind of like having a small little Arduino-powered palm top or laptop :)
The first step was putting together the gadget, which meant plugging an Arduino underneath an ExtenderShield, with a Lithium Backpack for power (the keyboard needs to be powered too), and a TouchShield on top. In order to power the device, I connected a wire from the Lithium Backpack’s 5V to the TouchShield’s 5 pin, and the Backpack’s GND to the TouchShield’s G pin.

Then, I opened up the end of a PS/2 extension cable, and soldered 4 wires to ground, +5V, data, and signal. I found the reference over at this site really helpful (thanks!).
Then I plugged the ground and +5V wires into free headers on the right side of the ExtenderShield, labeled G and 5V:

Here’s a view of the gadget so far:

The rest of the project is pretty much all in source code. Here’s the little snippet of code that runs on the TouchShield:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
COLOR green = { 0, 255, 0 };
COLOR blue = {0,0,255};
COLOR yellow = {255,255,0};
COLOR BLACK = {0,0,0};
COLOR grey = {0x77,0x77,0x77};
COLOR red = {255,0,0};
COLOR WHITE = {255,255,255};
LCD_RECT screenRect = { 0, 0, 127, 127 };
unsigned char x;
int px, py;
void setup()
{
lcd_rect(screenRect,BLACK,BLACK);
Serial.begin(9600);
delay(3000);
Serial.print('U');
px = 1;
py = 5;
}
void loop()
{
x = Serial.read();
lcd_putc(x,px,py,WHITE,BLACK);
px += 10;
if (px >= 120) {
px = 1;
py += 10;
}
if (py >= 120) {
py = 5;
lcd_rect(screenRect,BLACK,BLACK);
}
}
|
And here’s the little snippet that runs on the Arduino. It’s definitely not the most elegant piece of code ever written, but basically it gets the job done (sorta). It reads the raw signal from the keyboard, stores it in a number. Then, it looks up the number in a big array until it finds a match. When it has the number of the pointer into the array that matches, it then looks up the corresponding pointer in another array, which returns the character it’ll spit out. There’s a bunch of weird if-then-else checking code I threw into the loop() section to deal with weird ‘i’ characters. I’m not entirely sure where they’re coming from, and what they’re doing in there, but at least it works now… I think it has something to do with the timing, which seems to be pretty finicky (a lot of other guys on the web have had difficulty here too):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
#include <AFSoftSerial.h> #define RXPIN 3 #define TXPIN 2 AFSoftSerial mySerial = AFSoftSerial(RXPIN, TXPIN); #define CLK 4 #define DAT 5 int dat[20]; long num; void setup() { pinMode(CLK, INPUT); pinMode(DAT, INPUT); mySerial.begin(9600); Serial.begin(9600); Serial.println("hi"); //delay(1000); while(mySerial.read() != 'U'); } int numlook[] = { 120, 398, 518, 902, 70, 950, 78, 910, 14, 958, 384, 944, 446, 526, 64, 624, 584, 630, 952, 118, 126, 438, 632, 390, 590, 440,//z 456,//1 504, 454, 582, 502, 462, 638, 510, 448, 576,//0 462,//esc 496,//- 584,//= 632,//\ 496,//~ 624,//tab 72,//[ 952,//] 454,//delete 72,//control 112,//; 392,//' 392,//left shift 512,//, 560,//. 432,// / 568,//right shift 520,//alt 566//space }; int charfind[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',//z '1',//1 '2', '3', '4', '5', '6', '7', '8', '9', '0',//0 'E',//esc '-',//- '=',//= '\\',//\ '`',//~ 'T',//tab '[',//[ ']',//] '<',//delete ' ',//control ';',//; '\'',//' ' ',//left shift ',',//, '.',//. '/',// / ' ',//right shift ' ',//alt ' '//space }; char lastchar = 0; char lastlastchar = 0; int sincelastchar = 1; void loopold() { while( digitalRead(DAT) ) { } while( digitalRead(CLK) ) { } num = 0; for (int i = 0;i<11;i++){ dat[i] = digitalRead(DAT); num = num + dat[i]; num = num << 1; delayMicroseconds(50); } delayMicroseconds(1000); Serial.println(num, DEC); lastlastchar = lastchar; lastchar = num; } void loop(void) { char string[6]; string[5]=0; char thischar; char finalchar; thischar = getpress(); finalchar = -1; if ((lastchar == 'i') && (lastlastchar == '8') && thischar == '-') { finalchar = '`'; } else if ((lastchar == 'i') && (lastlastchar == '8') && thischar == 'w') { finalchar = '\\'; } else if ((lastchar == 'i') && (lastlastchar == '6') && thischar == '6' && sincelastchar >= 4) { finalchar = 'i'; } else if ((lastchar == 'i') && (lastlastchar == '8') && thischar == '6') { finalchar = 'i'; } else if (lastchar == 'i') { finalchar = thischar; } if (finalchar != -1) { sincelastchar = 0; Serial.println(finalchar,BYTE); serial_sendChar(finalchar); } lastlastchar = lastchar; lastchar = thischar; sincelastchar++; } char getpress( void) { int thechar; char retchar; while( digitalRead(DAT) ) { } while( digitalRead(CLK) ) { } num = 0; for (int i = 0;i<11;i++){ num = num + digitalRead(DAT); num = num << 1; delayMicroseconds(50); } thechar = findref(num); retchar = charfind[thechar]; delayMicroseconds(100); return retchar; } int findref(int num) { int ret=-1; int maxsize = sizeof(numlook) / sizeof(int); for ( int i=0 ; i<maxsize ; i++) { if (numlook[i] == num) { ret = i; break; } } return ret; } void serial_sendChar(char theChar) { mySerial.print(theChar,BYTE); delay(2); } |
Finally, I uploaded the code to the Arduino and the TouchShield, and turned the power on:

Of course when I was actually writing the code, it definitely didn’t work on the first try, but after about a dozen tries and some debugging, it worked out pretty well!

Let me know if it doesn’t work for any reason, and I’ll try to work it out… otherwise, I’d be curious if you make anything cool with it!

7 Comments on Mini Portable Arduino Laptop
Thanks! Actually, that’s not a bad idea… plus I’ve been meaning to figure out how to use bluetooth for a while now. I think I’ll go figure out how to use USB now… :)
when i compile the arduino code i get “error: stray ’#’ in program In function ‘void loop()’:” please help ray
Hi ray,
Sorry about the confusion, there was an error in the website changing ”&” characters into invalid ones- Everything seems to look better now so give it another go!
thank you
the usb vdip modual should be used for datalogging the txt to a flashdrive
Do you know where to get a book on how to write code in the arduino software?








Very cool. What do you think about bluetooth for the keyboard to sever the keyboard cord?