One Wire Keypad - Writing & Read to/from EEPROM

Hi guys, first time posting so please be gentle....

if you can find the time i would like some help with a little project for my workshop........i have little C knowledge but i thought buy a starter kit would inflate my interest and it has - until now.

im stuck, i have a 3x4 matrix keypad and just to make it harder i wanted to use the OneWire method using an analog input which works fine - no issues there.

i can use the Password.h library and all is well. i have a larger sketch with RFID and OLED all with no problems - i have become stuck, when trying to use the EEPROM to store and read a password.

like i said i have little knowlege here but i assumed i would need to use a char array and perform some reads in the setup section?

i thought it would just be that but i seem to get nothing?

here is my basic code working fine with no EEPROM commands in it.

#include <Password.h>

Password password = Password("1234" );

byte currentLength = 0;
int threshold[16] = {528, 424, 265, 8, 549, 456, 313, 88, 570, 483, 354, 161, 588, 507, 391, 219};
char keypad[16] = {'1','2','3','A','4','5','6','B','7','8','9','C','*','0','#','D'};

void setup(){
  
 Serial.begin(9600);
 Serial.println("Reset with #");
 Serial.print("Enter Passcode: ");
 delay(1000);
 
}

void loop(){

int value = analogRead(A0);
  for (int x=0; x<16; x++){
  if (abs(value - threshold[x])<5){    
  char input =  keypad[x];
  
  switch (input){
     case '#': //Reset Password
        password.reset();
        currentLength = 0;
        Serial.println("Passcode Reset");
        delay(150);
    break;
    case '*': //New Passcode Input
        // Perform EEPROM read/write here.
        // Create new Void here NewPasscode();
    break;
        default: //Append any keypress that is not a '#' nor a '*'
        password.append(input);
        currentLength++;
        Serial.print("Enter Passcode: ");
   }
       
for (byte i=0; i<currentLength; i++){ // increase int as digits are pressed
        Serial.print('*');
        delay(150);
       }
        Serial.println();




  if (currentLength == 4){ //evaluate password when 4 digits have been pressed
    if (password.evaluate()){
    AccessGranted();
    }else{   
    AccessDenied();   
 }
 }
 
 if (currentLength >=4){ // Reset input/guess after 4 digits have been pressed
    password.reset();
    currentLength = 0;
    Serial.println("Passcode Reset");
}
}
}
}

void AccessGranted(){ // Code here to execute when password is correct.
    Serial.println("Access Granted");
    delay(3000);
    password.reset();
    currentLength = 0;
    Serial.print("Enter Passcode: ");
}

void AccessDenied(){ // Code here to execute when password is NOT correct.
    Serial.println("Access Denied");
    delay(3000);
    password.reset();
    currentLength = 0;
    Serial.print("Enter Passcode: ");
}

//NewPasscode(){ 
// here run the code to....
// 1. validate current passcode.
// 2. input new 4digit passcode.
// 3. buffer this input to confirm it to the next entry.
// 4. enter 4 digits again and compare this to the buffered 4 digits.
// 5. if both entries are equal - store last entry in EEPROM address 0+
// perform EEPROM read if required to update 'Passcode'

