Removing garbage Values from an array

Hello all,

I have written a code for displaying Keyboard data on LCD.
When i press the RETURN key it shows data stored in the array InputMsg[20]. However, it also fills in the unused space of array with garbage value, how will i overcome this?

Attached an image showing the problem.

the input i gave was “Hello All” the remaining inputs are garbage value.

Regards.

#include <LiquidCrystal.h>
#include <PS2Keyboard.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 13, 14, 15, 16, 17);

const int DataPin = 2;
const int IRQpin =  3;

char InputMsg[20];
static int i = 0;
char KbChars;


PS2Keyboard keyboard;
 

void setup() {
  lcd.begin(16, 2);
  delay(100);
  keyboard.begin(DataPin, IRQpin);
  lcd.setCursor(0, 0);
  lcd.print("Input Message:");
  lcd.setCursor(0, 1);
}
 
void loop() {


 
 // Turn off the cursor:
  lcd.noCursor();
  delay(100);
  // Turn on the cursor:
  lcd.cursor();
  delay(100);
 
if (keyboard.available()) {
 

  // read the next key
    KbChars = keyboard.read();
        

   if (KbChars == PS2_ESC) {
      clear();
                          }
 /////////////////////FUNCTION/////////////////////    
     else if (KbChars == PS2_ENTER) {
                lcd.clear();
                delay(100);
                for(int k=0;k<20;k++)
                {
                 lcd.print(InputMsg[k]);
                }
               }
 ///////////////////////FUNCTION/////////////////////  
   
   else
   {
      // otherwise, just print all normal characters
      lcd.print(KbChars);
    }
    InputMsg[i] = KbChars;
    i++;
    InputMsg[i] = '\0';  // terminate the string

    }
  }


void clear()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Input Message:");
  KbChars = keyboard.read();
  lcd.setCursor(0, 1);
}

                int k=0;
                while(InputMsg[k] != '\0')
                {
                 lcd.print(InputMsg[k]);
                  k++:
                }

When i press the RETURN key

At first sight I cannot see a test for the Return key in your code.

However, I do see that if you receive more than 8 characters you print the entire contents of the buffer. Why not just print the number of characters that you have received instead of all 20 ?

Sorry, that was an older code, thanks for pointing it out UKHeliBob.

#include <LiquidCrystal.h>
#include <PS2Keyboard.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 13, 14, 15, 16, 17);

const int DataPin = 2;
const int IRQpin =  3;

char InputMsg[20];
static int i = 0;
char KbChars;


PS2Keyboard keyboard;
 

void setup() {
  lcd.begin(16, 2);
  delay(100);
  keyboard.begin(DataPin, IRQpin);
  lcd.setCursor(0, 0);
  lcd.print("Input Message:");
  lcd.setCursor(0, 1);
}
 
void loop() {


 
 
 // Turn off the cursor:
  lcd.noCursor();
  delay(100);
  // Turn on the cursor:
  lcd.cursor();
  delay(100);
 
if (keyboard.available()) {
 

  // read the next key
    KbChars = keyboard.read();
        

   if (KbChars == PS2_ESC) {
      clear();
                          }
 /////////////////////FUNCTION/////////////////////    
     else if (KbChars == PS2_ENTER) {
                lcd.clear();
                delay(100);
                for(int k=0;k<20;k++)
                {
                 lcd.print(InputMsg[k]); 
                }
               }
 ///////////////////////FUNCTION/////////////////////  
   
   else
   {
      // otherwise, just print all normal characters
      lcd.print(KbChars);
    }
    InputMsg[i] = KbChars;
    i++;
    InputMsg[i] = '\0';  // terminate the string

    }
  }


void clear()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Input Message:");
  KbChars = keyboard.read();
  lcd.setCursor(0, 1);
}

Also, in the above program how will i clear the data of array once i press Escape key?

i tried writing

if (KbChars == PS2_ESC) {

       InputMsg[i] = '\0';
      clear();
                          }

but it doesn’t help.

Thank You.

Instead of

      delay(100);
      for (int k = 0; k < 20; k++)
      {
        lcd.print(InputMsg[k]);
      }

just do

lcd.print(InputMsg);

It will stop at the terminating zero in the array.

Also, in the above program how will i clear the data of array once i press Escape key?

You don’t need to as long as when you receive a character you put the zero after it.

Incidentally, you are not counting the number of characters entered, so if the user enters 20 characters or more you will write outside of the memory allocated to the array.

