Problem about EEPROM.write(j, j+49);

Hi! I found this code from
https://circuitdigest.com/microcontroller-projects/digital-code-lock-using-arduino

And I’ve been working with my project where, the system give random password using random function, register it to eeprom, and compare the customkey from keypad . if right, led will light and if wrong led wil not;
I’ve been studying the code from the link above to help me doing my project but I just can’t understand what the “j+49” value is.

Here’s the code from above link.

#include <Keypad.h>
#include<LiquidCrystal.h>
#include<EEPROM.h>
#define buzzer 15
LiquidCrystal lcd(13,12,11,10,9,8);
char password[4];
char pass[4],pass1[4];
int i=0;

char customKey=0;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {4, 5, 6, 7}; //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
void setup()
{
  lcd.begin(16,2);
  
  pinMode(buzzer, OUTPUT);
  
  
  lcd.print("  Electronic ");
  lcd.setCursor(0,1);
  lcd.print("  Keypad Lock ");
  delay(2000);
  lcd.clear();
  lcd.print("Enter Ur Passkey:");
  lcd.setCursor(0,1);
  for(int j=0;j<4;j++)
  EEPROM.write(j, j+49);
  for(int j=0;j<4;j++)
  pass[j]=EEPROM.read(j);
}
  
void loop()
{
  customKey = customKeypad.getKey();
  if(customKey=='#')
  change();
  if (customKey)
  {
     password[i++]=customKey;
     lcd.print(customKey);
     beep();
  }
  if(i==4)
  {
    delay(200);
    for(int j=0;j<4;j++)
    pass[j]=EEPROM.read(j);
    if(!(strncmp(password, pass,4)))
    {
      
      beep();
      lcd.clear();
      lcd.print("Passkey Accepted");
      delay(2000);
      lcd.setCursor(0,1);
      lcd.print("#.Change Passkey");
      delay(2000);
      lcd.clear();
      lcd.print("Enter Passkey:");
      lcd.setCursor(0,1);
      i=0;
      
    }
    
    else
    {
      digitalWrite(buzzer, HIGH);
      lcd.clear();
      lcd.print("Access Denied...");
      lcd.setCursor(0,1);
      lcd.print("#.Change Passkey");
      delay(2000);
      lcd.clear();
      lcd.print("Enter Passkey:");
      lcd.setCursor(0,1);
      i=0;
      digitalWrite(buzzer, LOW);
    }
  }
}
void change()
{
  int j=0;
  lcd.clear();
  lcd.print("UR Current Passk");
  lcd.setCursor(0,1);
  while(j<4)
  {
    char key=customKeypad.getKey();
    if(key)
    {
      pass1[j++]=key;
      lcd.print(key);
      beep();
    }
    key=0;
  }
  delay(500);
  
  if((strncmp(pass1, pass, 4)))
  {
    lcd.clear();
    lcd.print("Wrong Passkey...");
    lcd.setCursor(0,1);
    lcd.print("Better Luck Again");
    delay(1000);
  }
  else
  {
    j=0;
    
  lcd.clear();
  lcd.print("Enter New Passk:");
  lcd.setCursor(0,1);
  while(j<4)
  {
    char key=customKeypad.getKey();
    if(key)
    {
      pass[j]=key;
      lcd.print(key);
      EEPROM.write(j,key);
      j++;
      beep();
    }
  }
  lcd.print("  Done......");
  delay(1000);
  }
  lcd.clear();
  lcd.print("Enter Ur Passk:");
  lcd.setCursor(0,1);
  customKey=0;
}
void beep()
{
  digitalWrite(buzzer, HIGH);
  delay(20);
  digitalWrite(buzzer, LOW);
}

So far here’s my code;

#include <Keypad.h>
#include<EEPROM.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char password[4];
int led = 13;
int passgen = 0;
char customkey = 0;
int i = 0;
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {4, 5, 6, 7}; //connect to the column pinouts of the keypad


//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup() {
Serial.begin(9600);
pinMode(led,OUTPUT);
}

