Introduction: PICAXE - Interface a PS2 Keyboard With an LCD

This project uses a PICAXE 20X2 microcontroller to interface an old style PS2 keyboard with a 2 X 16 LCD. The program is quite lengthy and is probably not perfect but most functions seem to work. Because some special keys use a preceeding $E0 character which the PICAXE Kbin command ignores, I was not able to decode them. This is my second PICAXE project so there are probably more elegant ways to program these functions, this is just the way that I figured out to do it on my own as very much a beginner.

The PICAXE has been programmed to ignore most keys that don't have much use in this application such as the up and down arrow, ALT, esc, break etc keys for example. CAP lock and Shift work. Shift behaves like CAP lock, press down once and it stays on until you press Shift again. It also displays "CAP" or "SHF" at the top right of line 1 to show that the function is active. The 20X2 has been programmed so that when Line 2 of the LCD display is full, pressing the key for any displayed or right cursor moving character will clear the display and return the cursor to start of Line 2. You will then need to press the key again to get it to display. Also I find that this keyboard to LCD interface is not fast. You need to wait about 1/2 sec after each keypress before it is ready to accept another keypress. I did not persue this because I don't need it to be fast, but suspect that this could be made faster by buffering the incoming characters in multiple variables.

The program is included and you will be able to follow how it works by reading the comments which are quite detailed. They are detailed because I left off working on this program for about a month and was totally lost when I came back to it, so I wanted to make sure that did not happen again. You can easily modify this program to use the keys that are currently ignored. Also, it will be fairly obvious to anyone familiar with PICAXE that this program and hardware can be modified so that instead of displaying characters on an LCD, you could control just about anything - relays, servos, logic, lights etc with a keyboard using this kind technique. I will leave it to the ambitious to do that!

Step 1: Parts List

Parts List:
Clear project box (Hammond 1591CTCL - it is a tight fit but works if you place components carefully)
PICAXE 20X2 Microcontroller
16 X 2 LCD - UniQ/eVision GC-1602I1 or equivalent
PS2 Keyboard
6 Pin Female mini-DIN to match keyboard connector (Bulkhead)
5V wall wart - SPS10A-001 or equivalent for 5V power supply (e.g. 9V battery and LM7805 regulator)
(You can also use a battery and clip, e.g. 3 x AAA instead of a wall wart - but do not exceed 5V!!)
A jack which matches the power connector on your wall wart
3.5 mm Stereo Jack - Programming connection
PICAXE USB Programming Cable AXE027
5K Potentiometer
10k resistor
22k resistor
2 x 4.7k resistors
Solder
Hook up wire
2" x 6" Breadboard or equivalent,                                                                                                                                                                PCB to fit in box,                                                                                                                                                                              Pushbutton latching on/off switch,                                                                                                                                                                                                          LM7805 (1A) Voltage Regulator,                                                                                                                                                                                              0.01 UF 16V capacitor,                                                                                                                                                                                                   4 - 1/4" standoffs,                                                                                                                                                                                                   8 - 4-40 nuts & bolts,                                                                                                                                                                               9V battery clip and 9V battery.                                                                                                                                                        

Step 2: Breadboard It

To date I have this working on a breadboard and have now completed the future ambition of soldering this together on a PCB and putting it in a box. To breadboard it you can just solder wires to the DIN connector and 3.5 mm jack for connecting your keyboard and computer to the 20X2. Here you see it working on the breadboard and using an old Compaq PS2 keyboard that I bought from A1 electronics in Toronto for $5.

Step 3: The Program

Below is a text version of the program with comments. I will attach a copy of the full.bas program at the end of this instructable.
Read the comments to understand how this works.

' ************** KeyBoardReader.bas **************

' This program runs on a PICAXE-20X2 at 4MHz which reads the characters from a
' PS2 computer keyboard & sends it to an HD44780 compatible 16x2 LCD display.
' Note that special characters with E0 leading, such as most of the right key pad, are not displayed.
' Developed and Copyright by Simon Carter April 20, 2013 - you may use it for personal use only, use at your own risk
' this program was written by an amateur programmer as an example for hobby use only and as such you may not rely
' on it to be be perfect or bug free.

