0

I am working on a school project, basically I have to create a lock system that opens a fictive gate when the correct code is entered. We have been asked to simulate our system before actually building it. So, I made the following circuit in Proteus(Labcenter Electronics' simulation software):

Here's what my system should do: A variable contains the correct code and the user must type a code on the keypad, and if it is correct, a green LED turns on and the LCD screen displays "Acces Granted!" if the code is wrong, the screen will display "Access refused!". It's a basic system, but I'm trying to make it as simple/short as possible(I have to explain it in an oral presentation, so the simpler the better) and for some reason, I can't get my code to work. Ideally, I'd like to have the LCD display a * for each character typed, liked on a real security system, but I haven't managed to do that either. I've been working on it for hours, trying different variants and etc.. but nothing seems to work the way I want to. BTW, my circuit works perfectly fine and the initialisation part of my code is therefore correct as well. Can anyone help me figure out what's wrong with my code and how I can make it better?

Here's my code so far:

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

//define LED pins
#define redLED 11
#define greenLED 10

String codeSerrure = "87362";   //correct code that opens the imaginative gate
String enteredCode = "";
int keyPressed;

const byte rows = 4;
const byte cols = 3;

char touches_digicode [rows] [cols] = {

  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins [rows] = {25, 26, 27, 28};
byte colPins [cols] = {24, 23, 22};

Keypad leDigicode = Keypad( makeKeymap(touches_digicode), rowPins, colPins, rows, cols);
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);


void setup(){
  lcd.begin(16, 2);
  pinMode(redLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
  digitalWrite(redLED, HIGH);
}

void loop(){
  lcd.setCursor(0,0);
  lcd.print(" Entrez le code");

  keyPressed = leDigicode.getKey();
  enteredCode += String(keyPressed);
  if(enteredCode.length() >= 5){
    if(enteredCode == codeSerrure){
      digitalWrite(greenLED, HIGH);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("  Acces autorise!");
      delay(4000);
      digitalWrite(greenLED, LOW);
      digitalWrite(redLED, HIGH);
      enteredCode = "";
    }
    else{
      digitalWrite(redLED, HIGH);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("  Acces refuse!");
      delay(4000);
      enteredCode = "";
    }
  }
  if(keyPressed == "#"){
    lcd.clear();
    enteredCode = "";
  }
}

The problem is that when I run this code in the simulation software, the LCD displays "Acces refuse!" and the red LED is on. No matter what keys I press (on the keypad) nothing happens. So the problem is that my code jumps straight to the else statement, inferring that the password typed is wrong (although no password was actually typed). I think the error is in here:

keyPressed = leDigicode.getKey();
  enteredCode += String(keyPressed);
  if(enteredCode.length() >= 5){
    if(enteredCode == codeSerrure){

Btw, forgive the french words, I am french. Also, I forgot to say, the # key should, clear the entered code. Any explanations, code samples or links would help.

  • 2
    Don't cross post. You already asked this on SO. – gre_gor Feb 27 '18 at 21:57
  • 1
    print enteredCode to serial right after this line ... enteredCode += String(keyPressed); – jsotola Feb 27 '18 at 22:09
  • Your code does not compile in the Arduino IDE (1.0.6.2). There is an issue with this line: if(keyPressed == "#"). If I replace the double quotes with single ones, it compiles. Are you sure the variable keyPressed should be an int? Perhaps it's suppose to be a char? – VE7JRO Feb 27 '18 at 22:17
  • @jsotola I will try that and report back, thank you! – Arxkz Feb 28 '18 at 10:53
  • @VE7JRO When I clicked the verify button in the Arduino IDE and it compiled fine for me. And I'm not sure which data type to use although char is probably better, because I have tried different ideas with both int and char and neither have worked. – Arxkz Feb 28 '18 at 10:56
1

The getKey() Funktion returns the define NO_KEY if no key was pressed, which is set in Keys.h as the NULL char (char with the value 0). In every loop cycle you are adding one character with value 0 to your string. But all functions, that handle strings, will stop, when they find a character with value 0 (it is the delimiter of C strings). Also a string with many NULL chars in it will not be matched to a string only consisting oft digits.

So you should check the return value of getKey for the NO_KEY define:

if(keyPressed != NO_KEY){
  enteredCode += String(keyPressed);
}

This avoids adding NULL chars to your string.

  • Yes, getKey() is not blocking which seems to be what the OP is assuming. – Nick Gammon Feb 28 '18 at 0:09
  • I hadn't thought of this. I will integrate it in my code and check for errors, thank you! – Arxkz Feb 28 '18 at 10:59
0

After reading all of your comments, I made some changes to my code and I was able to figure out a few other things that weren't working before. I think, because of the way I had coded my password checking function it made all the rest more complicated. I have also implemented the erase key feature, so a press of the * or # keys, erase the entered code. I still need to implement the feature that displays a * on the lcd each time the user presses a key, but I a not sure of what way to do this. Anyways, here's my working code if you're interested:

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

//define LED pins
#define redLED 11
#define greenLED 10

String codeSerrure = "87362";
String enteredCode = "";
char keyPressed;

const byte rows = 4;
const byte cols = 3;

char touches_digicode [rows] [cols] = {

  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins [rows] = {25, 26, 27, 28};
byte colPins [cols] = {24, 23, 22};

Keypad leDigicode = Keypad( makeKeymap(touches_digicode), rowPins, colPins, rows, cols);
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);


void setup(){
  lcd.begin(16, 2);
  pinMode(redLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
  digitalWrite(redLED, HIGH);
}

void loop(){
  lcd.setCursor(0,0);
  lcd.print(" Entrez le code");

  keyPressed = leDigicode.getKey();
  if(keyPressed != NO_KEY){
    if(keyPressed == 0x23 || keyPressed == 0x2A){
      lcd.clear();
      enteredCode = "";
    }
    else{
      enteredCode += String(keyPressed);
    }
  }

  if(enteredCode == codeSerrure){
      digitalWrite(greenLED, HIGH);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("  Acces autorise!");
      delay(4000);
      digitalWrite(greenLED, LOW);
      digitalWrite(redLED, HIGH);
      enteredCode = "";
      lcd.clear();
  }
  else if(enteredCode.length() >= 5){
      digitalWrite(redLED, HIGH);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("  Acces refuse!");
      delay(4000);
      enteredCode = "";
      lcd.clear();
  }
}

Thank you to everyone for the help (I'm a noobie)! I'm aware that my code is problably not the best way to do what I'm trying to do, so any suggestions and upgrades to the code you could give me are very welcome. Thanks again!

The final version of my code with all the features working can be found in this thread, for those interested.

  • For the * for every digit, you can use an integer variable, that gives you the position in the entered code (so if enteredCode is empty, pos = 0; if you enter a digit, you do pos++;) And directly after you added the new digit to your enteredCode string, you can use lcd.setCursor(1,pos);lcd.print("*"); to print your * to the LCD. Of course you have to set the position right for your LCD (I haven't looked for how many rows and columns you have in your display) – chrisl Mar 1 '18 at 15:02
  • And since your main question (why your code wasn't working) is now answered, you should mark one question as correct, either mine or yours, depending on what you think is better. – chrisl Mar 1 '18 at 15:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.