LCD code for display numbers

Hello,

I want to display the typed in numbers of the keypad on the LCD. For example: if I press 1234 on the keypad, the display says 1234. Could someone help me with the code?
Everything else works fine.

The plan
Locksystem with passwordcode. If the door is closed (Red led), door open is (green led) The servo will be the lock.

The code

// How to Make an Arduino Keypad Lock
// Jlaservideo.com

#include <Servo.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

Servo ServoMotor;
char* password = "158";  // change the password here, just pick any 3 numbers
int position = 0;
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' }
};

byte rowPins[ROWS] = { 8, 7, 6, 9 };
byte colPins[COLS] = { 5, 4, 3, 2 };
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
int RedpinLock = 12;
int GreenpinUnlock = 13;

void setup() {
  pinMode(RedpinLock, OUTPUT);
  pinMode(GreenpinUnlock, OUTPUT);
  ServoMotor.attach(11);
  LockedPosition(true);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Escaperoom");
  lcd.setCursor(0, 1);
  lcd.print("Stefan");
  delay(5000);
  lcd.clear();
}

void loop() {
  char key = keypad.getKey();
  if (key == '*' || key == '#') {
    position = 0;
    LockedPosition(true);
  }
  if (key == password[position])

  {
    position++;
  }
  if (position == 3) {
    LockedPosition(false);
  }
  delay(100);
}
void LockedPosition(int locked) {
  if (locked) {
    digitalWrite(RedpinLock, HIGH);
    digitalWrite(GreenpinUnlock, LOW);
    ServoMotor.write(0);
  } else {
    digitalWrite(RedpinLock, LOW);
    digitalWrite(GreenpinUnlock, HIGH);
    ServoMotor.write(90);
  }
}

  • append the key to the current value and simply do an lcd.print() of that value as keys are pressed
    value = 10*value + key;
  • check the value only after the '*' or '#' are pressed and reset the value

seems wrong to check the code after each keypress, implies a fixed # of digits

  if (key == password[position])
  {
    lcd.print(key);  // Add this line
    position++;
  }

there is a nice keypad tutorial:

furthermore nowadays no PIN is shown on a display. Just print * as feedback to the user, that a digit was entered.

@gcjr How do I embed this in my code? Do you have an example, where to put it?

@johnwasser I did a test. Only the right awnser numbers appears, in this case 158. The rest isnt working.

noiasca Thnx for the link! Still trying to fix it. In this case, is isnt a problem that the code is on the display.

OK. Try this:

  if (key >= '0' && key <= '9') // Add these two lines
    lcd.print(key);  // Add these two lines

  if (key == password[position])
  {
    position++;
  }

i didn't realize you were operating on a char array

consider

char input [20];

void loop() {
    char key = keypad.getKey();
    if (! key)
        return;

    Serial.println (key);

    if (key == '*' || key == '#') {
        input [position++] = '\0';      // terminate string w/ Null
        if (! strcmp (input, password))  {
            LockedPosition (false);
            delay (3000);
            LockedPosition (true);
        }
        else  {
            Serial.print   ("wrong: ");
            Serial.println (input);
        }
        position = 0;
    }
    else
        input [position++] = key;
}

@johnwasser Yes this works
@gcjr The code was giving me errors

Just found out that if you typ 12345678 the lock will unlock , back to the drawing board

The original example code is a bad implementation of how to handle a PIN, and adding the printing of the key when a digit position is correct makes it even worse.

As a bad actor I would love this implementation since I can easily "guess" the code by just pressing all the keys.
i.e. simply pressing 1 through 9 three times is guaranteed to unlock the device.
It could be less depending on the PIN.
This is because there is no reset / penalty for guessing an incorrect button.

Adding the printing of the key on the LCD when correct makes it even worse.
Since as you "guess" each position correctly along the way the key will show up until you have fully guessed the code.

The logic for handling this must be different and more extensive.

My garage keypad uses # as an ending to indicate that the PIN has been entered.
i.e. you press the buttons for the PIN code and press # when done.
It looks as the previous 4 buttons pressed before the # to see what PIN you typed in.
i.e. you could type a million buttons/digits and nothing will happen, but when you press the # it uses the last 4 button presses for the PIN.

But if using a fixed number of digits you also could also just check the PIN on the Nth digit entered.

I would also not hard code the PIN in software as that makes it hard to change.
I would store it in EEPROM.
i.e. you could have a "factory default" in code but the user can override it with their own pin stored in EEPROM.

You can use the LCD backlight as feedback.

IMO, this project like all software should be designed up front before any coding starts.

You need to figure out how you want it to work - FIRST.
i.e. define how you want it work.
This requires no coding ability, no coding skills, or any software or hardware since it just defining the high level functionality of how it should work.
i.e. just brain work and writing things down at this point.