' *** Constants ***
symbol EnablePin = C.7      ' LCD Enable pin connected to C.7
symbol RegSelPin = C.4      ' LCD Register Selelect pin connected to C.4
symbol KeyBoard = C.1      ' Keyboard data connected to C.1

' *** Variables ***
symbol   char   = b0     ' used to hold characters to be sent to LCD
symbol  index  = b1     ' used as counter in For-Next loops
symbol  keybd  = b2     ' character received from the ketboard
symbol   flag   = b3     ' a flag used to indicate that backspace or delete key has been used i.e. LCD cursor moves left
symbol   capflag  = b4     ' a flag used to indicate that the CAPS lock key has been pressed
symbol  shftflag  = b5     ' a flag used to indicate that the Shift key has been pressed - this program treats one press as locked down
symbol       j  = b6     ' a counter that keeps track of the LCD cursor position on line 2 of the LCD at all times
symbol  capindf = b7     ' a flag used to indicate that "CAPS" is being displayed on line 1 of the LCD i.e. CAPS lock is on.
symbol  capclearf = b8     ' a flag used to indicate that the CAPS lock key is off and "CAPS" is cleared from the display on line 1 of the LCD
symbol shftindf = b9     ' a flag used to indicate that "SHF" is being displayed on line 1 of the LCD i.e. Shift lock is on.
symbol shftclearf = b10     ' a flag used to indicate that the Shift lock key is off and "SHF" is cleared from the display on line 1 of the LCD
symbol keyrem = b11     ' used to hold the character from the keyboard right as it comes in
symbol ignore = b12
' *** Directives ***
#com 3        ' specify download port
#picaxe 20X2       ' specify processor
#no_data        ' save time downloading
#terminal off       ' disable terminal window
     

' *** Table ***
Table  0, ("Type letters:   ")    ' displays "Type Letters:" on line 1 of the LCD

' *** Main Program ***
  dirsB = %11111111       ' set all portB pins as outputs
  dirsC = %11111101       ' set  C.1 as input, C2 as an output
  flag = 0        ' next few steps initialize some flags
  j = 0
  capindf = 0
  capclearf = 1
  shftindf = 0
  shftclearf = 1
  ignore = 0
 
' *** Initialize the LCD ***        
pause 200        ' pause 200 mS for LCD initialization as per HD44780 specs
char = 56        ' setup for 8-bits, 2 lines & 5X8 display
  gosub CmdLCD       ' send the instruction to LCD
char = 13        ' display on, cursor blink
gosub CmdLCD       ' send the instruction to LCD 
  char = 1        ' clear display,go home to line 1 of LCD display
  gosub CmdLCD       ' send the instruction to LCD
gosub ReadTab       ' read text characters in the Table and send text in the Table to LCD
char = 192        ' move cursor to the start of line two
  gosub CmdLCD       ' send the instruction to LCD 
            

' *** Main loop - continuously read the PS2 keyboard ***
do

gosub RetKey       ' go retrieve any character coming in from the keyboard
gosub Track        ' go check if the retrieved character was one that was displayed and if so, increment the cursor tracking counter "j"
              
               
loop                      

