printing multiple characters on LCD

Hi,
Hopefully I'm already on the right track, but I just want to confirm that I should be using an array to print and store key presses on an lcd screen after sequential inputs.

I want to print (and later save) an input from a user that is 8 characters long (say, 12345678) after they've entered it on a keypad.

Yes, an array is ideal for this. If you ensure that the character after the last one entered is at all times character(0) then what you have there is a C string, with which you can do such things as compare it with strcmp(), etc.

much appreciated.
regarding your advice, would it be better/simpler to have the user input the 8 characters followed by a terminating character, like say '#'.

If it is always 8 characters then the terminating character isn't needed. If, on the other hand, it could be less, or you want to give the ability to go back and edit, then a terminating character can be useful, yes.

It's up to you :wink:

great, thank you.

Onsan:
much appreciated.
regarding your advice, would it be better/simpler to have the user input the 8 characters followed by a terminating character, like say '#'.

A terminating character would be preferable as it would allow you to positively identify the end of the input, but it is very possible that the input is already terminated by a carriage return, line feed or both and you could use that.

Cheers Bob.

I'm making a noob mistake here, I can't seem to work out why my loop isn't looping and why I can't get the code to progress.
I have a narrow window to enter the key press, I was hopping to have the program wait for a key press before moving on, and then once the 4 numbers have been gathered, the program to move on and loop around.
Would someone mind pointing out where I've gone wrong?
cheers.

  #include <Wire.h>
  #include <LCDi2cW.h>                    
  LCDi2cW lcd = LCDi2cW(4,20,0x4C,0); 
  char buttons[17] = { ' ','1', '4', '7', '*', '2', '5','8','0','3','6','9','#','A','B','C','D' };
  char KeySeq[4];
  int i;
  
  void setup()
    { 
      lcd.init(); 
    }
  
  void loop()
    {
      lcd.clear();
      lcd.setCursor(1,8);
      
      byte digit = lcd.keypad();
      char displayChar = buttons[digit];
      KeySeq[i] = displayChar;
      i++;
      
      if (displayChar)
         {
           lcd.print(KeySeq[0]);
           lcd.print(KeySeq[1]);
           lcd.print(KeySeq[2]);
           lcd.print(KeySeq[3]);
         }
      if (displayChar == '#')
         {
           lcd.clear();
         }
    }

Just think what happens if no key is pressed. It is no good simply hoping. You need to write code that waits for a key to be pressed, then dealers with that one key and the waits until it is released before going on to the next key. Also why not just print the keys to the LCD as they come in instead of printing them all when ever one key OS pressed.

In short the code is no where close to being right.

I read a post by the author of the keypad lib that he felt people misused the NO_KEY function, I was trying to heed that in not using it, my use might have been misplaced?
read hoping as "my intention", it was a colloquial turn of phrase.
I'm not sure by what you mean re: printing them as they come rather then whenever one is pressed; when put in use, the code prints the character, holds it on the screen and prints the next number pressed, this is what I was aiming for, however the program doesn't wait around if you take to long to make the input and moves on to the next position in the array.

however the program doesn't wait around if you take to long to make the input and moves on to the next position in the array.

That's what you need to deal with. Don't move on until a key IS pressed.

The concept I understand, the solution I don't.
I thought 'while' would be the way to go but I can't get it to work the way I understood it to.

  #include <Wire.h>
  #include <LCDi2cW.h>                    
  LCDi2cW lcd = LCDi2cW(4,20,0x4C,0); 
  char buttons[17] = { '_','1', '4', '7', '*', '2', '5','8','0','3','6','9','#','A','B','C','D' };
  char KeySeq[4];
  int i=0;
  
  void setup()
    { 
      lcd.init(); 
    }
  
  void loop()
    {
      lcd.clear();
      lcd.setCursor(1,8);
      
      byte digit = lcd.keypad();
      char displayChar = buttons[digit];
      KeySeq[i] = displayChar;
        
      while(displayChar == '_'){}
            
      if (displayChar)
         {
           lcd.print(KeySeq[0]);
           i++;
          }
      if (displayChar)
         {
           lcd.print(KeySeq[1]);
           i++;
          }
      if (displayChar)
         {
           lcd.print(KeySeq[2]);
           i++;
          }
      if (displayChar)
         {
           lcd.print(KeySeq[3]);
           i++;
          }      
      if (displayChar == '#')
         {
           lcd.clear();
           i=0;
         }
      
    }
      byte digit = lcd.keypad();
      char displayChar = buttons[digit];
      KeySeq[i] = displayChar;

