Getting input from keyboard to output on Matrix

Hey guys, I am quite new to this arduino stuff and I have never really done any programming in C. I am trying to get input from a keyboard, save it to an array of chars and then output that array to the 8*8 matrix LED. I have combined code of previous people of the Keyboard and displaying a message on the MAtrix LED - which was found on the Arduino website.

I have tried many ways to do this including trying to save serial.read to an array but still not luck with outputing it, I wonder if anyone can look at my code and see where I am going wrong. This would be MUCH APPRECIATED :slight_smile:

#include "ps2.h"

#define PS2_KC_BKSP    0x08
#define PS2_KC_UP      0x81
#define PS2_KC_DOWN    0x82
#define PS2_KC_LEFT    0x83
#define PS2_KC_RIGHT   0x84
#define PS2_KC_PGDN    0x85
#define PS2_KC_PGUP    0x86
#define PS2_KC_END     0x87
#define PS2_KC_HOME    0x88
#define PS2_KC_INS     0x89
#define PS2_KC_DEL     0x8A
#define PS2_KC_ESC     0x8B
#define PS2_KC_CLON    0x8C // caps_lock on
#define PS2_KC_CLOFF   0x8D // caps_lock off

/*
 * Pin 2 is the ps2 data pin, pin 3 is the clock pin
 */

PS2 kbd(3, 2);
bool ps2Keyboard_release = false;
bool ps2Keyboard_extend = false;
bool cmd_ack_byte_ok = false;
bool ps2Keyboard_shift = false;
bool ps2Keyboard_alt = false;
bool ps2Keyboard_caps_lock = false;
bool ps2Keyboard_ctrl = false;

byte ps2Keyboard_CharBuffer = 0;

byte code;


int count = 0;

int speed = 20; //number of times to repeat each frame
int pauseDelay = 500;  //microseconds to leave each row  on before moving to the next

char requestString[] = "";   //The string to display

                              
int index = 0;  //this is the current charachter in the string being displayed
int offset = 0; //this is how many columns it is offset by

//Pin Definitions
int rowA[] ={11,14,16,18,13,5,7,9};  //5,6,7,8,9,10,11,12 of matrix

                                         //(rows are common anode (drive HIGH))
int colA[] = {8,6,4,19,17,15,12,10}; //24,23,22,21,4,3,2,1 of matrix

                                         //(columns are common cathode (drive LOW))

//Constants defining each charachters position in an array of integer arrays
//Letters
const int A = 0;  const int B = 1;  const int C = 2;  const int D = 3;  const int E = 4;
const int F = 5;  const int G = 6;  const int H = 7;  const int I = 8;  const int J = 9;  
const int K = 10; const int L =11;  const int M = 12; const int N = 13; const int O = 14; 
const int P = 15; const int Q =16;  const int R = 17; const int S = 18; const int T = 19; 
const int U = 20; const int V =21;  const int W = 22; const int X = 23; const int Y = 24; 
const int Z = 25;

//Punctuation
const int COL =26; const int DASH = 27; const int BRA2 = 28; const int  _ = 29; const int LINE = 34;
const int DOT =36;

//Extra Charchters
const int  FULL =30; const int CHECK = 31; const int A3 = 32; const int TEMP = 33; 
const int SMILE =35; const int COLDOT = 36;


//The array used to hold a bitmap of the display 
//(if you wish to do something other than scrolling marque change the data in this
//variable then display)
byte data[] = {0,0,0,0,0,0,0,0};        

//The alphabet
//Each Charachter is an 8 x 7 bitmap where 1 is on and 0 if off
const int _A[] = {B0001000,
                  B0010100,
                  B0100010,
                  B1000001,
                  B1111111,
                  B1000001,
                  B1000001,
                  B0000000};

const int _B[] = {B1111110,
                  B0100001,
                  B0100001,
                  B0111110,
                  B0100001,
                  B0100001,
                  B1111110,
                       B0000000};

const int _C[] = {B0011111,
                  B0100000,
                  B1000000,
                  B1000000,
                  B1000000,
                  B0100000,
                  B0011111,
                       B0000000};

