Arduino_touchshield_keyboard_setup_small
Reddit Twitter Digg Facebook Delicious Stumbleupon
14 images, 4 parts, 7 comments

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 :)

Parts for Mini Portable Arduino 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

Win Sep 27 2008

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

Matt Sep 27 2008

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… :)

ray Oct 13 2008

when i compile the arduino code i get “error: stray ’#’ in program In function ‘void loop()’:” please help ray

Matt Oct 14 2008

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!

ray Oct 14 2008

thank you

ray Oct 14 2008

the usb vdip modual should be used for datalogging the txt to a flashdrive

Danny Jul 01 2009

Do you know where to get a book on how to write code in the arduino software?



Add A Comment: