Change push button to keypad button

Hello all.
I have a small project where I want to scroll text vertically on a 16x2 LCD display. I found some examples and different bits of code searching the interwebs, and SUCCESS!!!. Code worked, project worked, all is good.

The project is basically an lcd display and a 4x4 keypad. A cde is entered on the keypad that activates a message on the lcd. This text message is sent in several lines, which are scrolled vertically by pressing a push button to scroll each line.
i would like to swap out the push button for a key on the keypad, so I can save space and use less components.

This is my code:

#include <LiquidCrystal.h>
#include <Keypad.h>

LiquidCrystal lcd (13, 12, 11, 10, 9, 8); // pins of the LCD. (RS, E, D4, D5, D6, D7)

int redLED = 5;           //define the LED pins
int greenLED = 6;
int scrollButton = 7;
int counter = 0;
int buttonState = 0;
int lastButtonState = 0;
int i = 0;
int currentButtonState = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

byte DOWN[8] = {            //Custom DOWN arrow char
  0b00000,
  0b00000,
  0b00000,
  0b00100,
  0b00100,
  0b11111,
  0b01110,
  0b00100
};

char *myStrings[] = {"Buen Trabajo!", "Ha conseguido", "un valioso",
                     "punto tactico.", "Ahora podra", "recibir datos de",
                     "la Comandancia", "sintonizando la", "frecuencia ",
                     "463.75 MHz", "Atentos!!", "FIN MENSAJE" 
                    };

char* password ="1825";       //this is the password

int pozisyon = 0;             //cursor position on lcd

const byte rows = 3;          //number of the keypad's rows and columns
const byte cols = 3;
char keyMap [rows] [cols] = { //define the symbols on the buttons of the keypad
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  };
byte rowPins [rows] = {A0, A1, A2}; //pins of the keypad
byte colPins [cols] = {A3, A4, A5};

Keypad myKeypad = Keypad( makeKeymap(keyMap), rowPins, colPins, rows, cols);

void setup() {
  lcd.begin(16,2); 
  pinMode(scrollButton, INPUT);
  lcd.createChar(2, DOWN);
  pinMode(redLED, OUTPUT);         //set the LED as an output
  pinMode(greenLED, OUTPUT);
  setLocked (true);               //state of the password
}

   //---- De-bouncing function for all buttons----//
boolean debounce(boolean last, int pin)
{
boolean current = digitalRead(pin);
if (last != current)
{
delay(5);
current = digitalRead(pin);
}
return current;
}

void loop() {

  char whichKey = myKeypad.getKey();  //define which key is pressed with getKey
  
  lcd.setCursor(0, 0);
  lcd.print("Introduzca");              //lcd initial text
  lcd.setCursor(0, 1);
  lcd.print("Codigo");

  if(whichKey == '*' || whichKey == '#' || whichKey == 'A' ||       //define invalid keys
  whichKey == 'B' || whichKey == 'C' || whichKey == 'D' || whichKey == '0'){

    pozisyon=0;
    setLocked (true);
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Codigo Invalido!");
    delay(1000);
    lcd.clear();
  }
  if(whichKey == password [pozisyon]){

    pozisyon ++;
  }
  if(pozisyon == 4){
    setLocked (false);
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("** Verificado **");      //message if password entered is correct
    delay(3000);
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Instrucciones");
    lcd.setCursor(2, 1);
    lcd.print("Entrantes");
    lcd.clear();
    delay(3000);                        //wait 3 seconds before clearing this message
}
  
  currentButtonState = digitalRead(scrollButton);

  if (currentButtonState != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (currentButtonState != buttonState) {
      buttonState = currentButtonState;
      if (buttonState == LOW) {
        while (i < 12) { 
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print(myStrings[i]);
   lcd.setCursor(0, 1);
   lcd.print(myStrings[i+1]);
   lcd.setCursor(15,1);
   lcd.write(byte(2));
   delay(1000);
   i++;
   break;
        }
      }
    }
  }
  lastButtonState = currentButtonState;
  if (i>=12) {
   i = 0;
   }
}

void setLocked(int locked){
  if(locked){
    digitalWrite(redLED, HIGH);
    digitalWrite(greenLED, LOW);
    }
    else{
      digitalWrite(redLED, LOW);
      digitalWrite(greenLED, HIGH);
    }
  }