Clearly i am wrong to think that the below code should work as it doesnt >:(

#include <Password.h>
#include <EEPROM.h>

char Passcode[4];

Password password = Password(Passcode);

byte currentLength = 0;
int threshold[16] = {528, 424, 265, 8, 549, 456, 313, 88, 570, 483, 354, 161, 588, 507, 391, 219};
char keypad[16] = {'1','2','3','A','4','5','6','B','7','8','9','C','*','0','#','D'};

void setup(){
  
 Serial.begin(9600);
 Serial.println("Reset with #");
 Serial.print("Enter Passcode: ");
 delay(1000);

 Passcode[0] = EEPROM.read(0);
 Passcode[1] = EEPROM.read(1);
 Passcode[2] = EEPROM.read(2);
 Passcode[3] = EEPROM.read(3);
    
}

i know the EEPROM has 1,3,7,9 stored in the first addresses 0,1,2,3

i assumed that "Passcode[0] would then have '1' from EEPROM address 0 as so on....

then "Passcode [4]" would be the complete array (1379) but the password does accept.

Can anyone tell me where i am going wring with my thinking and point me in the right direction or throw some examples at me for pointers.

any help is greatly appreciated guys. :slight_smile:

i know the EEPROM has 1,3,7,9 stored in the first addresses 0,1,2,3

How do you know? None of your code shows displaying the content of the eeprom. Non of your code shows storing that data in eeprom.

Password password = Password(Passcode);

Will this work as expected before Passcode holds the actual password ?

When you read the four characters from EEPROM you are not creating a four character string but a four character array of chars. Make the array one character larger then terminate the array with a '\0' in position 4 and you will have a string

Note also that you can use the put() and get() methods to save and load a variable of any kind without the need to do it byte by byte

sterretje:
How do you know? None of your code shows displaying the content of the eeprom. Non of your code shows storing that data in eeprom.

Sorry sterretje, i was playing with writing and reading on a new sketch and managed to write to them no problem and read them back as individual bytes so i know the 1379 i wrote to them is there, i double checked before posting.

i am able to read them as bytes but the password.h library will only accept a char in the (password) field

UKHeliBob:

Password password = Password(Passcode);

When you read the four characters from EEPROM you are not creating a four character string but a four character array of chars. Make the array one character larger then terminate the array with a '\0' in position 4 and you will have a string

Thanks UKHeliBob, so something like

char Passcode[] = '0' '0' '0' '0' '\0'

i dont have IDE in front of me so i am not even sure if that would compile but like i said i am new to all this.

More like

char Passcode[5];

Then in setup()

 Passcode[0] = EEPROM.read(0);
 Passcode[1] = EEPROM.read(1);
 Passcode[2] = EEPROM.read(2);
 Passcode[3] = EEPROM.read(3);
 Passcode[4] = '\0';

or better use the get() method

EEPROM.get(0, Passcode);

The password library expects (a pointer to) a c-string. As UKHeliBob indicated, make the array one char bigger and filll the last position with a '\0'. The declaration in below already does that as does "1234" in your Password password = Password("1234");

To try yo show what goes on under the hood

char password[] = "1234";  // the array will be 5 bytes or UKHeliBob's fixed 5 byte array

void setup()
{
  Serial.begin(57600);

  Serial.print("strlen = "); Serial.println(strlen(password));  // will be 4
  Serial.print("sizeof = "); Serial.println(sizeof(password));  // will be 5

  for (uint8_t cnt = 0; cnt < sizeof(password); cnt++)
  {
    Serial.print("password["); Serial.print(cnt);
    Serial.print("] contains "); Serial.println(password[cnt], HEX);
  }
}

void loop()
{
}

Note that the code displays values in hex; consult e.g http://www.asciitable.com/ to see how they translate to characters.

UKHeliBob:
More like

or better use the get() method

[code]
EEPROM.get(0, Passcode);

One thing i forgot to mention - its i only have a NodeMCU with me (ESP8266) so i think the commands are read and write., i think get and put only work on Arduino boards.

So i had a little play and once again came up wanting guys.....

Using

#include <EEPROM.h>

// start reading from the first byte (address 0) of the EEPROM
int address = 0;
byte value;

void setup() {
  // initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  EEPROM.begin(512);
}

void loop() {
  // read a byte from the current address of the EEPROM
  value = EEPROM.read(address);

  Serial.print(address);
  Serial.print("\t");
  Serial.print(value, DEC);
  Serial.println();

  // advance to the next address of the EEPROM
  address = address + 1;

  // there are only 512 bytes of EEPROM, from 0 to 511, so if we're
  // on address 512, wrap around to address 0
  if (address == 512) {
    address = 0;
  }

  delay(500);
}

i am able to read the memory of the board

Address Content
0 1
1 2
2 3
4 4

so, when 1234 is appended to the password it should work? but alas nothing.

#include <Password.h>
#include <EEPROM.h>

char Passcode[5];

Password password = Password(Passcode);

byte currentLength = 0;
int threshold[16] = {528, 424, 265, 8, 549, 456, 313, 88, 570, 483, 354, 161, 588, 507, 391, 219};
char keypad[16] = {'1','2','3','A','4','5','6','B','7','8','9','C','*','0','#','D'};

void setup(){
  
 Serial.begin(9600);
 EEPROM.begin(32);
 Passcode[0] = EEPROM.read(0);
 Passcode[1] = EEPROM.read(1);
 Passcode[2] = EEPROM.read(2);
 Passcode[3] = EEPROM.read(3);
 Passcode[4] = '\0';
 
 Serial.println("Reset with #");
 Serial.print("Enter Passcode: ");
 delay(1000);
 
}

void loop(){

if i try to Serial.println(Passcode); i get gibberish is that normal? < here i was just trying to confirm that the EEPROM had been read and Passcode contained 1234.

Sorry to be a fud here guys, not sure where i am going wrong.

How are you saving the data to the EEPROM ?
Are you saving bytes such as as 1, 2, 3, 4
or chars such as '1', '2', '3', '4' ?

UKHeliBob:
How are you saving the data to the EEPROM ?
Are you saving bytes such as as 1, 2, 3, 4
or chars such as '1', '2', '3', '4' ?

Ah, this could be where i am going wrong.

i have just been using something like below to get figures into the EEPROM to then read them back using my program (Get the read part correct before moving on to the writing in my program i thought).

#include <EEPROM.h>

void setup() {
  EEPROM.begin(512);
}

void loop() {
  
//EEPROM.write(addr, val);
  EEPROM.write(0, 1);
  EEPROM.write(1, 2);
  EEPROM.write(2, 3);
  EEPROM.write(3, 4);
  EEPROM.commit();
  
  }

What do you think if i just change it to:

#include <EEPROM.h>

void setup() {
  EEPROM.begin(512);
}

void loop() {
  
//EEPROM.write(addr, val);
  EEPROM.write(0, '1');
  EEPROM.write(1, '2');
  EEPROM.write(2, '3');
  EEPROM.write(3, '4');
  EEPROM.commit();
  
  }

UKHeliBob:
How are you saving the data to the EEPROM ?
Are you saving bytes such as as 1, 2, 3, 4
or chars such as '1', '2', '3', '4' ?

UKHeliBob, i know we.ve only just met, but i love you :slight_smile: something so simple!

So thats the read all sorted and working well, ill come back to this post when i have problems with writing a new passcode but thanks again for your help & sterretje!