' *** Subroutines ***
Track:         ' this sub checks if retrieved character was one that was displayed or otherwise increments the cursor tracking counter
debug
if keyrem = $01 then return endif    ' F9 keypress - this character not displayed, so do not increment LCD cursor tracking counter "j"
if keyrem = $0a then return endif    ' F8 keypress - same as above
if keyrem = $0b then return endif    ' F6 keypress - same
if keyrem = $0c then return endif    ' F4 keypress - same
if keyrem = $03 then return endif    ' F5 keypress - same
if keyrem = $04 then return endif    ' F3 keypress - same
if keyrem = $05 then return endif    ' F1 keypress - same
if keyrem = $06 then return endif    ' F2 keypress - same
if keyrem = $07 then return endif    ' F12 keypress - same
if keyrem = $09 then return endif    ' F10 keypress - same
if keyrem = $11 then return endif    ' L Alt keypress - same
if keyrem = $12 then return endif    ' L Shift keypress - same
if keyrem = $14 then return endif    ' L Ctrl keypress - same
if keyrem = $1f then return endif    ' L Gui keypress - same   
if keyrem = $27 then return endif    ' R Gui keypress - same
if keyrem = $2f then return endif    ' Special function key - same
if keyrem = $58 then return endif    ' Caps Lock keypress - same
if keyrem = $59 then return endif    ' R Shift keypress - same
if keyrem = $5a then return endif    ' Enter keypress - same
if keyrem = $69 then return endif    ' End keypress - same
if keyrem = $6c then return endif    ' Home keypress - same
if keyrem = $70 then return endif    ' Insert keypress - same
if keyrem = $72 then return endif    ' Down Arrow keypress - same
if keyrem = $73 then return endif    ' KP 5 keypress - same
if keyrem = $75 then return endif    ' Up Arrow keypress - same
if keyrem = $76 then return endif    ' Esc keypress - same
if keyrem = $77 then return endif    ' Num Lock keypress - same
if keyrem = $78 then return endif    ' F11 keypress - same
if keyrem = $7a then return endif    ' Page Down keypress - same
if keyrem = $7d then return endif    ' Page Up keypress - same
if keyrem = $7e then return endif    ' Scroll keypress - same
if keyrem = $83 then return endif    ' F7 keypress - same
if keyrem = $99 then return endif    ' Dummy value - used when displaying "CAP" or "SHF" on first line so do not increment line 2 counter
if keyrem = $e1 then return endif    ' Pause/Break - same
if flag = 0 and j <= 16 then let j=j+1 endif  ' flag = 0 indicates keypress retrieved is displayed, increment the LCD cursor tracking counter by 1
if flag = 1 and j > 0 then let j=j-1 endif  ' flag = 1 indicates the keypress retrieved moves the cursor left, decrement the LCD cursor tracking counter by 1
if flag = 0 and j = 17 then gosub Zcount   ' flag = 0 so keypress retrieved should be displayed, but j =17, at the end of line 2, go clear LCD and start at j =0
if flag = 1 and j = 0 then gosub LStart   ' flag = 1 indicates the keypress retrieved moves the cursor left, but j=0 so cannot move left, so stay put
flag = 0        ' if flag was = 1, then any code left moves was executed, reset the flag = 0, ready for next character
'debug        ' a debug here lets you see where the counter is
return

RetKey:         ' this sub continuously watches for new characters coming from the keyboard
kbin[1000,RetKey],keybd      ' continuously check for characters from the keyboard
   put 1, keybd       ' stick the incoming character in memory register 1,
   get 1, keyrem       ' set the variable "keyrem" to the incoming character so we can check it later to see if it should increment counter j
        if keybd = $01 then return    ' next instructions ignore the key press because it is not a character that is displayed or increments j e.g $01 is F9
else if keybd = $1f then return
else if keybd = $2f then return
else if keybd = $03 then return
else if keybd = $04 then return
else if keybd = $05 then return
else if keybd = $06 then return
else if keybd = $07 then return
else if keybd = $09 then return
else if keybd = $0a then return
else if keybd = $0b then return
else if keybd = $0c then return
else if keybd = $11 then return
else if keybd = $14 then return
else if keybd = $1f then return
else if keybd = $27 then return
else if keybd = $5a then return
else if keybd = $70 then return
else if keybd = $72 then return
else if keybd = $73 then return
else if keybd = $75 then return
else if keybd = $76 then return
else if keybd = $77 then return
else if keybd = $78 then return
else if keybd = $7a then return
else if keybd = $7d then return
else if keybd = $7e then return
else if keybd = $83 then return
else if keybd = $e1 then return
endif
   'debug        ' a debug here lets you see the character coming in on the keyboard
   gosub ShftCheck       ' go check if the Shift key was pressed
   gosub CapCheck       ' go check if the CAPS key was pressed
return

