No wonder you need goto statements. You have a while-loop based on a variable that never changes.
To demonstrate how to use a struct
// max length of user code; 4 digits plus terminating nul character
#define CODE_LENGTH 5
// max length of password; 9 digits plus terminating nul character
#define PASSWORD_LENGTH 10
struct USER
{
char code[CODE_LENGTH];
char password[PASSWORD_LENGTH];
};
// variable to hold user code and password
USER user;
A struct combines related information. E.g. entries in a phone book with a name and a phone number; in this case a code and a password.
I suggest that you store the user information in eeprom; that way updated information will be remembered. The below code will put 10 user records in eeprom.
#include <EEPROM.h>
// generic macro to determine number of elements in array
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))
// macro to determine the largest of two numbers
#define MAX(x,y) ((x>y)?x:y)
// max length of user code; 4 digits plus terminating nul character
#define CODE_LENGTH 5
// max length of password; 9 digits plus terminating nul character
#define PASSWORD_LENGTH 10
// max number of users
#define MAXUSERS 10
struct USER
{
char code[CODE_LENGTH];
char password[PASSWORD_LENGTH];
};
// variable to hold user code and password
USER user;
void setup()
{
Serial.begin(57600);
// default password for all users
strcpy(user.password, "1234");
for (byte userCnt = 0; userCnt < MAXUSERS; userCnt++)
{
// assign a random user code
itoa(random(1000), user.code, 10);
// create a user record in eeprom
createUser(userCnt);
//delay(100);
}
}
void loop()
{
}
/*
create a user record in eeprom; uses global user variable
*/
void createUser(byte number)
{
EEPROM.put(number * sizeof(USER), user);
}
The only weak point is that it can create duplicate codes; I leave that up to you to fix if needed. If you can't fix it, use userCnt instead of random().
The next code displays all user records in the eeprom
#include <EEPROM.h>
// generic macro to determine number of elements in array
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))
// macro to determine the largest of two numbers
#define MAX(x,y) ((x>y)?x:y)
// max length of user code; 4 digits plus terminating nul character
#define CODE_LENGTH 5
// max length of password; 9 digits plus terminating nul character
#define PASSWORD_LENGTH 10
// max number of users
#define MAXUSERS 10
struct USER
{
char code[CODE_LENGTH];
char password[PASSWORD_LENGTH];
};
// variable to hold user code and password
USER user;
void setup()
{
Serial.begin(57600);
for (byte userCnt = 0; userCnt < MAXUSERS; userCnt++)
{
EEPROM.get(userCnt * sizeof(USER), user);
Serial.print("user: "); Serial.println(userCnt + 1);
Serial.print("Code: "); Serial.println(user.code);
Serial.print("Pass: "); Serial.println(user.password);
Serial.println();
}
}
void loop()
{
}
In a for-loop, it reads each user record and displays it.
The below function allows you to find a record in eeprom for a given user code
/*
find a user by user code
In:
user code
Return:
0xFF if not found, else index in array in eeprom
*/
byte findUser(char *code)
{
byte index = 0xFF;
USER u;
for (byte userCnt = 0; userCnt < MAXUSERS; userCnt++)
{
// read eeprom record
EEPROM.get(userCnt * sizeof(USER), u);
// if user code matches
if (strcmp(u.code, code) == 0)
{
// remember index
index = userCnt;
// copy to global user variable
memcpy(&user, &u, sizeof(USER));
}
}
// if not found
if (index == 0xFF)
{
// clear global user variable
memset(&user, 0, sizeof(USER));
}
return index;
}
And can be used like this
#include <EEPROM.h>
// generic macro to determine number of elements in array
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))
// macro to determine the largest of two numbers
#define MAX(x,y) ((x>y)?x:y)
// max length of user code; 4 digits plus terminating nul character
#define CODE_LENGTH 5
// max length of password; 9 digits plus terminating nul character
#define PASSWORD_LENGTH 10
// max number of users
#define MAXUSERS 10
struct USER
{
char code[CODE_LENGTH];
char password[PASSWORD_LENGTH];
};
// variable to hold user code and password
USER user;
void setup()
{
Serial.begin(57600);
// find user with code 878
byte idx = findUser("878");
if (idx == 0xFF)
{
Serial.println("user not found");
}
else
{
Serial.println("user found");
Serial.print("user: "); Serial.println(idx + 1);
Serial.print("Code: "); Serial.println(user.code);
Serial.print("Pass: "); Serial.println(user.password);
Serial.println();
}
}
You can not store String (capital S) directly in eeprom; use of String (capital S) is anyway discouraged. The codes shown above use so-called c-strings (character arrays terminated with '\0');
I strongly suggest that you write a function to read a c-string from keypad that can be used for both the code and the password.