const int _D[] = {B1111100,
                  B0100010,
                  B0100001,
                  B0100001,
                  B0100001,
                  B0100010,
                  B1111100,
                       B0000000};

const int _E[] = {B1111111,
                  B1000000,
                  B1000000,
                  B1111100,
                  B1000000,
                  B1000000,
                  B1111111,
                       B0000000};

const int _F[] = {B1111111,
                  B1000000,
                  B1000000,
                  B1111100,
                  B1000000,
                  B1000000,
                  B1000000,
                  B0000000};

const int _G[] = {B0011111,
                  B0100000,
                  B1000000,
                  B1001111,
                  B1000001,
                  B0100001,
                  B0011111,
                       B0000000};

const int _H[] = {B1000001,
                  B1000001,
                  B1000001,
                  B1111111,
                  B1000001,
                  B1000001,
                  B1000001,
                       B0000000};

const int _I[] = {B1111111,
                  B0001000,
                  B0001000,
                  B0001000,
                  B0001000,
                  B0001000,
                  B1111111,
                       B0000000};

const int _J[] = {B0001111,
                  B0000001,
                  B0000001,
                  B0000001,
                  B0000001,
                  B1000001,
                  B0111110,
                       B0000000};

const int _K[] = {B1000011,
                  B1000100,
                  B1001000,
                  B1110000,
                  B1001000,
                  B1000100,
                  B1000011,
                       B0000000};

const int _L[] = {B1000000,
                  B1000000,
                  B1000000,
                  B1000000,
                  B1000000,
                  B1000000,
                  B1111111,
                       B0000000};

const int _M[] = {B1110110,
                  B1001001,
                  B1001001,
                  B1001001,
                  B1001001,
                  B1001001,
                  B1001001,
                       B0000000};

const int _N[] = {B1000001,
                  B1100001,
                  B1010001,
                  B1001001,
                  B1000101,
                  B1000011,
                  B1000001,
                       B0000000};

const int _O[] = {B0011100,
                  B0100010,
                  B1000001,
                  B1001001,
                  B1000001,
                  B0100010,
                  B0011100,
                       B0000000};

const int _P[] = {B1111110,
                  B0100001,
                  B0100001,
                  B0111110,
                  B0100000,
                  B0100000,
                  B0100000,
                       B0000000};

const int _Q[] = {B0011100,
                  B0100010,
                  B1000001,
                  B1000001,
                  B1000101,
                  B0100010,
                  B0011101,
                       B0000000};

const int _R[] = {B1111110,
                  B0100001,
                  B0100001,
                  B0101110,
                  B0100100,
                  B0100010,
                  B0100001,
                       B0000000};

const int _S[] = {B0111111,
                  B1000000,
                  B1000000,
                  B0111110,
                  B0000001,
                  B0000001,
                  B1111110,
                       B0000000};

const int _T[] = {B1111111,
                  B0001000,
                  B0001000,
                  B0001000,
                  B0001000,
                  B0001000,
                  B0001000,
                       B0000000};

const int _U[] = {B1000001,
                  B1000001,
                  B1000001,
                  B1000001,
                  B1000001,
                  B1000001,
                  B0111110,
                       B0000000};

const int _V[] = {B1000001,
                  B1000001,
                  B1000001,
                  B1000001,
                  B0100010,
                  B0010100,
                  B0001000,
                       B0000000};
                  
const int _W[] = {B1000001,
                  B1001001,
                  B1001001,
                  B1001001,
                  B1001001,
                  B1001001,
                  B0110110,
                       B0000000};