void loop() {
  passgen = random(0000,9999);
  Serial.print(passgen);
  EEPROM.write(
  customkey = customKeypad.getKey();
  if(i==4)

{
}

j+48 would convert the numeric value of j into its character equivalent as long as the value of j is restricted to between 0 and 9. The characters are stored in the EEPROM. Using 49 instead ensures that zero is never written to the EEPROM which could could be important as zero flags the end of a C style string.

The method used is strange and I can see no reason for it.

UKHeliBob:
j+48 would convert the numeric value of j into its character equivalent as long as the value of j is restricted to between 0 and 9

Oh! okay okay, since his default password is “1234” that answer my question as to why the zero from “for(int j=0;j<4;j++)” is removed. Also password from keypad is read as char data type right? did he do this to convert int to char type?? (correct me if I’m wrong)

if so, can I use it for my code like

int passgen = 0;
void setup()
{
passgen = random(0000,9999);
EEPROM.write(passgen,j+48);}

to convert passgen from int to char?
do I need to individually generate random single digit number and use the “j+48”?

Thank you soo much for the info, it really helped a lot understanding the code

The values from the keypad will be chars. You can convert each of them to integers by subtracting 48 (or '0') if you have stored integers in the EEPROM or leave them as chars and store chars in the EEPROM, or store integers in the EEPROM and convert them to chars when comparing them. Choices, choices !

The important thing is to compare data of the same type.

UKHeliBob:
store integers in the EEPROM and convert them to chars

This is my choice, and I want to convert whatever four digit random numbers from

random(0000,9999);

to char and compare it twith keypad.

Will this code work if I do that?

int passgen = 0;
void setup()
{
passgen = random(0000,9999);
EEPROM.write(passgen,j+48);}

Thank you for the fast reply really appreciate it!!

passgen = random(0000,9999);
EEPROM.write(passgen,j+48);}

EEPROM.write writes a byte to a single EEPROM location so I don't know what your intended code is designed to do but I am sure that it won't do what you think.

EEPROM.put() writes data of any type to the EEPROM but you must get the parameters in the right order, address then the data to be written.

So, back to choices. You could generate a pseudo random passcode and EEPROM.put() the number in an EEPROM location to be read later using EEPROM.get(), When you have the user input you could convert it to a number (remember that user input will be 4 separate chars) to compare with what is in the EEPROM.

UKHeliBob:
(remember that user input will be 4 separate chars) to compare with what is in the EEPROM.

Mmm I have this vague idea on how to do it but I'm not really sure here's how it goes:

Since the keypad generate 4 separate chars, I could generate four separate single digit random number with different address,

BTW the idea of using this is to generate a one time use password, each time the password is correct it will generate another.

 int pass1 = 0;
int pass2 = 0;
int pass 3 = 0;
int pass 4 = 0;
void setup() // this should be void loop right???
{  pass1 = random(0,9);
   pass2 = random(0,9);
   pass3 = random(0,9);
   pass4 = random(0,9);
EEPROM.put(a,pass1);
EEPROM.put(b,pass2);
EEPROM.put(c,pass3);
EEPROM.put(d,pass4);}

then I can compare each to the keypad input

UKHeliBob:
When you have the user input you could convert it to a number

About this how do I convert the input char to integer??
I found this one from the forum while, reading on conversions
http://forum.arduino.cc/index.php?topic=438980.0

char test[] = "3689";

Serial.println(test[0] - '0');

can I use this code to convert the chars from user input in keypad and compare it to EEPROM.put()?

I'm really really REALLY thankful for helping me out!!

how do I convert the input char to integer??

Initialise theInt to zero then :

theInt = (theInt * 10) + (singleDigitFromKeypad - '0');

After 4 digits have been entered by the user theInt will contain an integer that you can compare with the integer from the EEPROM that you put there using EEPROM.put()

UKHeliBob:
theInt will contain an integer that you can compare with the integer from the EEPROM

Do I need to convert and compare them individually? or will theInt have all the four input keypad chars and I can directly compare it to my EEPROM.put()?

Do I need to convert and compare them individually?

No. After reading 4 characters the theInt will have the passcode number in it and it can be compared directly with the int from the EEPROM.

Okay thank you very for helping me, I'll try to write the whole code and may post again if I encounter problems or questions that I need to ask, again thanks!!

gorgonopsis:
About this how do I convert the input char to integer??

in your post you asked what does j+49 mean. it means j + 48 + 1 and that means j + '0' + 1
it's a conversion from int to char. and adding 1 to avoid zero.
so back from digit char to int it is ch - '0' or ch - 48.

48 is the ascii code of char '0' and chars for digits are next to it in natural order

48 '0'
49 '1'
50 '2'
51 '3'
52 '4'
53 '5'
54 '6'
55 '7'
56 '8'
57 '9'

Hi! it’s me again I did some coding but I just can’t figure it out on how to apply the char to int conversion.
I’m a little confused also, on where and what variable should I compare with my code,

This is how my system should work:

  1. generate a password
  2. input a number through keypad
    3)if the password is right print “password matched” in serial monitor
    4)if the password is wrong( do not print)