What is the value of digit when no key is pressed? Is that a valid index into the buttons array?

      while(displayChar == '_'){}

This is an infinite loop, since displayChar never changes while the loop is running.

You want a while loop that checks lcd.keypad(). break; out of the while loop when a key is pressed. THEN use that key.

PaulS:
What is the value of digit when no key is pressed? Is that a valid index into the buttons array?

That's an answer I don't know for sure. In the keypad.h there is the NO_KEY funtion, but in the LCDi2cW lib, NO_KEY doesn't work.
I think that in my buttons array, the first character '' is equivalent to "NO_KEY", (I normally use ' ' in the array- without the _ ), so I believe that the value of the digit is '' in this instance. When I modified the keypad example in the LCDi2cW lib to use my buttons array it returned the _ until a key was pressed. Does that sound right?

PaulS:
You want a while loop that checks lcd.keypad(). break; out of the while loop when a key is pressed. THEN use that key.

Ok, that's given me something to work with, I'll work on applying that, thank you.
Paul S (too)

That's an answer I don't know for sure.

Print it, and learn something.

I think that in my buttons array, the first character '_' is equivalent to "NO_KEY",

Only if the function returns a value of 0 when no key is pressed. If -1 means no key, then using that as an index into the buttons array is not valid.

When I modified the keypad example in the LCDi2cW lib to use my buttons array it returned the _ until a key was pressed. Does that sound right?

Yes. And, the assumption that lcd.keypad() returns 0 when no key is pressed is probably valid. On the other hand, it would take less than 5 minutes to know for sure.

Yes to all, I've done those steps, that's how I came up with what I believe is happening.
When I run the standard keypad example from the lcdi2cW lib, not pressing a key returns 0, pressing any of the keys returns a value 1-16.
With my buttons array, the '_' replaces the 0. It returns _ until a key is pressed, then it returns the correctly assigned array value.
So, I believe that's the answer, I'm just new to this and not confident that I've understood everything correctly.

Hi,
I've modified the sketch and I believe the 'while' function is working now, but the approach I've used to add the key presses to the array and the lcd screen is not successful.
It prints it to the screen but still cycles through the array rather than waiting for the next key press.
I thought then that I needed to halt the loop between each 'if' statement using the 'while' function again, but needless to say, that didn't work either.
This is what I'm working with at the moment;

  #include <Wire.h>
  #include <LCDi2cW.h>                    
  LCDi2cW lcd = LCDi2cW(4,20,0x4C,0); 
  char buttons[17] = { '_','1', '4', '7', '*', '2', '5','8','0','3','6','9','#','A','B','C','D' };
  char KeySeq[4];
  int i=0;
  
  void setup()
    { 
      lcd.init(); 
    }
  
  void loop()
    {
      byte digit = lcd.keypad();
      char displayChar = buttons[digit];
      KeySeq[i] = buttons[digit];
        
      while(displayChar == '_')
        {
          lcd.keypad();
          break;
        }
      if (displayChar != '_')
         {
           lcd.setCursor(1,8);          
           lcd.print(KeySeq[i]);
           i++;
          }
      if (displayChar != '_')
         {
           lcd.setCursor(1,9);
           lcd.print(KeySeq[i]);
           i++;
          }
      if (displayChar != '_')
         {
           lcd.setCursor(1,10);
           lcd.print(KeySeq[i]);
           i++;
          }
      if (displayChar != '_')
         {
           lcd.setCursor(1,11);
           lcd.print(KeySeq[i]);
           i++;
          }      
      if (displayChar == '#')
         {
           lcd.clear();
           i=0;
         }
      
    }

Any advice one where I've gone wrong?

Thank you.

Loose the break instruction it is just making the while loop not work.
Then you don't need the second if.
I stopped looking at the code after that so there might be more errors.

Try and think what the code is doing running through things in your mind.

      byte digit = lcd.keypad();
      char displayChar = buttons[digit];
      KeySeq[i] = buttons[digit];

What is this doing if no switch is pressed? Is that what you want?

      while(displayChar == '_')
        {
          lcd.keypad();
          break;
        }

If displayChar is '', this will make a useless call to lcd.keypad (useless because the returned value is discarded), and then break out of the while loop. If displayChar is not '', this does nothing. The combination of possibilities means that this loop does exactly nothing.

Ok, thanks guys, will go through it with that in mind.

Cheers.