UKHeliBob:
You don't need to as long as when you receive a character you put the zero after it.

But if i don't clear the array, and press ESCAPE key, the data still remains in the Array and the LCD gets cleared, according to what have i written in the code for "void clear()".
Now,when i type new from keyboard, it gets concatenated to the previous data.

Now,when i type new from keyboard, it gets concatenated to the previous data.

Only if you don't set the array index variable back to zero before handling the first character in the new string

Hi everyone,

I’m using my PS2 keyboard and an LCD to set a password.
The program i have written works as follows:
Read Keyboard Characters–> If TAB key pressed–> LCD displays “Enter Password”–> I enter password of characters of length not more than password[6],i.e. 5 Characters.–> Then i press Enter Key–> LCD shows “Password Set”.
However, right after the TAB key operation, i face some bugs:
1)Garbage values written on LCD.(in the attached picture,please see)
2)When i press ENTER key,it gets printed on the LCD instead of showing “PASSWORD is…”

I know where am I wrong–>in the declaration of IF loop concerning the ENTER key.
What should i do to correct this?
Regards. :slight_smile:

#include <LiquidCrystal.h>
#include <PS2Keyboard.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 13, 14, 15, 16, 17);

const int DataPin = 2;
const int IRQpin =  3;


PS2Keyboard keyboard;

char KbChars;
char array[50];
char inByte;
char password[6];
int i=0;

void setup() {

  lcd.begin(16, 2);
  delay(100);
  keyboard.begin(DataPin, IRQpin);
  lcd.setCursor(0, 0);
  lcd.print("Input Message:");
  lcd.setCursor(0,1);
 } 


void loop() {
 
   if (keyboard.available()) {
  KbChars=keyboard.read();
  
  if (KbChars == PS2_TAB) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Enter Password:");
      lcd.setCursor(0, 1);
      KbChars=keyboard.read();
      lcd.print(KbChars);
        password[i]=KbChars;
        i++;
        password[i]='\0';
      if(i==6 || KbChars == PS2_ENTER){
                lcd.clear();
                lcd.setCursor(0, 0);
                lcd.print("Password is:");
                delay(100);
                while(password[i] != '\0')
                {
                 lcd.setCursor(0, 1);
                 lcd.print(password[i]);
                  i++;
                }
               }
      }
      lcd.print(KbChars);
      }
      
  }

DSC_3664.jpg

The program that you have posted has no chance of working.
Once the user presses the tab key you immediately read the keyboard again. How likely is it that the user will have pressed enter by then ?

Even if that worked you never set the array index i back to zero in the program.

If I were you I would have a variable whose state, perhaps 0, 1, 2 etc indicates what stage the program is at, test it, perhaps using switch/state, to take the appropriate action

state is 0
  read keyboard until use presses tab then move to state 1
state 1
  read keyboard
  if user presses enter move to state 2
  if index equal 6 move to state 2
  display character entered
state 2
  do whatever you want/need with the password

As suggested by UKHeliBob i tried using the Switch Case statement, it works good with ENTER and TAB keys,i.e. cases of the switch, but doesn’t accept any characters inside the case loop.
the problem occurs where ////Problem///// sign is shown.

Thank you.

#include <LiquidCrystal.h>
#include <PS2Keyboard.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 13, 14, 15, 16, 17);

const int DataPin = 2;
const int IRQpin =  3;


PS2Keyboard keyboard;

char KbChars;
char array[50];
char inByte;
char password[6];
int i=0;

void setup() {

  lcd.begin(16, 2);
  delay(100);
  keyboard.begin(DataPin, IRQpin);
  lcd.setCursor(0, 0);
  lcd.print("Input Message:");
  lcd.setCursor(0,1);
 } 


void loop() {
 // read the sensor:
  KbChars=keyboard.read();
  
   switch (KbChars) {
    case PS2_TAB:
      lcd.clear(); 
      lcd.setCursor(0,0);
      lcd.print("Password:");
      lcd.setCursor(0,1);
///////////////////////////////////////////Problem/////
      KbChars=keyboard.read();
      lcd.print(KbChars);
      break;
   
    case PS2_ENTER: 
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Password Set");
      lcd.setCursor(0,1);
///////////////////////////////////////////Problem/////
      KbChars=keyboard.read();
      lcd.print(KbChars);
      break;
    
  }
  delay(1);        // delay in between reads for stability
}