My problem is do I use a getkey() to prompt for the key press here:?

    if (buttonState == LOW) {
        while (i < 12) { 
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print(myStrings[i]);
   lcd.setCursor(0, 1);
   lcd.print(myStrings[i+1]);
   lcd.setCursor(15,1);
   lcd.write(byte(2));
   delay(1000);
   i++;
   break;
        }

I have a debouncing set up before the if condition above, will it work here inside this if statement?

This is where I am stumped.

Any help will be appreciated.

That depends on the library which you are using. Does it have Arduino sample code?

I'm using the Keypad.h library.
What do you mean by "Ardino smaple code"?

That's a header file that belongs to a library. A library should come with documentation and example programs.

Let me take a look at that. Thanks

Hi @capetito
Which keyboard key would you like to use to replace the button?

It cannot be the numbers from 0 to 9, as these are used to test the password.

It could be any of these:

  • , # , A, B, C or D.

I was thinking about 'D', since it's nicely placed in the corner.
Could you elaborate on why I can't use the number keys?

Hi @capetito
You cannot use numeric keys as they are used in the password routine and using them to scroll will conflict.

Test this code..
I used the D key as per your suggestion.

#include <LiquidCrystal.h>
#include <Keypad.h>

LiquidCrystal lcd (13, 12, 11, 10, 9, 8); // pins of the LCD. (RS, E, D4, D5, D6, D7)

int redLED = 5;           //define the LED pins
int greenLED = 6;
int scrollButton = 7;
int counter = 0;
int buttonState = 0;
int lastButtonState = 0;
int i = 0;
int currentButtonState = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

byte DOWN[8] = {            //Custom DOWN arrow char
  0b00000,
  0b00000,
  0b00000,
  0b00100,
  0b00100,
  0b11111,
  0b01110,
  0b00100
};

char *myStrings[] = {"Buen Trabajo!", "Ha conseguido", "un valioso",
                     "punto tactico.", "Ahora podra", "recibir datos de",
                     "la Comandancia", "sintonizando la", "frecuencia ",
                     "463.75 MHz", "Atentos!!", "FIN MENSAJE"
                    };

char* password = "1825";      //this is the password

int pozisyon = 0;             //cursor position on lcd

const byte rows = 3;          //number of the keypad's rows and columns
const byte cols = 3;
char keyMap [rows] [cols] = { //define the symbols on the buttons of the keypad
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
};
byte rowPins [rows] = {A0, A1, A2}; //pins of the keypad
byte colPins [cols] = {A3, A4, A5};

Keypad myKeypad = Keypad( makeKeymap(keyMap), rowPins, colPins, rows, cols);
//-----------------------------------------------------------------------------
void setup() {
  lcd.begin(16, 2);
  pinMode(scrollButton, INPUT);
  lcd.createChar(2, DOWN);
  pinMode(redLED, OUTPUT);         //set the LED as an output
  pinMode(greenLED, OUTPUT);
  setLocked (true);               //state of the password
}
//-----------------------------------------------------------------------------
//---- De-bouncing function for all buttons----//
boolean debounce(boolean last, int pin)
{
  boolean current = digitalRead(pin);
  if (last != current)
  {
    delay(5);
    current = digitalRead(pin);
  }
  return current;
}
//-----------------------------------------------------------------------------
void loop() {

  char whichKey = myKeypad.getKey();  //define which key is pressed with getKey

  lcd.setCursor(0, 0);
  lcd.print("Introduzca");              //lcd initial text
  lcd.setCursor(0, 1);
  lcd.print("Codigo");

  if (whichKey == '*' || whichKey == '#' || whichKey == 'A' ||      //define invalid keys
      whichKey == 'B' || whichKey == 'C' || whichKey == '0') {

    pozisyon = 0;
    setLocked (true);
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Codigo Invalido!");
    delay(1000);
    lcd.clear();
  }

  if (whichKey == password [pozisyon]) {

    pozisyon ++;
  }
  if (pozisyon == 4) {
    setLocked (false);
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("** Verificado **");      //message if password entered is correct
    delay(3000);
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Instrucciones");
    lcd.setCursor(2, 1);
    lcd.print("Entrantes");
    lcd.clear();
    delay(3000);                        //wait 3 seconds before clearing this message
  }
  if (whichKey == "D")                  // If Key pressed was D rotate LCD
  {
    while (i < 12) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(myStrings[i]);
      lcd.setCursor(0, 1);
      lcd.print(myStrings[i + 1]);
      lcd.setCursor(15, 1);
      lcd.write(byte(2));
      delay(1000);
      i++;
      break;
    }
  }
  i = 0;

  //  currentButtonState = digitalRead(scrollButton);
  //
  //  if (currentButtonState != lastButtonState) {
  //    lastDebounceTime = millis();
  //  }

  //  if ((millis() - lastDebounceTime) > debounceDelay) {
  //    if (currentButtonState != buttonState) {
  //      buttonState = currentButtonState;
  //      if (buttonState == LOW) {
  //        while (i < 12) {
  //          lcd.clear();
  //          lcd.setCursor(0, 0);
  //          lcd.print(myStrings[i]);
  //          lcd.setCursor(0, 1);
  //          lcd.print(myStrings[i + 1]);
  //          lcd.setCursor(15, 1);
  //          lcd.write(byte(2));
  //          delay(1000);
  //          i++;
  //          break;
  //        }
  //      }
  //    }
  //  }
  //  lastButtonState = currentButtonState;
  //  if (i >= 12) {
  //    i = 0;
  //  }
}
//-----------------------------------------------------------------------------
void setLocked(int locked) {
  if (locked) {
    digitalWrite(redLED, HIGH);
    digitalWrite(greenLED, LOW);
  }
  else {
    digitalWrite(redLED, LOW);
    digitalWrite(greenLED, HIGH);
  }
}