Zcount:         ' this sub resets the LCD & position counter, clears the display, goes to start of line and reads the Table
j = 0         ' reset cursor position counter to 0
char = 1        ' command to clear display and move cursor to the start of line one
gosub CmdLCD       ' send the instruction to LCD      
gosub ReadTab       ' go read the table
if capindf = 1 and capclearf = 0 then gosub CapInd ' after clear with Caps Lock on, refresh CAPital letter indication when returning to start of line
if shftindf = 1 and shftclearf = 0 then gosub ShftInd ' after clear with Shift on, refresh SHFt letter indication when returning to start of line

LStart:         ' this sub moves the cursor to the start of line 2
char = 192        ' command to move cursor to the start of line two
gosub CmdLCD       ' send the instruction to LCD
return

LEnd:          ' this sub moves the cursor to the end of line 2        
j = 15        ' this command presets the cursor position counter for the end of line 2
char = 207        ' command to move cursor to the end of line two
gosub CmdLCD       ' send the instruction to LCD
return

CmdLCD:         ' this sub tells the LCD to expect a command character
low RegSelPin       ' This pulls this pin low to tell the LCD the next input will be a command byte
gosub LoadLCD       ' goes to the sub to load the command into the LCD
return       

TxtLCD:         ' this sub tells the LCD to expect a text character
high RegSelPin       ' this pulls this pin high to tell the LCD the next input will be text byte

LoadLCD:         ' this sub executes loading byte into LCD
outpinsB = char       ' load byte onto outpinsB
pulsout EnablePin,1      ' execute loading bytes onto LCD
return

LoadIntoLCD:        ' this sub tells the LCD to expect a text character and executes loading byte into LCD    
high RegSelPin       ' this pulls this pin high to tell the LCD the next input will be text byte
outpinsB = keybd       ' load byte onto outpinsB
pulsout EnablePin,1      ' execute loading byte into LCD   
return

ReadTab:         ' this sub reads the contents of the Table into char
for index = 0 to 15
  readtable index, char      ' read text characters in the Table
  gosub TxtLCD       ' send text in the Table to LCD
  next index
return

LArrow:         ' this sub is for the backspace key
char = 16        ' this command will move cursor to the left one position
gosub CmdLCD
flag = 1        ' this flag tells the cursor position tracking counter to subtract 1 from j for a left move
return

Del:          ' this sub is for the delete key
char = 16        ' this command will move cursor to the left one position 
gosub CmdLCD       ' send the instruction to LCD
let keybd =" "       ' loads a blank in the keybd variable
gosub LoadIntoLCD       ' loads blank to the LCD
char = 16        ' this command will move cursor to the left one position (move back to the left after loading blank)
gosub CmdLCD       ' send the instruction to LCD
flag = 1        ' this flag tells the cursor position tracking counter to subtract 1 from j for a left move
return

RArrow:         ' this sub is for the right arrow key
char = 20        ' this command will move cursor to the right one position
gosub CmdLCD       ' send the instruction to LCD      
return

ShftCheck:         ' this sub checks if the left or right Shift key was pressed
if keybd = $12 then togglebit shftflag, 0 endif  ' if L Shift key was press then toggle shftflag from 0 to 1 indicating to the program what path to take
if keybd = $59 then togglebit shftflag, 0 endif  ' if R Shift key was press then toggle shftflag from 0 to 1 indicating to the program what path to take
if shftflag = 1 and shftindf = 0 then gosub ShftInd ' if the shftflag set to 1 & shftindf =0, then go display "SHF" on the 1st line of the LCD to indicate shift is activated
if shftflag = 0 and shftclearf = 0 then gosub ShftClear ' if the shftflag set to 0 and shftclearf set to 0, then go clear display and flags that indicate Shift
if shftflag = 1 then gosub ReadShftKey   ' if the shftflag set to 1 then go to the sub that will interpret key presses with Shift on
if shftflag = 0 then return endif    ' if the shftflag set to 0 then return to the main program to check for Capital or regular letter indication 
return