Here’s a rough sketch ( I can only generate random number with these)\

#include <Keypad.h>
#include<EEPROM.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
int led = 13;
char customkey = 0;
char password[4];
int i=0;
int theint = 0;
int x = 0;
int data;
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = {8, 7, 6, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 10, 11, 12}; //connect to the column pinouts of the keypad


//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup() {
Serial.begin(9600);
pinMode(led,OUTPUT);
}

void loop() {
  customkey = customKeypad.getKey();
  if(customkey=='#') //generate password when pressed 
 {generate();}
 if(customkey)
 password[i++]=customkey;
 Serial.print(customkey);
  // supposed to convert
 if (i==4)
 {theint = (theint * 10) + (password[i++] - '0'); //Supposed to convert char to int
  if(theint==data)
  {Serial.print("PASSWORD MATCHED");}}
 
}
  
  
  void generate()
  { 
x = random(1000,9999);
Serial.println(x);
EEPROM.put(3,x);

Serial.println("FROM EEPROM");
Serial.println(EEPROM.get(3,data));
  }

I’m still new to arduino so any form of help is greatly appreciated.
Thank you.

UKHeliBob:
j+48 would convert the numeric value of j into its character equivalent as long as the value of j is restricted to between 0 and 9. The characters are stored in the EEPROM. Using 49 instead ensures that zero is never written to the EEPROM which could could be important as zero flags the end of a C style string.

The method used is strange and I can see no reason for it.

This is why magic numbers suck.

It's much, much better to use the expression j + '0'. That makes it abundantly clear that you're getting a value offset from the ASCII 0 position.

  customkey = customKeypad.getKey();
  if (customkey == '#') //generate password when pressed

Personally I would check whether a key had been pressed before doing any more processing

  customkey = customKeypad.getKey();
  if (custom_key != NO_KEY)
   {
      //do stuff
   }
    theint = (theint * 10) + (password[i++] - '0'); //Supposed to convert char to int

Add to the int each time a character between '0' and '9' is received, not after all four have been received.
Suppose that you get '4', '2', '7' and '1'. When you subtract '0' from each you will have 4, 2, 7, and 1 so the calculation will go like this with theInt initialised to zero

Got '4'
theInt = (10 * theInt) + 4 equals 4

Then '2'
theInt = (10 * theInt) + 2 equals 42

Then '7'
theInt = (10 * theInt) + 7 equals 427

Finally '1'
theInt = (10 * theInt) + 1 equals 4271

UKHeliBob:
Add to the int each time a character between ‘0’ and ‘9’ is received, not after all four have been received.
Suppose that you get ‘4’, ‘2’, ‘7’ and ‘1’. When you subtract ‘0’ from each you will have 4, 2, 7, and 1 so the calculation will go like this with theInt initialised to zero

Got ‘4’
theInt = (10 * theInt) + 4 equals 4

Then ‘2’
theInt = (10 * theInt) + 2 equals 42

Then ‘7’
theInt = (10 * theInt) + 7 equals 427

Finally ‘1’
theInt = (10 * theInt) + 1 equals 4271

Thank you for replying and helping me this far, pardon me for asking too many questions.

