Variable looses value

Hi Guys,

I am working on my first real project and one of the aspects is to enter a pin.
I have my hardware setup as per this image except mine is a 4x4 keypad :

The guide I followed for most of this is located here : https://www.brainy-bits.com/i2c-explained-i2c-keypad/

My program is working perfectly as expected. I can enter my pin and see it on the screen and all is correct.
However, when I push the button to “Accept” my pin, the full value of the pin is nullified.

Here is my code :

//--------------(c) Electronics project hub -----------//
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//#include <I2CKeyPad.h>
#include <Keypad_I2C.h>
#define lcd_addr 0x27     // I2C address of typical I2C LCD Backpack
#define keypad_addr 0x20  // I2C address of I2C Expander module (A0-A1-A2 dip switch to off position)

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(lcd_addr, 20, 4);
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] = {0, 1, 2, 3}; // connect to the row pinouts of the keypad
byte colPins[COLS] = {4, 5, 6, 7};    // connect to the column pinouts of the keypad
Keypad_I2C keyPad( makeKeymap(keys), rowPins, colPins, ROWS, COLS, keypad_addr, PCF8574 );
bool pin_correct = false; 
const String Pin = "1234";
String EnteredPin = "";
char key;
String KeyChar = "";

void setup()
{
  Serial.begin(9600);
  keyPad.begin();
  lcd.init();
  lcd.begin(20, 4);
  lcd.clear();
  lcd.setBacklight((uint8_t)1);
  lcd.setCursor(0, 0);
  lcd.print("    ELECTRONIC");
  lcd.setCursor(0, 1);
  lcd.print("    PIN TEST");

  delay(1500);
}

void loop()
{
  if (!pin_correct) //Trigger armed. Prompt for Pin
  {
    if (KeyChar = "")
    {
      lcd.setCursor(0, 3);
      lcd.print("ENTER PIN : ");
    }
    char key = keyPad.getKey();
    if (key != '\0')
    {
      if (key != 'A' && key != 'B' && key != 'C' && key != 'D' && key != '*' && key != '#')
      {
        lcd.setCursor(12, 3);
        EnteredPin += String(key);
        //lcd.print(key);
        KeyChar.concat(EnteredPin);
        lcd.print(KeyChar);
        Serial.println("Captured Pin = " + KeyChar);
      }
      else if (key == 'A')
      {
        Serial.println("Final Pin = " + KeyChar);
        Serial.println("Pin = " + Pin);
        if (KeyChar.equals(Pin))
        {
          pin_correct = true;
          lcd.setCursor(0, 3);
          lcd.print("     PIN CORRECT! ");
          KeyChar = "";
          EnteredPin = "";
          delay(2000);
          lcd.setCursor(0, 3);
          lcd.print("                    ");
        }
        else
        {
          pin_correct = false;
          lcd.setCursor(0, 3);
          KeyChar = "";
          EnteredPin = "";
          lcd.print("!!!!PIN INCORRECT!!!");
          delay(2000);
          lcd.setCursor(0, 3);
          lcd.print("                    ");
        }
      }
    }
  }
}
//--------------(c) Electronics project hub -----------//

And here is the output on my serial scanner :

Captured Pin = 1
Captured Pin = 12
Captured Pin = 123
Captured Pin = 1234
Final Pin =
Pin = 1234

that aligns with entering the numbers 1-4 and then pressing “A” to accept.
The Pin is printed on line 67 so it is going into that IF, but why would my variable “KeyChar” now be empty when it was storing the values correctly in another part of the if statement?

I feel my code is very simple and everything is working as expected, except this 1 small issue.
Please help me in finding the issue.

Thank you very much.

Thanks, that is a nicely detailed first post. One thing, can you please go back and change the "quote" tags around the code, to "code" tags? It's the normal thing around here.

Serial.println("Final Pin = " + KeyChar);
Serial.println("Pin = " + Pin);

Change to:

Serial.print("Final Pin = ");
Serial.println(KeyChar);
Serial.print("Pin = “);
Serial.println(Pin);

KeyChar is a String object. It will work. I'm not saying that it's good...

aarg:
Thanks, that is a nicely detailed first post. One thing, can you please go back and change the "quote" tags around the code, to "code" tags? It's the normal thing around here.

Thank you very much. Good point and fixed :slight_smile:

KeyChar is a String object. It will work. I'm not saying that it's good...

Sorry yes, that was a char at some point to try and see if that fixed the issue, but I was struggling with the syntax so I don't think it was a valid test.

Change to:
Serial.print("Final Pin = ".....);

I tried that but the result is the exact same :

Captured Pin = 1
Captured Pin = 12
Captured Pin = 123
Captured Pin = 1234
Final Pin =
Pin = 1234

Thank you very much for the imput.

In this line at the beginning:

    if (KeyChar = "")

I think you're resetting your string by using assignment (=) instead of comparison (==).

Note that if you fix that, I don't think you want to add your captured key to EnteredPin, then concat EnteredPin to KeyChar. If I'm understanding your intention, that error was concealing the problem with resetting KeyChar.

Professor_Chaos:
In this line at the beginning:

    if (KeyChar = "")

I think you're resetting your string by using assignment (=) instead of comparison (==).

Note that if you fix that, I don't think you want to add your captured key to EnteredPin, then concat EnteredPin to KeyChar. If I'm understanding your intention, that error was concealing the problem with resetting KeyChar.

Ahhh GENIUS. Thank you soo much.
That was my bug.
Well spotted :slight_smile:

You're welcome! I think we've all made that particular mistake....

You can turn compiler warnings to "more" in the IDE preferences, and it will give you a warning when you use an assignment in an if statement.