ShftInd:         ' this sub displays "SHF" on the 1st line of the LCD to indicate shift is activated
gosub CapClear       ' because Shift is active, ensure that Caps lock is cleared first
shftindf = 1       ' set the flag that indicates that the display is showing "SHF" 
  shftclearf = 0       ' set the flag that indicates that the display is showing "SHF" and is not currently cleared
  char = 141        ' command to move to the starting position on line 1 of the display where "SHF" will be displayed
  gosub CmdLCD       ' send the instruction to LCD       '
let keybd ="S"        ' next few instructions set keybd variable to the SHF letters and load them to the LCD
gosub LoadIntoLCD
let keybd ="H"
gosub LoadIntoLCD
let keybd ="F"   
gosub LoadIntoLCD
let keybd =$99        ' set keybd to a dummy value so the program will not increment the j count after display of last letter "F"  
char = 192 + j       ' command to return the cursor to last know position on line 2 after display of "SHF" on line 1
  gosub CmdLCD       ' send the instruction to LCD
return

ShftClear:         ' this sub clears the "SHF" displayed on line 1 as well as the flags indicating that "SHF" is displayed & active
shftflag = 0       ' set flag =0 to indicate Shift is pressed to off
shftindf = 0       ' set flag =0 to indicate "SHF" is no longer indicated on the display    
shftclearf = 1       ' set flag =1 to indicate that "SHF" was cleared from the display
char = 141        ' command to move to the starting position on line 1 of the display where "SHF" is displayed
  gosub CmdLCD       ' send the instruction to LCD
let keybd =" "        ' next few instructionss set keybd variable to a blank and load them to the LCD
gosub LoadIntoLCD
let keybd =" "
gosub LoadIntoLCD
let keybd =" "
gosub LoadIntoLCD
let keybd =$99       ' set keybd to a dummy value so the program will not increment the j count after display of last blank
char = 192 + j       ' command to return the cursor to last know position on line 2 after blanking display on line 1
  gosub CmdLCD       ' send the instruction to LCD
return   

CapCheck:         ' this sub checks if the Caps lock key was pressed
if keybd = $58 then togglebit capflag, 0 endif  ' if Caps lock key was press then toggle capflag from 0 to 1 indicating to the program what path to take 
if capflag = 1 and capindf = 0 then gosub CapInd ' if the capflag set to 1 & capindf =0, then go display "CAP" on the 1st line of the LCD to indicate Caps is activated
if capflag = 0 and capclearf = 0 then gosub CapClear ' if the capflag set to 0 and capclearf set to 0, then go clear display and flags that indicate Caps lock on
if capflag = 1 then gosub ReadCapKey   ' if the capflag set to 1 then go to the sub that will interpret key presses with Caps lock on
if capflag = 0 and shftflag = 0 then gosub Readkey ' if the capflag set to 0 then return to the main program to check for regular letter indication 
return

CapInd:         ' this sub displays "CAP" on the 1st line of the LCD to indicate Caps lock is activated
gosub ShftClear       ' because Caps lock is active, ensure that Shift lock is cleared first
capindf = 1        ' set the flag that indicates that the display is showing "CAP"        
  capclearf = 0       ' set the flag that indicates that the display is showing "CAP" and is not currently cleared
  char = 141        ' command to move to the starting position on line 1 of the display where "CAP" will be displayed
  gosub CmdLCD       ' send the instruction to LCD
let keybd ="C"        ' next few instructions set keybd variable to the CAP letters and load them to the LCD
gosub LoadIntoLCD
let keybd ="A"
gosub LoadIntoLCD
let keybd ="P"   
gosub LoadIntoLCD
let keybd =$99        ' set keybd to a dummy value so the program will not increment the j count after display of last letter "P"  
char = 192 + j       ' command to return the cursor to last know position on line 2 after display of "CAP" on line 1
  gosub CmdLCD       ' send the instruction to LCD
return

CapClear:         ' this sub clears the "CAP" displayed on line 1 as well as the flags indicating that "CAP" is displayed & active
capflag = 0        ' set flag =0 to indicate Cap lock is pressed to off
capindf = 0        ' set flag =0 to indicate "CAP" is no longer indicated on the display
capclearf = 1       ' set flag =1 to indicate that "CAP" was cleared from the display
char = 141        ' command to move to the starting position on line 1 of the display where "CAP" is displayed
  gosub CmdLCD       ' send the instruction to LCD
