PS/2 keyboard + LCD wireless communicator

I have recently built my first 'proper' Arduino based project which is a wireless communicator gadget (see attachment). It basicly is a keyboard + LCD connected to an ATMEGA328 running 2009 bootloader connected to a transparent serial tranciever (Ciesco XRF). On the other end I have another XRF connected through an FTDI to my PC.

/*
*****************
Woozle - 2012
*****************
*/

#include <LiquidCrystal.h>    //LCD libary
#include <PS2Keyboard.h>      //PS2 libary

LiquidCrystal lcd(10, 9, 5, 6, 7, 8);  //LCD initialize
PS2Keyboard kb;                        //Keyboard initialize

void setup()
{
  kb.begin(4, 3);          // Set up the keyboard
  lcd.begin(16, 2);        // Set up the LCD
  Serial.begin(9600);      // Start Serial at 9600bps
}

void loop()
{
  if (Serial.available())     // Check if data is available
  {    
    delay(100);        // Wait for all data to arrive from PC
    lcd.clear();       // Clear LCD display
    while (Serial.available() > 0) // While data is available
    {  
      lcd.write(Serial.read());    // Write it to screen
    }
  }
   if (kb.available())   // Check for incoming keyboard keystrokes
   {  
    char x = kb.read();  // Write keystrokes to a variable
    Serial.print(x);     // Send to PC
   }
}

This works well for bi-directional communication between the PC and 'the device' but I was wondering how to have the device print the keyboard's message (in a sort of buffer) on the second line of the LCD and allow for corrections (backspace) before being sent over serial by pressing enter. Thanks in advance for any replies.

PS. This is my first forum post so if I have done anything wrong (code etiquette etc) please tell me.

You would modify this bit:

 if (kb.available())   // Check for incoming keyboard keystrokes
   {  
    char x = kb.read();  // Write keystrokes to a variable
    Serial.print(x);     // Send to PC
   }

Instead of the Serial.print(x) you would do lcd.print(x) ... keeping track of how much data you had. Before doing the print you would check for a couple of things like and .

So that could work you would have to save what you had received in a small buffer (eg 40 bytes). Most characters would advance you through the buffer (and LCD) and backspace would move you backwards.

Thank you, thats just what I needed, I will edit the code now and repost it when I have done it.

Ok, so I have started editing the code, debugging as I went along along and already I seem to have a problem. I started by just setting up buffer as a string and by setting up the Return key to send the buffer over serial. But the data appears to the LCD as black filled-in boxes and when return is pressed the Buffer appears as the correct length of characters but all as 'ÿ's.

#include <LiquidCrystal.h>    //LCD libary
#include <PS2Keyboard.h>      //PS2 libary
String buff;        // Buffer for PS/2 data
LiquidCrystal lcd(10, 9, 5, 6, 7, 8);  //LCD initialize
PS2Keyboard kb;                        //Keyboard initialize
//Same here as before
if (kb.available())   // Check for incoming keyboard keystrokes
   {  
     char x = kb.read();  // Write keystrokes to a variable
     
     if (x == PS2_ENTER) 
     {
      Serial.print(buff);
     }
     
     else
     {
      char x = kb.read();  // Write keystrokes to a variable
      buff.concat(x);      // Add variable to end of string
      byte l = buff.length();    //Length of buffer
      lcd.print(x);     // Send to LCD
     }
   }

Any ideas on why this is happening?

Here:

byte l = buff.length();    //Length of buffer
      lcd.print(x);     // Send to LCD

Why find "l"? You never use it.


Here:

if (kb.available())   // Check for incoming keyboard keystrokes
   {  
     char x = kb.read();  // Write keystrokes to a variable
     
     if (x == PS2_ENTER) 
  ...     
     else
     {
      char x = kb.read();  // Write keystrokes to a variable

You know you have one byte available but you read two. Almost certainly the next one will be -1 which prints as ÿ.

I realised my error as soon as I posted. Here is my completly amended code.

/*
*****************
Woozle - 2012
*****************
*/
#include <LiquidCrystal.h>    //LCD libary
#include <PS2Keyboard.h>      //PS2 libary
String buff;                  // Buffer for PS/2 data
LiquidCrystal lcd(10, 9, 5, 6, 7, 8);  //LCD initialize
PS2Keyboard kb;                        //Keyboard initialize

void setup()
{
  kb.begin(4, 3);          // Set up the keyboard
  lcd.begin(16, 2);        // Set up the LCD
  Serial.begin(9600);      // Start Serial at 9600bps
}

void loop()
{
  
  if (Serial.available())     // Check if data is available
  {    
    delay(100);        // Wait for all data to arrive from PC
    lcd.setCursor(0,0);
    lcd.write("                ");       // Clear LCD top line
    lcd.setCursor(0,0);
    while(Serial.available() > 0) // While data is available
    {  
      lcd.write(Serial.read());    // Write it to screen
    }
  }
   if (kb.available())   // Check for incoming keyboard keystrokes
   {  
     
     char x = kb.read();    
     unsigned int y = buff.length();    //Length of buffer
     if (x == PS2_ENTER)                   //If return key is pressed
     {
      Serial.println(buff);                // Send the buffer over serial
      lcd.setCursor(0,1);                  // Set the cursor on bottom line
      lcd.write("                ");       // Clear LCD bottom line
      buff = "";                           // Clear the buffer
     }
    else
     {
      buff.concat(x);      // Add variable to end of string     
      lcd.setCursor(y,1);        //Postition that PS/2 data will be written to
      lcd.write(x);              // Send to LCD
     }
   }
}

I used 'l' for the next part. It has now been changed to 'y' because I got it mixed up with a 1. I don't know how to erase the last character of a String though so I have not been able to get the 'backsparce' working. Any ideas?

You are probably better off using a fixed buffer than the String class.

eg.

char buf [60];
int pos = 0;

...

// add something:

if (pos < sizeof (buf) - 1)
  buf[pos++] = x;
buf[pos] = 0;  // terminating null byte

...

// remove something:

if (pos > 0)
  pos--;
buf [pos] = 0;  // terminating null byte

...

// send to serial

Serial.println (buf);

I like what you have done and I may need to copy it.

Thank you for the inspiration.