Then think of the logic to make that happen - still no coding skills h/w or s/w needed.
Work through all the scenarios like what happens when each button is pressed and what happens when the incorrect buttons are pressed.
What type of user feedback to provide on the LCD.
Then and only then, attempt to start writing the code to implement it.
This includes figuring out things like how the user interface works,
i.e. how to enter the PIN, how to provide feedback on the LCD, and if desired, how to change the PIN.

There are many things you must decide.
The main things being how secure you want this to be and how configurable you want/need it to be, and user feedback when entering things.

  • how many digits? Is it fixed or can it vary like be 3 or 4 digits or more?
    Keeping it a fixed number like 4 is easier to implement.

  • How to terminate entering the PIN?
    It could be automatic if the number of digits is fixed.
    i.e. after entering the Nth digit, it checks it.
    if the PIN is correct it does what it needs to do, or starts over with the 1st digit.
    This option is fairly easy to implement. Que up the buttons and automatically check all of them once the proper number has been entered.
    Or treat the PIN as an actual integer number and create the number as the user types in the digits.
    Or it could require telling it you have entered the PIN by doing something like pressing a key like #. But then you must figure out how to handle things when they type more than the number of buttons. i.e. does it start over or does it rotate through the PIN positions queued up or does it shift the PIN buttons in the que to allow using the most recent N buttons.
    And what type of user feedback if any when they have exceeded the total number of expected PIN digits.

  • LCD backlight control.
    With an i2c LCD you can also can control the backlight.
    You could have a timeout that turns off the backlight to preserve the life of the backlight save power that triggers after a certain amount of time with no button pressed.

  • User feedback
    Lots of options here.
    You need to figure out how you want to use the display.
    Perhaps you print '*' for each button press.
    If using backlight control you can use that for feedback as well.
    How to provide feedback if any for correct or incorrect button presses.
    The most secure is only provide feedback when something is pressed but no feedback when a button is correct or incorrect for the PIN until entering the final PIN position.

  • how / when to lock back.
    i.e. should it lock back based on some amount of time, or does the user have to do something to lock.
    If the user has to do something to lock it, should the user enter the unlock PIN when doing the lock sequence?
    On some safes you enter the open/unlock PIN each time you lock the safe.
    This is a fairly simple way to have a user configurable PIN that is built in by design.
    While this is good for some use cases like a safe, it may not work well for other use cases.

  • Should the PIN be changeable from the keypad?
    This depends how the PIN works since if a PIN is entered to lock the device, it becomes changeable by design.
    If it is fixed pin that can be modified, then there would need to be a sequence to enter the existing pin to allow changing the pin. And then there must be a way to set the PIN back the "factory default" that is hard coded in the source code.
    like pressing some combination of * or # to enter a PIN change mode.

I would suggesting spending some time thinking about how you want your system to work and then when you have a design, come back to code implementation.

--- bill

Here is an example Keypad combination lock I wrote a while back. Perhaps it will be of use.

#include <Keypad.h>

// Combination is "08675309"
// Use any value up to 4 billion

// NOTE: '08675309ul' is not a valid integer literal 
// and will not compile.  The leading zero means 
// 'octal literal' and the digits 8 and 9 are not 
// valid octal digits.
//
// To get leading zeroes, set CombinationLength
// higher than the number of digits

const unsigned long Combination = 8675309ul;
const byte CombinationLength = 8;

const byte ROWS = 4; // set four rows
const byte COLS = 4; // set four columns
const char keys[ROWS][COLS] =   // Define the keymap
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[ROWS] = { 36, 34, 32, 30 };
byte colPins[COLS] = { 28, 26, 24, 22 };
// Create the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );

unsigned long InputValue = 0;
byte InputLength = 0;

void setup()
{
  Serial.begin(115200);
  pinMode(46, OUTPUT); // Set green LED as output
  pinMode(48, OUTPUT); // Set red LED as output
}

void loop()
{
  char key = keypad.getKey();

  switch (key)
  {
    case '*':  // Clear
      InputValue = 0;
      InputLength = 0;
      break;

    case '0'...'9':
      InputValue *= 10;
      InputLength++;
      InputValue += key - '0';
      break;

    case '#': // Enter
      if (InputLength == CombinationLength && InputValue == Combination)
      {
        Serial.println("Success, Come inside"); // If the password is correct
        digitalWrite(46, HIGH); // Turn on green LED
        delay(500); // Wait 5 seconds
        digitalWrite(46, LOW); // Turn off green LED
      }
      else
      {
        Serial.println("Access Denied"); // If the password is incorrect
        digitalWrite(48, HIGH); // Turn on red LED
        delay(500); // Wait 5 seconds
        digitalWrite(48, LOW); // Turn off red LED
      }
      InputValue = 0;
      InputLength = 0;
      break;

  }  // switch(key)
}  // loop()

not for me

1
2
3
4
5
6
7
8
*
wrong: 12345678
1
5
8
*
servo write: 11 90
servo write: 11 0
1
5
8
2
3
4
*
wrong: 158234

First of all, thanks for the fast responds.
Got it working, with different codes

Topic can be closed

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.