-1

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): Keypad circuit

Sorry, I can't post images.

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 aswell. 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, infering 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 explainations, code samples or links would help. Thank you!

Arxkz
  • 1
  • 3
  • 1
    "Something is wrong below" -> give more details please. – nyr1o Feb 27 '18 at 21:19
  • Added clarifications. – Arxkz Feb 27 '18 at 21:40
  • Just a question about your code, why is keyPressed an int and then you are comparing it with String ?! I think you should compare it with char. (like this '#') – TheEngineer Feb 27 '18 at 22:13
  • 1
    Also posted at https://arduino.stackexchange.com/q/50284 – per1234 Feb 27 '18 at 23:03
  • @TheEngineer I might be mistaken (probably), but I thought that String(keyPressed) would convert it from an integer to a string. Either way, using a char is probably a better idea indeed. – Arxkz Feb 28 '18 at 11:02
  • @per1234 Sorry, I'm new here. Should I remove it? – Arxkz Feb 28 '18 at 11:03
  • I don't know of a specific rule against cross posting but there are certainly a lot of users who don't think it's a good idea: https://meta.stackexchange.com/q/64068. I'll just say that if you are going to do it then you need to add links from each cross post to the other. – per1234 Feb 28 '18 at 13:35

2 Answers2

0

The method getKey() returns a char; so it ALWAYS returns a char ! For instance if no key has been pressed, it returns NO_KEY (= '\0').

The way you wrote your code, you quickly fill enteredCode string with "\0\0\0\0\0". Change your code with:

keyPressed = leDigicode.getKey();
if (keyPressed)   {
    enteredCode += String(keyPressed);
    // following is for debug
    // lcd.print(keyPressed);   delay(300);
}
if(enteredCode.length() >= 5) {   ...  
Arno Bozo
  • 454
  • 3
  • 8
  • I will try this and see if it fixed my issue, thanks! I wasn't aware of the fact that NO_KEY was infact a 0 char. – Arxkz Feb 28 '18 at 11:05
  • I found the "instruction" `if (keyPressed) {}` in the library example HelloKeypad.ino – Arno Bozo Feb 28 '18 at 13:47
0

Thanks to all you guys' help I finally managed to code all the features I wanted with no glitches and the code is much cleaner. I'm aware that my code is not perfect and can probably be improved, so if anyone still interested, any modification ideas are welcome. Anyway, here's my final code for those interested:

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

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

int contrast = 25;
String codeSerrure = "87362";
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);

byte e_aigu[8] = {
  B00010,
  B01100,
  B00000,
  B01110,
  B10001,
  B11111,
  B10000,
  B01110
};
byte e_grave[8] = {
  B01000,
  B00110,
  B00000,
  B01110,
  B10001,
  B11111,
  B10000,
  B01110
};

void setup(){
  analogWrite(8, contrast);
  lcd.createChar(0, e_aigu);
  lcd.createChar(1, e_grave);
  lcd.begin(16, 2);
  pinMode(redLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
  digitalWrite(redLED, HIGH);
}

void loop(){
  String enteredCode = "";
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" Entrez le code:");

  while(enteredCode.length() < 5){
    keyPressed = leDigicode.getKey();
    if(keyPressed){
      if(keyPressed == 0x23 || keyPressed == 0x2A){
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(" Entrez le code:");
        enteredCode = "";
      }
      else
      {
        enteredCode += keyPressed;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(" Entrez le code:");
        lcd.setCursor(5, 1);
        for(int i=0; i < enteredCode.length(); i++){
          lcd.print("*");
        }
      }
    }
  }

  delay(390);

  if(enteredCode == codeSerrure){
    digitalWrite(redLED, LOW);
    digitalWrite(greenLED, HIGH);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(" Acc");
    lcd.write((uint8_t)1);
    lcd.print("s autoris");
    lcd.write((uint8_t)0);
    lcd.print("!");
    delay(4000);
    digitalWrite(greenLED, LOW);
    digitalWrite(redLED, HIGH);
  }
  else
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("  Acc");
    lcd.write((uint8_t)1);
    lcd.print("s refus");
    lcd.write((uint8_t)0);
    lcd.print("!");
    delay(4000);
  }
}

As you can see I changed many things. I rewrote the password check function with a while loop and integrated a function that displays a * on the LCD each time a key is pressed. I have also added the erase function for the * and # keys. And since my LCD doesn't support characters such as é and è (I needed them for french words, why do we have to make everything more complicated), I created my own. I also made a small modification to my circuit, I removed the potentiometer and assigned the contrast value of the LCD in my code instead. Here's the finished schematics:

Can't post pictures yet

Thanks to everyone who helped me!

Arxkz
  • 1
  • 3