Hi @ruilviana
I tried your code and it worked after some minor adjustments. Maybe it was problems with my original code???
This is what I ended up with:

#include <LiquidCrystal.h>
#include <Keypad.h>

LiquidCrystal lcd (13, 12, 11, 10, 9, 8); // pins of the LCD. (RS, E, D4, D5, D6, D7)

int redLED = 5;           //define the LED pins
int greenLED = 6;
int scrollButton = 7;
int i = 0;


byte DOWN[8] = {            //Custom DOWN arrow char
  0b00000,
  0b00000,
  0b00000,
  0b00100,
  0b00100,
  0b11111,
  0b01110,
  0b00100
};

char *myStrings[] = {"EMPIEZA MENSAJE", "Buen Trabajo!", "Ha conseguido", "un valioso",
                     "punto tactico.", "Ahora podra", "recibir datos de",
                     "la Comandancia", "sintonizando la", "frecuencia ",
                     "463.75 MHz", "Atentos!!", "FIN MENSAJE"
                    };

char* password = "1825";      //this is the password

int pozisyon = 0;             //cursor position on lcd

const byte rows = 4;          //number of the keypad's rows and columns
const byte cols = 4;
char keyMap [rows] [cols] = { //define the symbols on the buttons of the keypad
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'},
};
byte rowPins [rows] = {A0, A1, A2, 4}; //pins of the keypad
byte colPins [cols] = {A3, A4, A5, 3};

Keypad myKeypad = Keypad( makeKeymap(keyMap), rowPins, colPins, rows, cols);

void setup() {
  lcd.begin(16, 2);
  pinMode(scrollButton, INPUT);
  lcd.createChar(2, DOWN);
  pinMode(redLED, OUTPUT);         //set the LED as an output
  pinMode(greenLED, OUTPUT);
  setLocked (true);               //state of the password

  //////lcd initial text
  lcd.setCursor(3, 0);
  lcd.print("Introduzca");
  lcd.setCursor(5, 1);
  lcd.print("Codigo");
}

//---- De-bouncing function for all buttons----//
boolean debounce(boolean last, int pin)
{
  boolean current = digitalRead(pin);
  if (last != current)
  {
    delay(5);
    current = digitalRead(pin);
  }
  return current;
}

void loop() {

  char whichKey = myKeypad.getKey();  //define which key is pressed with getKey

  if (whichKey == '*' || whichKey == '#' || whichKey == 'A' ||      //define invalid keys
      whichKey == 'B' || whichKey == 'C' || whichKey == 'D' || whichKey == '0') {

    pozisyon = 0;
    setLocked (true);
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Codigo Invalido!");
    delay(1000);
    lcd.clear();
    lcd.setCursor(3, 0);
    lcd.print("Introduzca");
    lcd.setCursor(5, 1);
    lcd.print("Codigo");
    delay(500);
  }
  if (whichKey == password [pozisyon]) {

    pozisyon ++;
  }
  if (pozisyon == 4) {
    setLocked (false);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("** Verificado **");      //message if password entered is correct
    delay(1000);
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Instrucciones");
    lcd.setCursor(3, 1);
    lcd.print("Entrantes");
    delay(1000);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Pulse Boton para");
    lcd.setCursor(3, 1);
    lcd.print("continuar");
  }

  if (whichKey == 'D') {
    while (i < 13) {
      lcd.clear();        //check process
      lcd.setCursor(0, 0);
      lcd.print(myStrings[i]);
      lcd.setCursor(0, 1);
      lcd.print(myStrings[i + 1]);
      lcd.setCursor(15, 1);
      lcd.write(byte(2));
      i++;
      break;
    }
  }
  if (i >= 13) {
    i = 0;
  }
}

void setLocked(int locked) {
  if (locked) {
    digitalWrite(redLED, HIGH);
    digitalWrite(greenLED, LOW);
  }
  else {
    digitalWrite(redLED, LOW);
    digitalWrite(greenLED, HIGH);
  }
}```

Now the code works out like this:
Input password>> "Verified">> "Press button" prompt>> "Wrong password" message>> Scrolling text>> Button press>> "Wrong password" message>> press button>> next scroll screen>> press button>> "Wrong password" text>> >>> and so on.

I cant figure out why after I receive the press button prompt I get the Wrong password message, then the scrolling text screen. I think it might have some thing to do with the fact that 'D' has already been used here:

if (whichKey == '*' || whichKey == '#' || whichKey == 'A' || //define invalid keys
whichKey == 'B' || whichKey == 'C' || whichKey == 'D' || whichKey == '0') {

pozisyon = 0;
setLocked (true);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Codigo Invalido!");
delay(1000);
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("Introduzca");
lcd.setCursor(5, 1);
lcd.print("Codigo");
delay(500);


Why would the code be jumpingback and forth between the IF statements? Any ideas??

PD 
Im having trouble formatting my post, some things are read as code that are text and vice versa. My apologies in advance