let keybd =" "        ' next few instructions set keybd variable to a blank and load them to the LCD
gosub LoadIntoLCD
let keybd =" "
gosub LoadIntoLCD
let keybd =" "
gosub LoadIntoLCD
let keybd =$99       ' set keybd to a dummy value so the program will not increment the j count after display of last blank
char = 192 + j       ' command to return the cursor to last know position on line 2 after blanking display on line 1
  gosub CmdLCD       ' send the instruction to LCD
return   

Readkey:         ' this sub converts the regular char code received from the keyboard into the correct character to display on the LCD

       if keybd = $29 then let keybd =" "   ' next few instructions set keybd to correct character to display and load them to the LCD
else if keybd = $0d then let keybd =" "
else if keybd = $1c then let keybd ="a"
else if keybd = $32 then let keybd ="b"
else if keybd = $21 then let keybd ="c"
else if keybd = $23 then let keybd ="d"
else if keybd = $24 then let keybd ="e"
else if keybd = $2b then let keybd ="f"
else if keybd = $34 then let keybd ="g"
else if keybd = $33 then let keybd ="h"
else if keybd = $43 then let keybd ="i"
else if keybd = $3b then let keybd ="j"
else if keybd = $42 then let keybd ="k"
else if keybd = $4b then let keybd ="l"
else if keybd = $3a then let keybd ="m"
else if keybd = $31 then let keybd ="n"
else if keybd = $44 then let keybd ="o"
else if keybd = $4d then let keybd ="p"
else if keybd = $15 then let keybd ="q"
else if keybd = $2d then let keybd ="r"
else if keybd = $1b then let keybd ="s"
else if keybd = $2c then let keybd ="t"
else if keybd = $3c then let keybd ="u"
else if keybd = $2a then let keybd ="v"
else if keybd = $1d then let keybd ="w"
else if keybd = $22 then let keybd ="x"
else if keybd = $35 then let keybd ="y"
else if keybd = $1a then let keybd ="z"
else if keybd = $45 then let keybd ="0"
else if keybd = $16 then let keybd ="1"
else if keybd = $1e then let keybd ="2"
else if keybd = $26 then let keybd ="3"
else if keybd = $25 then let keybd ="4"
else if keybd = $2e then let keybd ="5"
else if keybd = $36 then let keybd ="6"
else if keybd = $3d then let keybd ="7"
else if keybd = $3e then let keybd ="8"
else if keybd = $46 then let keybd ="9"
else if keybd = $54 then let keybd ="["
else if keybd = $5b then let keybd ="]"
else if keybd = $4e then let keybd ="-"
else if keybd = $55 then let keybd ="="
else if keybd = $4c then let keybd =";"
else if keybd = $52 then let keybd ="'"
else if keybd = $41 then let keybd =","
else if keybd = $49 then let keybd ="."
else if keybd = $4a then let keybd ="/"
else if keybd = $5d then let keybd ="`"
else if keybd = $0e then let keybd ="`"
else if keybd = $54 then let keybd ="{"
else if keybd = $5b then let keybd ="}"
else if keybd = $5d then let keybd ="|"
else if keybd = $4c then let keybd =":"
else if keybd = $52 then let keybd ="'"
else if keybd = $41 then let keybd ="<"
else if keybd = $49 then let keybd =">"
else if keybd = $7b then let keybd ="-"
else if keybd = $7c then let keybd ="*"
else if keybd = $79 then let keybd ="+"
else if keybd = $12 then return    ' ignore L Shift key
else if keybd = $58 then return    ' ignore Caps lock key
else if keybd = $59 then return    ' ignore R Shift lock key
else if keybd = $99 then return    ' ignore dummy value
else if keybd = $74 then goto RArrow   ' code for right arrow, so go to that sub
else if keybd = $6b then goto LArrow   ' code for a Left arrow, same as a backspace, so go to that sub
else if keybd = $6c then goto Zcount   ' code for "Home" key, so clear and refresh LCD display and go home to first position on line 2
else if keybd = $69 then goto LEnd    ' code for "End" key, so go to the end position on line 2  
else if keybd = $66 then goto Del    ' code for "Backspace", so go to that Del sub
else if keybd = $71 then goto Del    ' code for "Delete" key, so go to that sub
endif
gosub LoadIntoLCD      
return