The code in case PS2_ENTER: will only be executed when enter is received, not for any other character, which is what is causing the problem.

My suggestion was based on using a state variable whose value would determine which section of code was executed.

This is the sort of structure that I had in mind

byte state = 0;

void loop()
{
  KbChars = keyboard.read();

  switch (state)
  {
    case 0:
      if (KbChars == PS2_TAB)
      case = 1;
      break;

    case 1:
      if (KbChars == PS2_ENTER || inputIndex == 6)
      case = 2;
      lcd.print(KbChars);
      inputIndex++;
      break;

    case 2:
      inputIndex = 0;
      //do what you want with the password
      break;
  }
}

NOTE that this is not a complete solution, merely an idea. For instance no messages are printed nor is the password saved to the array but these can be added at appropriate points.

Actually its not just the password and keyboard, i have many other functions to be performed:
1)input message->Display it
2)Cipher that message-->Display it
3)Set a key(password), This is the only case where i need to use the keyboard keys THRICE in one function (One for Entering the Password Loop,And second to Enter the Key,third for breaking out from the loop)

Hence Im afraid that using what you suggested will not be advisable for whole process.
Is there a way i can use Three keys in a row, like i explained for setting password?

The state machine will work fine alongside other functions or you can incorporate other functions within it. For instance you could encrypt the password once it reached state 2. If you set state to a number not recognised by the switch/case then the code will simply be ignored if that is what you want.

Is there a way i can use Three keys in a row, like i explained for setting password?

That is exactly what the state machine does

Thanks Bob,
Ill try it and repost about the results.

I suggest that you get the password input, including saving to a zero terminated array of chars working first.

okay,as you say. :slight_smile: Will work out that first.

I have done displaying of message and ciphering it using the ROT13, all works well but:

  1. When i press tab key for encrypting the text, Ciphered message is shown,however,a Garbage value is also printed on LCD, now this is NOT actually GARBAGE value,but its the value of TAB key. how?

As many times i press TAB, the text gets ciphered and another Garbage(TAB value) gets added at the end. See attachment 1 and 2.
Same is for the ENTER Key.

What should i do so that it is not printed on LCD?

  1. When ESCAPE (ESC) pressed, the loop is refreshed, but LCD starts from the position (1,1) instead of (0,1). I dont get why.

The Code:

#include <LiquidCrystal.h>
#include <PS2Keyboard.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 13, 14, 15, 16, 17);

const int DataPin = 2;
const int IRQpin =  3;


PS2Keyboard keyboard;

char KbChars;
char array[50];
char inByte;
int i=0;

void setup() {

  lcd.begin(16, 2);
  delay(100);
  keyboard.begin(DataPin, IRQpin);
  i=0;
  lcd.setCursor(0, 0);
  lcd.print("Input Message:");
  lcd.setCursor(0,1);
 } 

void loop() {
 
//Blinking  
  lcd.noCursor();
  delay(100);
  lcd.cursor();
  delay(100);
//Blinking
  
   if (keyboard.available()) {
  KbChars=keyboard.read();
  
  if (KbChars == PS2_ESC)
      {
      lcd.clear();
      delay(500);
      setup();
      }
  if (KbChars == PS2_TAB) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Ciphered Text:");
      lcd.setCursor(0, 1);
      rot13();
      lcd.print(array);
    }
    if (KbChars == PS2_ENTER) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Main:");
      lcd.setCursor(0, 1);
      lcd.print(array);
    }
    
    
    array[i]=KbChars;
    i++;
    lcd.print(KbChars);
  }
}
   

void rot13() {

         for (int i = 0; i <= 50; ++i) {  
            inByte = array[i];
       if (!inByte) return; //end of string reached
          
        if (inByte >= 'A' && inByte <= 'M')
            inByte +=13;
        else if (inByte >= 'a' && inByte <= 'm')
            inByte +=13;
        else if (inByte >= 'N' && inByte <= 'Z')
            inByte -=13;
        else if (inByte >= 'n' && inByte <= 'z')
            inByte -=13;

        array[i] = inByte;
     }
    }

I thought that you were going to get the password input working first.

As to the program that you posted, nowhere do you put the terminating zero in the array.

I can't help feeling that we are going round in circles.

But adding a terminating Zero wont really help, the output is still the same. See the pictures in attachments.
Pic 1&2 refers to problem 1.
Pic 3 is for problem 2.

Thank You.

I will be working on my PASSWORD problem as soon as i remove these small bugs.