const int _X[] = {B1000001,
                  B0100010,
                  B0010100,
                  B0001000,
                  B0010100,
                  B0100010,
                  B1000001,

Part 2:

const int _Y[] = {B1000001,
                  B0100010,
                  B0010100,
                  B0001000,
                  B0001000,
                  B0001000,
                  B0001000,
                       B0000000};

const int _Z[] = {B1111111,
                  B0000010,
                  B0000100,
                  B0111110,
                  B0010000,
                  B0100000,
                  B1111111,
                       B0000000};

const int _COL[] = {B0000000,
                  B0011000,
                  B0011000,
                  B0000000,
                  B0011000,
                  B0011000,
                  B0000000,
                       B0000000};

const int _DASH[] = {B0000000,
                  B0000000,
                  B0000000,
                  B0111110,
                  B0000000,
                  B0000000,
                  B0000000,
                       B0000000};

const int _BRA2[] = {B0010000,
                  B0001000,
                  B0000100,
                  B0000100,
                  B0001000,
                  B0010000,
                  B0000000,
                       B0000000};                  

const int __[] = {B0000000,
                  B0000000,
                  B0000000,
                  B0000000,
                  B0000000,
                  B0000000,
                  B0000000,
                       B0000000};

const int _FULL[] = {B1111111,
                     B1111111,
                     B1111111,
                     B1111111,
                     B1111111,
                     B1111111,
                     B1111111,
                       B0000000};                  

const int _CHECK[] = {B1010101,
                     B0101010,
                     B1010101,
                     B0101010,
                     B1010101,
                     B0101010,
                     B1010101,
                       B0000000};
                  
const int _A3[] = {B0111110,
                   B0000001,
                   B0000001,
                   B0001111,
                   B0000001,
                   B1000001,
                   B0111110,
                       B0000000};

const int _TEMP[] = {B0000011,
                     B0011111,
                     B0111111,
                     B1111110,
                     B1111111,
                     B0011111,
                     B0000011,
                       B0000000};

const int _LINE[] = {B0000001,
                     B0000001,
                     B0000001,
                     B0000001,
                     B0000001,
                     B0000001,
                     B0000001,
                       B0000000};                     
                 
const int _SMILE[] = {B1100110,
                      B1100110,
                      B0000000,
                      B0011100,
                      B1000001,
                      B0100010,
                      B0011100,
                      B0000000};                     
                  

const int _DOT[] = {B0000000,
                  B0000000,
                  B0000000,
                  B0000000,
                  B1100000,
                  B1100000,
                  B0000000,
                  B0000000};                     
                  
const int _COLDOT[] = {B0000000,
                       B0110000,
                       B0110000,
                       B0000000,
                       B0110011,
                       B0110011,
                       B0000000,
                       B0000000};                  

//Load the bitmap charachters into an array (each charachters position corresponds to its previously defined index (ie _A (a's bitmap) 
//is at index 0 and A = 0 so letters[A] will return the 'A' bitmap)
const int* letters[] = {_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,_COL,_DASH,_BRA2,__, _FULL, _CHECK, _A3, _TEMP, _LINE, _SMILE, _DOT, _COLDOT};

//Setup runs once when power is applied

// val : bit_2=caps_lock, bit_1=num_lock, bit_0=scroll_lock
void kbd_set_lights(byte val) {
  kbd.write(0xED);   
  kbd.read(); // pull out the ack byte
  kbd.write(val);     // now send the data
}

byte lookupCode() {
  byte result = ps2Keyboard_CharBuffer; 
  
  // Use a switch for the code to character conversion.
  // This is fast and actually only uses 4 bytes per simple line
  switch (result) {
  case 0x1C: result = A; break;
  case 0x32: result = B; break;
  case 0x21: result = C; break;
  case 0x23: result = 'd'; break;
  case 0x24: result = 'e'; break;
  case 0x2B: result = 'f'; break;
  case 0x34: result = 'g'; break;
  case 0x33: result = 'h'; break;
  case 0x43: result = 'i'; break;
  case 0x3B: result = 'j'; break;
  case 0x42: result = 'k'; break;
  case 0x4B: result = 'l'; break;
  case 0x3A: result = 'm'; break;
  case 0x31: result = 'n'; break;
  case 0x44: result = 'o'; break;
  case 0x4D: result = 'p'; break;
  case 0x15: result = 'q'; break;
  case 0x2D: result = 'r'; break;
  case 0x1B: result = 's'; break;
  case 0x2C: result = 't'; break;
  case 0x3C: result = 'u'; break;
  case 0x2A: result = 'v'; break;
  case 0x1D: result = 'w'; break;
  case 0x22: result = 'x'; break;
  case 0x35: result = 'y'; break;
  case 0x1A: result = 'z'; break;

      default:  delay(500); // but wait a bit in case part way through a shift
            ps2Keyboard_shift      = false;
            ps2Keyboard_ctrl       = false;
            ps2Keyboard_alt        = false;
            ps2Keyboard_extend     = false;
            ps2Keyboard_release    = false;
            ps2Keyboard_caps_lock  = false;
   ps2Keyboard_CharBuffer = 0;
  }
  return(result);
}

void kbd_init()
{
  char ack;

  kbd.write(0xff);  // send reset code
  ack = kbd.read();  // byte, kbd does self test
  ack = kbd.read();  // another ack when self test is done
}

void setup()
{

  Serial.begin(9600); 
  kbd_init();
  code = kbd.read();
        for(int i = 0; i <8; i++){  //Set the 16 pins used to control the array as OUTPUTs
    pinMode(rowA[i], OUTPUT);
    pinMode(colA[i], OUTPUT);
  }  



/*
 * get a keycode from the kbd and report it back to the
 * host via the serial line.
 */
}



void key()
{code = kbd.read();
// updateMatrix();   
    if( !code ) return; 
   // ignore null bytes
    
    // convert from scan code 
    switch (code) {
    case 0xF0: { // key release char
      ps2Keyboard_release = true;
      ps2Keyboard_extend = false;
         break;
    }
    case 0xFA: { // command acknowlegde byte
      cmd_ack_byte_ok = true;

Part3 -

 break;
    }
    case 0xE0: { // extended char set
      ps2Keyboard_extend = true;
      break;
    }
    case 0x12:   // left shift
    case 0x59: { // right shift
      ps2Keyboard_shift = ps2Keyboard_release? false : true;
      ps2Keyboard_release = false;
      break;
    }
    case 0x11: { // alt key (right alt is extended 0x11)
      ps2Keyboard_alt = ps2Keyboard_release? false : true;
      ps2Keyboard_release = false;
      break;
    }
    case 0x14: { // ctrl key (right ctrl is extended 0x14)
      ps2Keyboard_ctrl = ps2Keyboard_release? false : true;
      ps2Keyboard_release = false;
      break;
    }
    case 0x58: { // caps lock key
      if (!ps2Keyboard_release) {
      ps2Keyboard_caps_lock = ps2Keyboard_caps_lock? false : true;
      // allow caps lock code through to enable light on and off
        if (ps2Keyboard_caps_lock) kbd_set_lights(4);
        else                       kbd_set_lights(0);
      }
      else {
      ps2Keyboard_release = false;
      }
      break;
    }
    default: { // not a control key
      if (ps2Keyboard_release) { // ignore releases
        ps2Keyboard_release = false;
      }
      else { // real keys get sent out
        ps2Keyboard_CharBuffer = code;
        Serial.print(lookupCode(), BYTE);
       }
  }
}  
 
 
 
void loop()
{   
key();
updateMatrix();  
}

void updateMatrix(){
  loadSprite();
  showSprite(speed);
}

const int powers[] = {1,2,4,8,16,32,64,128};

void loadSprite(){
  int currentChar = getChar(requestString[index]);
  int nextChar = getChar(requestString[index+1]);
  
  for(int row=0; row < 8; row++){                    //iterate through each row
    data[row] = 0;                                   //reset the row we're working on
    for(int column=0; column < 8; column++){         //iterate through each column
     data[row] = data[row] + ((powers[column] & (letters[currentChar][row] << offset)));   //loads the current charachter offset by offset pixels 
     data[row] = data[row] + (powers[column] & (letters[nextChar][row] >> (8-offset) ));   //loads the next charachter offset by offset pixels
    }
  }
  offset++;                                          //increment the offset by one row
  if(offset==8){offset = 0; index++; if(index==sizeof(requestString)-2){index=0;}}         //if offset is 8 load the next charachter pair for the next time through
}

void showSprite(int speed2){
 for(int iii = 0; iii < speed2; iii++){                 //show the current frame speed2 times
  for(int column = 0; column < 8; column++){            //iterate through each column
   for(int i = 0; i < 8; i++){                          
       digitalWrite(rowA[i], LOW);                      //turn off all row pins  
   }
   for(int i = 0; i < 8; i++){ //Set only the one pin
     if(i == column){     digitalWrite(colA[i], LOW);}  //turns the current row on
     else{                digitalWrite(colA[i], HIGH); }//turns the rest of the rows off
   }

   for(int row = 0; row < 8; row++){                    //iterate through each pixel in the current column
    int bit = (data[column] >> row) & 1;
    if(bit == 1){ 
       digitalWrite(rowA[row], HIGH);                   //if the bit in the data array is set turn the LED on
    }

   }
   delayMicroseconds(pauseDelay);                       //leave the column on for pauseDelay microseconds (too high a delay causes flicker)
  } 
 }
}

int getChar(){}
 int returnValue;
 switch(character){
  case 'A': returnValue = A; break;
  case 'a': returnValue = A; break;
  case 'B': returnValue = B; break;
  case 'b': returnValue = B; break;
  case 'C': returnValue = C; break;
  case 'c': returnValue = C; break;
  case 'D': returnValue = D; break;
  case 'd': returnValue = D; break;
  case 'E': returnValue = E; break;
  case 'e': returnValue = E; break;
  case 'F': returnValue = F; break;
  case 'f': returnValue = F; break;
  case 'G': returnValue = G; break;
  case 'g': returnValue = G; break;
  case 'H': returnValue = H; break;
  case 'h': returnValue = H; break;
  case 'I': returnValue = I; break;
  case 'i': returnValue = I; break;
  case 'J': returnValue = J; break;
  case 'j': returnValue = J; break;
  case 'K': returnValue = K; break;
  case 'k': returnValue = K; break;
  case 'L': returnValue = L; break;
  case 'l': returnValue = L; break;
  case 'M': returnValue = M; break;
  case 'm': returnValue = M; break;
  case 'N': returnValue = N; break;
  case 'n': returnValue = N; break;
  case 'O': returnValue = O; break;
  case 'o': returnValue = O; break;
  case 'P': returnValue = P; break;
  case 'p': returnValue = P; break;
  case 'Q': returnValue = Q; break;
  case 'q': returnValue = Q; break;
  case 'R': returnValue = R; break;
  case 'r': returnValue = R; break;
  case 'S': returnValue = S; break;
  case 's': returnValue = S; break;
  case 'T': returnValue = T; break;
  case 't': returnValue = T; break;
  case 'U': returnValue = U; break;
  case 'u': returnValue = U; break;
  case 'V': returnValue = V; break;
  case 'v': returnValue = V; break;
  case 'W': returnValue = W; break;
  case 'w': returnValue = W; break;
  case 'X': returnValue = X; break;
  case 'x': returnValue = X; break;
  case 'Y': returnValue = Y; break;
  case 'y': returnValue = Y; break;
  case 'Z': returnValue = Z; break;
  case 'z': returnValue = Z; break;
  case ' ': returnValue = _; break;
  case '3': returnValue = A3; break;
  case '<': returnValue = TEMP; break;
  case '*': returnValue = FULL; break;
  case '|': returnValue = LINE; break;  
  case '_': returnValue = _; break;  
  case ':': returnValue = COL; break;  
  case '-': returnValue = DASH; break;  
  case ')': returnValue = BRA2; break;  
  case '%': returnValue = SMILE; break;  
  case '.': returnValue = DOT; break;    
  case '^': returnValue = COLDOT; break;      
  }
  return returnValue;
}

You haven't said what the problem is, but I think you will find it easier to see where you are going wrong if you start off by with a simpler sketch that doesn't attempt to get everything going at once.

For example you could start by just displaying the keyboard key on the serial monitor. That will help you get your keyboard interface and getChar function working. When you can correctly display the keyboard letters on the serial monitor you should find it easier to add the functionality to display this on the LED matrix.

Hey there, thanks for the reply. Yeah I know its a bit of a mess because I have been mudling with it so much. The serial output is fine, so the keyboard is having no trouble outputing at all.

When i press a key, the value is displayed in the serial box. This is great. However I want it to display on the matrix display as well and this is where I am having the trouble. No matter what I have tried it wont display any value typed in via keyboard on the display.

Thanks for helping - again much appreciated.

Have you tried to write a test sketch that just updates the matrix (without any keyboard code). Perhaps just sequencing through all the letters

Perhaps modify your updateMatrix function so it can be given a letter to display, for example:

void updateMatrix( char currentChar)
{
loadSprite(currentChar);
showSprite(speed);
}

I was having trouble with your example to get it to work, however when the code

requestString [] = "message";

is written at the top, when i press a key the message is displayed, only when I hit a key. Which is good however it writes that message and I am having trouble being able to over write this message with the serial input. Does give you any ideas how to fix?
I orginally tried using in void loop and where the letter is printed to screen:

if (Serial.available () > 0)
    {
      // read the incoming byte:
     incomingByte = Serial.read ();

      //Store it in a character array
     requestString[count] = incomingByte;
     count++;

      // if count = 1 than output letter to matrix display
      if (count == 1)
       {
          updateMatrix();
         count=0;
        }

However this did absoulutly nothing, just so frustrating thanks for your time :slight_smile:

How does "updateMatrix" know about "incomingByte"?

As a courtesy, when posting code, can you please delete all commented-out code, please?

Sorry Groove, will do from now on! I will rego through the post code and delete what is not needed. When I used incomingByte, it was to save it into requestString[], then in loadsprite it was suppose to be able to read the characters there.

I have now re-gone through it though and thought, since lookupCode() returns a char, why does requestString [] = {lookupCode()}; not seem to do anything? i thought this would return the value into the request string as well as display it on serial screen, however it seems to stop it being displayed on the serial screen?

Coding now only has the most important stuff that is needed at the moment.

I tried this under void key();

else { // real keys get sent out
ps2Keyboard_CharBuffer = code;
requestString[count] = lookupCode();
Serial.print(requestString[count]);
Serial.print(lookupCode(), BYTE);
requestString[count] = lookupCode();
count++;

I have found when printing requestString[count] to screen, it shows blank, however when i print lookupCode(), BYTE) it prints the letter to the screen - does this mean that lookupCode() is not being saved in the array requestString[]? at the start it is declared as requestString[] =""; so I assume for some reason it is not being over written?

it is declared as requestString[] ="";

...is an empty string, in effect a "char" array, with one element, filled with a zero.

if I declare requestString[] = {lookupCode()}; it does not do anything,
this is where it is not working I think.

You need to separate your declaration of requestString from your initialization/valuation of it.

int requestString[80]; // Or, however big it needs to be

cheers paul, thats helped a lot I have now set the requestString[1000] and in my code i have got:

ps2Keyboard_CharBuffer = code;
requestString[count] = ' ';
count++;
requestString[count] = lookupCode();
Serial.print(requestString[count]);
count++;
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();
updateMatrix();

This writes it to the screen as well as to my matrix display - although its not the best coding I can't see away around it and it seems to work.

Thanx!

Two things:

  1. the numerous calls to updateMatrix.
For(int i = 0; i < 10; i += 1)
{
  updateMatrix();
}

A for loop is ideal for that, the loop above will execute updateMatrix 10 times, I'd suggest using it in your code, preferably with a command stating why it has to be run X times.

  1. int requestString[1000] will bite your hiney.
    Assuming you use a duemilanove with atmega328, you've just given that array all the memory it has, leaving only a couple of bytes for the rest of your program.
    I'd suggest lowering it to 100 or so. If you need to store more than that, it is best to look for alternative ways to store it somehow, or to simply ignore them, depending on the situation.
    An atmega328 has 2kb of memory, or 2048 bytes (not 1000 bytes per kilobyte, which the hard-drive manufacturers want you to believe).
    An int takes 2 bytes of memory, so an array of 1000 ints will take at least 2000 bytes to store, and I don't know how many bytes of overhead the arduino platform takes.

Hope this helped!

Thats awsome, thanks for that, maybe its why it is going a bit slow.

cheers