ReadCapKey:         ' this sub converts char code rx from the keyboard into the correct character to display on the keyboard with CAPS lock
      if keybd = $29 then let keybd =" "   ' next few instructions set keybd to correct character to display and load them to the LCD
else if keybd = $0d then let keybd =" "
else if keybd = $1c then let keybd ="A" 
else if keybd = $32 then let keybd ="B"
else if keybd = $21 then let keybd ="C"
else if keybd = $23 then let keybd ="D"
else if keybd = $24 then let keybd ="E"
else if keybd = $2b then let keybd ="F"
else if keybd = $34 then let keybd ="G"
else if keybd = $33 then let keybd ="H"
else if keybd = $43 then let keybd ="I"
else if keybd = $3b then let keybd ="J"
else if keybd = $42 then let keybd ="K"
else if keybd = $4b then let keybd ="L"
else if keybd = $3a then let keybd ="M"
else if keybd = $31 then let keybd ="N"
else if keybd = $44 then let keybd ="O"
else if keybd = $4d then let keybd ="P"
else if keybd = $15 then let keybd ="Q"
else if keybd = $2d then let keybd ="R"
else if keybd = $1b then let keybd ="S"
else if keybd = $2c then let keybd ="T"
else if keybd = $3c then let keybd ="U"
else if keybd = $2a then let keybd ="V"
else if keybd = $1d then let keybd ="W"
else if keybd = $22 then let keybd ="X"
else if keybd = $35 then let keybd ="Y"
else if keybd = $1a then let keybd ="Z"
else if keybd = $45 then let keybd ="0"
else if keybd = $16 then let keybd ="1"
else if keybd = $1e then let keybd ="2"
else if keybd = $26 then let keybd ="3"
else if keybd = $25 then let keybd ="4"
else if keybd = $2e then let keybd ="5"
else if keybd = $36 then let keybd ="6"
else if keybd = $3d then let keybd ="7"
else if keybd = $3e then let keybd ="8"
else if keybd = $46 then let keybd ="9"
else if keybd = $54 then let keybd ="["
else if keybd = $5b then let keybd ="]"
else if keybd = $4e then let keybd ="-"
else if keybd = $55 then let keybd ="="
else if keybd = $4c then let keybd =";"
else if keybd = $52 then let keybd ="'"
else if keybd = $41 then let keybd =","
else if keybd = $49 then let keybd ="."
else if keybd = $4a then let keybd ="/"
else if keybd = $5d then let keybd ="`"
else if keybd = $0e then let keybd ="`"
else if keybd = $54 then let keybd ="{"
else if keybd = $5b then let keybd ="}"
else if keybd = $5d then let keybd ="|"
else if keybd = $4c then let keybd =":"
else if keybd = $52 then let keybd ="'"
else if keybd = $41 then let keybd ="<"
else if keybd = $49 then let keybd =">"
else if keybd = $7b then let keybd ="-"
else if keybd = $7c then let keybd ="*"
else if keybd = $79 then let keybd ="+"
else if keybd = $12 then return
else if keybd = $58 then return
else if keybd = $59 then return
else if keybd = $99 then return
else if keybd = $74 then goto RArrow   
else if keybd = $6b then goto LArrow
else if keybd = $6c then goto Zcount
else if keybd = $69 then goto LEnd
else if keybd = $66 then goto Del
else if keybd = $71 then goto Del
endif
gosub LoadIntoLCD     
return

ReadShftKey:        ' this sub converts char code received from the keyboard into the correct character to display on the LCD with Shift lock
       if keybd = $29 then let keybd =" "   ' next few instructions set keybd to correct character to display and load them to the LCD