Alright I did this code

#include <Keypad.h>
#include<EEPROM.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
int led = 13;
char customkey = 0;
char password[5];
int i=0;

int x = 0;
int data;
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = {8, 7, 6, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 10, 11, 12}; //connect to the column pinouts of the keypad


//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup() {
Serial.begin(9600);
pinMode(led,OUTPUT);
randomSeed(analogRead(A0));
}

void loop()
{
  customkey = customKeypad.getKey();
 
  if (customkey != NO_KEY)
   {
    if(customkey=='#') 
 { 
  generate(); //generate code
  }
      
   }
  
 if(customkey)
{
  password[i++]=customkey;
  int theint = 0;

theint = (10* theint + password[1] - '0');
theint = (10* theint + password[2] - '0');
theint = (10* theint + password[3] - '0');// convert char from keypad to int
theint = (10* theint + password[4] - '0');// I'm stuck with theint value when I press another button

 Serial.println(theint);
 
 
  if(theint==data) //print if condition is met
  {
    digitalWrite(led,HIGH);
    Serial.print("PASSWORD MATCHED");
    delay(400);
    digitalWrite(led,LOW);}
   }
   }
  
 
  
  void generate() //generatecode
  { 
x = random(1111,9999);
Serial.println(x);
EEPROM.put(3,x);

Serial.println("FROM EEPROM");
Serial.println(EEPROM.get(3,data));
  }

It can generate and match the code inside EEPROM, tho it needed to be right the first time
Now my problem once I reached four input, the value of the next ended up to stuck ,
each time I press another button the value is already equivalent to theint.
Should I use a loop statement here?? so if the user input a wrong password he/she can try again.
any advice what function should I use??

Again, THANK YOU so much for helping me.

once I reached four input, the value of the next ended up to stuck

After testing for a match set theInt and i back to zero ready for the next input.

There is something wrong with how you save the input to the array and use it later. The variable i starts with a value of zero so when you first do

   password[i++] = customkey;

you are writing to password[0] but later you get the first character like this

   theint = (10 * theint + password[1] - '0');

when you should get it from password[0]

UKHeliBob:
. The variable i starts with a value of zero so when you first do

   password[i++] = customkey;

you are writing to password[0] but later you get the first character like this

   theint = (10 * theint + password[1] - '0');

when you should get it from password[0]

mmmm i did that because when “#” is pressed it counts as password[0]
I did reset the array password by subtracting
here’s my code now

#include <Keypad.h>
#include<EEPROM.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
int led = 13;
char customkey = 0;
char password[5];
int i=0;

int x = 0;
int data;
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = {8, 7, 6, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 10, 11, 12}; //connect to the column pinouts of the keypad


//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup() {
Serial.begin(9600);
pinMode(led,OUTPUT);
randomSeed(analogRead(A0));
Serial.println("WELCOME TO PPCS");}

void loop()
{
  customkey = customKeypad.getKey();
 
  if (customkey != NO_KEY)
   {
    if(customkey=='#') 
 { digitalWrite(led,HIGH);
  generate(); //generate code
  }
      
   }
  
 if(customkey)
{
  password[i++]=customkey;
  int theint = 0;

theint = (10* theint + password[1] - '0');
theint = (10* theint + password[2] - '0');
theint = (10* theint + password[3] - '0');
theint = (10* theint + password[4] - '0');// convert char from keypad to int
if(i==5)
{i=(i-4);
Serial.println("WRONG PASSWORD");}
Serial.println(customkey);
 
 
 
  if(theint==data) //print if condition is met
  {
    digitalWrite(led,HIGH);
    Serial.print("PASSWORD MATCHED");
    delay(400);
    digitalWrite(led,LOW);
    }
    
   }
   }
  
 
  
  void generate() //generatecode
  { 
x = random(1111,9999);
Serial.println(x);
EEPROM.put(3,x);

Serial.println("FROM EEPROM");
Serial.println(EEPROM.get(3,data));
  }

What ydo you think???
Now all I need is to disable other button when I first ran my program except “#”
and each time the password is correct my system should reset

Thank you.