else if keybd = $0d then let keybd =" "
else if keybd = $45 then let keybd =")"
else if keybd = $16 then let keybd ="!"
else if keybd = $1e then let keybd ="@"
else if keybd = $26 then let keybd ="#"
else if keybd = $25 then let keybd ="$"
else if keybd = $2e then let keybd ="%"
else if keybd = $36 then let keybd ="^"
else if keybd = $3d then let keybd ="&"
else if keybd = $3e then let keybd ="*"
else if keybd = $46 then let keybd ="("
else if keybd = $4e then let keybd ="_"
else if keybd = $55 then let keybd ="+"
else if keybd = $0e then let keybd ="`"
else if keybd = $54 then let keybd ="{"
else if keybd = $5b then let keybd ="}"
else if keybd = $5d then let keybd ="|"
else if keybd = $0e then let keybd ="`"
else if keybd = $4c then let keybd =":"
else if keybd = $52 then let keybd ="'"
else if keybd = $41 then let keybd ="<"
else if keybd = $49 then let keybd =">"
else if keybd = $4a then let keybd ="?"
else if keybd = $1c then let keybd ="A"
else if keybd = $32 then let keybd ="B"
else if keybd = $21 then let keybd ="C"
else if keybd = $23 then let keybd ="D"
else if keybd = $24 then let keybd ="E"
else if keybd = $2b then let keybd ="F"
else if keybd = $34 then let keybd ="G"
else if keybd = $33 then let keybd ="H"
else if keybd = $43 then let keybd ="I"
else if keybd = $3b then let keybd ="J"
else if keybd = $42 then let keybd ="K"
else if keybd = $4b then let keybd ="L"
else if keybd = $3a then let keybd ="M"
else if keybd = $31 then let keybd ="N"
else if keybd = $44 then let keybd ="O"
else if keybd = $4d then let keybd ="P"
else if keybd = $15 then let keybd ="Q"
else if keybd = $2d then let keybd ="R"
else if keybd = $1b then let keybd ="S"
else if keybd = $2c then let keybd ="T"
else if keybd = $3c then let keybd ="U"
else if keybd = $2a then let keybd ="V"
else if keybd = $1d then let keybd ="W"
else if keybd = $22 then let keybd ="X"
else if keybd = $35 then let keybd ="Y"
else if keybd = $1a then let keybd ="Z"
else if keybd = $12 then return
else if keybd = $58 then return
else if keybd = $59 then return
else if keybd = $99 then return
else if keybd = $74 then goto RArrow 
else if keybd = $6b then goto LArrow
else if keybd = $69 then goto LEnd
else if keybd = $6c then goto Zcount
else if keybd = $66 then goto Del
else if keybd = $71 then goto Del
endif
gosub LoadIntoLCD     
return

Step 4: The Schematic

This is the schematic. You need to use a PICAXE 20X2 or close to it not only for the number of pins required to feed the LCD but also the memory space to hold the rather large program. J1 represents the keyboard connector. I did not explicitly specify in the program that the keyboard clock and data are connected to pins 8 and 9, however it seems to work with these connections. The schematic was created with DipTrace and you can download a free shareware version for limited hobby use from their website at www.diptrace.com/download.php. You can see the keyboard to picaxe connection instructions on page 133 of the Revolution Education Picaxe manual 2. I've included the schematic and the manual at the end of this instructable.
 

Step 5: Build It

Here are pictures of this project built in a clear box. If you use a clear box, then you don't need to cut a hole in the box for the LCD and it is cool to see the insides. This project in a box is powered by a 9V battery and this is fed into a 5V regulator (LM7805) which is not shown on the schematic. If you use one, put a 0.01 UF capacitor across the +/- 5V supply rail at the output of the voltage regulator to supress noise. A 6 pin bulkhead mount DIN connector going to the keyboard and 3.5 mm stereo jack for programming are mounted in the walls of the box along with an on/off switch to preserve the battery.                                                                                                                                                                                                                                      

Step 6: Project Files

Here are the project files - program, schematic and PICAXE Manual 2