Password Library and Creating a Variable Integer

Hey, so I read up on arrays and found some rough example code in depths of the internet. I completely threw out the password library in favor of this new code. The problem I'm having now is that after the LCD prints Password is Good or Password is Bad it wont move onto the next screen. ex. I punch in 1234 I get password is good, the the screen flickers some (like its trying to move on, but the password is good is still true so it keeps on showing password is good ? maybe?) and that's it, it just gets stuck there.

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

int pressCnt = 0;

#define Password_Length 5
char Data[Password_Length];
char Master[Password_Length] = "1234";
byte data_count = 0, master_count = 0;
bool Pass_is_good;
char customKey;

enum MODES
{
  MAINMENUMODE,
  SECURITYMODE,
  SECURITYMODETWO,
  COOPMODES
};


const byte ROWS = 4;
const byte COLS = 4;
MODES mode = MAINMENUMODE;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
byte rowPins[ROWS] = {3, 5, 6, 7};
byte colPins[COLS] = {8, 9, 10};

Keypad myKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);

void setup() {
  lcd.begin(16, 2);
  MainMenu();
  Serial.begin(9600);
}

void loop() {
  char myKey = myKeypad.getKey();

  if (myKey == '#') {
    mode = SECURITYMODE;
    pressCnt = 0;
    SecurityScreen();
  }

  if (mode == SECURITYMODE && myKey == '*') {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("  Invalid Key  ");
    delay (2000);
    SecurityScreen();
  }
  else if (mode == MAINMENUMODE && myKey == '*')
  {
    MainMenu(); //Replace with coop Door function down the line
  }

  if (mode == SECURITYMODE) {
    if (myKey >= '0' && myKey <= '9') {
      Data[pressCnt] = myKey;
      lcd.setCursor(pressCnt, 1);
      lcd.print('*');
      pressCnt++;
    }
  }
  
if (pressCnt == Password_Length - 1) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Password is ");

    if (!strcmp(Data, Master)) {
      lcd.print("Good");    
      delay(1000);
      clearData();
      SecurityScreenTWO();
    }
    else {
    lcd.print("Bad");
    delay(1000);
    clearData();
    MainMenu();
    }
  }
}

void clearData() {
  while (data_count != 0)
  {
    Data[data_count--] = 0;
  }
  return;
}

void SecurityScreen() {
  mode = SECURITYMODE;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(" Enter Password");
}

void SecurityScreenTWO() {
  mode = SECURITYMODETWO;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(" ARM System?");
}
void MainMenu() {
  mode = MAINMENUMODE;
  lcd.setCursor(0, 0);
  lcd.print("* for Coop");
  lcd.setCursor(0, 1);
  lcd.print("# for Security");
}

I suspect that when you clear the data, you need to clear pressCnt as well. If you don't, each iteration of loop will see that if (pressCnt == Password_Length - 1) evaluates to true and goes through that block.

OMG thank you so much! This was driving me crazy! It works now!

So I've run into another problem. I'm trying to combine both my coop/radio code and the password/security system code and things are going weird. I can't move onto the next screen. From main menu I can't go anywhere! I tried getting rid of the "else if" stuff to see if that was a problem, but even then it only works if I'm supplying power through the USB and not through the barrel plug? And I can't input anything after I move onto the Enter Password Screen. Its almost like the Arduino doesn't recognize the keypad anymore... (the keypad works though, I verified it)

My Combo Code

#include <Wire.h>
#include <LiquidCrystal.h>
#include <Keypad.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>

#define Password_Length 5
int pressCnt = 0;
char Data[Password_Length];
char Master[Password_Length] = "1234";
byte data_count = 0, master_count = 0;
bool Pass_is_good;

unsigned long startMillis;
unsigned long currentMillis;
const unsigned long ScreenRefresh = 5000;

boolean RefreshDone = false;

boolean DoorIsOpen = false;
boolean DoorIsClosed = false;

enum MODES
{
  MAINMENUMODE,
  SECURITYMODE,
  SECURITYMODETWO,
  COOPMODE
};
MODES mode = MAINMENUMODE;

int msg[1];
RF24 radio(2, 4);
const uint64_t pipes[2] = {
  0xF0F0F0F000LL, 0xF0F0F0F0FFLL
};

const byte ROWS = 4;
const byte COLS = 4;


char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
byte rowPins[ROWS] = {3, 5, 6, 7};
byte colPins[COLS] = {8, 9, 10};

Keypad myKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);

void setup() {
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.setChannel(100);
  radio.setRetries(15, 15);
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1, pipes[1]);
  radio.setPALevel(RF24_PA_MAX);
  radio.startListening();

  startMillis = millis();
  mode = MAINMENUMODE;
  lcd.begin(16, 2);
  MainMenu();
  Serial.begin(9600);
}

void loop() {
  char myKey = myKeypad.getKey();

   if (mode == SECURITYMODE && myKey == '*') {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("  Invalid Key  ");
    delay (2000);
    SecurityScreen();
  }
  else if (mode == SECURITYMODETWO && myKey == '*'){
    ArmedScreen();
  }
  else if (mode == SECURITYMODETWO && myKey == '#'){
    DisarmScreen();
  }

//PASSWORD CODE
  if (myKey == '#' && mode == MAINMENUMODE) {
    mode = SECURITYMODE;
    pressCnt = 0;
    SecurityScreen();
  }

  if (mode == SECURITYMODE) {
    if (myKey >= '0' && myKey <= '9') {
      Data[pressCnt] = myKey;
      lcd.setCursor(pressCnt, 1);
      lcd.print('*');
      pressCnt++;
    }
  }
  if (pressCnt == Password_Length - 1) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Password Is ");

    if (!strcmp(Data, Master)) {
      lcd.print("Good");
      delay(1000);
      clearData();
      SecurityScreenTWO();
    }
    else {
      lcd.print("Bad");
      delay(1000);
      clearData();
      MainMenu();
    }
  }
  
// RADIO CODE
  if (radio.available()) {
    bool done = false;
    while (!done) {
      done = radio.read(msg, 1);

      if (msg[0] == 111) {
        DoorIsOpen = true;
        DoorIsClosed = false;
      }

        if (msg[0] == 112) {
        DoorIsClosed = true;
        DoorIsOpen = false;
      }
    }
  }

// COOP CODE  
  if (myKey == '*' && mode == MAINMENUMODE) {
    currentMillis = millis();
    mode = COOPMODE;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("The Coop Door Is");
    CoopDoorIs();
  }
if (mode == COOPMODE) {
    if (currentMillis - startMillis >= ScreenRefresh) {
      CoopDoorIs();
      startMillis = currentMillis;  //save the time that it was refreshed
      RefreshDone = true;
    }
  }
  if (RefreshDone == true) {
    ClearScreen();
    RefreshDone = false;
  }
}



void clearData() {
  while (data_count != 0){
    Data[data_count--] = 0;
  }
  pressCnt = 0;
  return;
}

void ClearScreen ()
{
  lcd.clear();
  MainMenu();
}

void MainMenu() {
  mode = MAINMENUMODE;
  lcd.setCursor(0, 0);
  lcd.print("* For Coop");
  lcd.setCursor(0, 1);
  lcd.print("# For Security");
}

void CoopDoorIs() {
  if (DoorIsOpen == true && DoorIsClosed == false) {
    lcd.setCursor(0, 1);
    lcd.print("Open");
  }
  else if (DoorIsClosed == true && DoorIsOpen == false    ) {
    lcd.setCursor(0, 1);
    lcd.print("Closed");
  }
}

void SecurityScreen() {
  mode = SECURITYMODE;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(" Enter Password");
}

void SecurityScreenTWO() {
  mode = SECURITYMODETWO;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("* To Arm");
  lcd.setCursor(0, 1);
  lcd.print("# To Disarm");
}

void ArmedScreen(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Security System");
  lcd.setCursor(0, 1);
  lcd.print("    Is ARMED    ");
}

void DisarmScreen (){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Security System Is");
  lcd.setCursor(0, 1);
  lcd.print("    Disarmed    ");
}

My Coop/Radio Code

#include <Password.h>
#include <Keypad.h>
#include <LiquidCrystal.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>

unsigned long startMillis;
unsigned long currentMillis;
const unsigned long ScreenRefresh = 5000;

boolean ScreenTwo = false;
boolean RefreshDone = false;

boolean DoorIsOpen = false;
boolean DoorIsClosed = false;

//Radio
int msg[1];
RF24 radio(2, 4);
const uint64_t pipes[2] = {
  0xF0F0F0F000LL, 0xF0F0F0F0FFLL
};

//LCD
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);

//Keypad
const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
byte rowPins[ROWS] = {3, 5, 6, 7};
byte colPins[COLS] = {8, 9, 10};

Keypad myKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() {
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.setChannel(100);
  radio.setRetries(15, 15);
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1, pipes[1]);
  radio.setPALevel(RF24_PA_MAX);
  radio.startListening();

  startMillis = millis();

  //Screen 1
  lcd.begin(16, 2);
  MainMenu();
  Serial.begin(9600);
}

void loop() {
  //Timing
  currentMillis = millis();

  //Keypad
  char myKey = myKeypad.getKey();


  //Radio Code
  if (radio.available()) {
    bool done = false;
    while (!done) {
      done = radio.read(msg, 1);

      if (msg[0] == 111) {
        DoorIsOpen = true;
        DoorIsClosed = false;
      }

        if (msg[0] == 112) {
        DoorIsClosed = true;
        DoorIsOpen = false;
      }
    }
  }

  // Screen 2
  if (myKey == '*' ) {
    currentMillis = millis();
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("The Coop Door Is");
    ScreenTwo = true;
    CoopDoorIs();
  }

  if (ScreenTwo == HIGH) {
    if (currentMillis - startMillis >= ScreenRefresh) {
      CoopDoorIs();
      startMillis = currentMillis;  //save the time that it was refreshed
      RefreshDone = true;
    }
  }

  if (RefreshDone == true) {
    ClearScreen();
    RefreshDone = false;
  }
}

void CoopDoorIs() {
  if (DoorIsOpen == true && DoorIsClosed == false) {
    lcd.setCursor(0, 1);
    lcd.print("Open");
  }
  else if (DoorIsClosed == true && DoorIsOpen == false    ) {
    lcd.setCursor(0, 1);
    lcd.print("Closed");
  }
}

void MainMenu () {
  lcd.setCursor(0, 0);
  lcd.print("* for Coop");
  lcd.setCursor(0, 1);
  lcd.print("# for Security");
}

void ClearScreen ()
{
  ScreenTwo = false;
  lcd.clear();
  MainMenu();
}

And My (almost final) Password/Security Code

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

int pressCnt = 0;

#define Password_Length 5
char Data[Password_Length];
char Master[Password_Length] = "1234";
byte data_count = 0, master_count = 0;
bool Pass_is_good;

enum MODES
{
  MAINMENUMODE,
  SECURITYMODE,
  SECURITYMODETWO,
  COOPMODES
};
const byte ROWS = 4;
const byte COLS = 4;
MODES mode = MAINMENUMODE;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
byte rowPins[ROWS] = {3, 5, 6, 7};
byte colPins[COLS] = {8, 9, 10};

Keypad myKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);

void setup() {
  lcd.begin(16, 2);
  MainMenu();
  Serial.begin(9600);
}

void loop() {
  char myKey = myKeypad.getKey();

  if (myKey == '#') {
    mode = SECURITYMODE;
    pressCnt = 0;
    SecurityScreen();
  }

  
   if (mode == SECURITYMODE && myKey == '*') {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("  Invalid Key  ");
    delay (2000);
    SecurityScreen();
  }
  else if (mode == SECURITYMODETWO && myKey == '*'){
    ArmedScreen();
  }
  else if (mode == SECURITYMODETWO && myKey == '#'){
    DisarmScreen();
  }
 

  if (mode == SECURITYMODE) {
    if (myKey >= '0' && myKey <= '9') {
      Data[pressCnt] = myKey;
      lcd.setCursor(pressCnt, 1);
      lcd.print('*');
      pressCnt++;
    }
  }
  
  if (pressCnt == Password_Length - 1) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Password Is ");

    if (!strcmp(Data, Master)) {
      lcd.print("Good");
      delay(1000);
      clearData();
      SecurityScreenTWO();
    }
    else {
      lcd.print("Bad");
      delay(1000);
      clearData();
      MainMenu();
    }
  }
}

void clearData() {
  while (data_count != 0)
  {
    Data[data_count--] = 0;
  }
  
pressCnt = 0;
  return;
}


void MainMenu() {
  mode = MAINMENUMODE;
  lcd.setCursor(0, 0);
  lcd.print("* for Coop");
  lcd.setCursor(0, 1);
  lcd.print("# for Security");
}

void SecurityScreen() {
  mode = SECURITYMODE;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(" Enter Password");
}

void SecurityScreenTWO() {
  mode = SECURITYMODETWO;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("* To Arm");
  lcd.setCursor(0, 1);
  lcd.print("# To Disarm");
}

void ArmedScreen(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Security System");
  lcd.setCursor(0, 1);
  lcd.print("    Is ARMED    ");
}

void DisarmScreen (){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Security System Is");
  lcd.setCursor(0, 1);
  lcd.print("    Disarmed    ");
}

radio.read() does not return anything; see http://tmrh20.github.io/RF24/classRF24.html#a8e2eacacfba96426c192066f04054c5b.

So the variable done will contain garbage (which can be either true or false) and your code might forever be stuck in the while (!done).

http://tmrh20.github.io/RF24/classRF24.html#a8e2eacacfba96426c192066f04054c5b.

Looking at this website, I'm not sure what to actually change in my code.

I saw this

void RF24::read( void* buf, uint8_t len ){ 
  // Fetch the payload
   read_payload( buf, len );
  //Clear the two possible interrupt flags with one command  
write_register(NRF_STATUS,_BV(RX_DR) | _BV(MAX_RT) | _BV(TX_DS) );
 }

But I don't know how to fix the variable done. The example code also used the variable data, but I don't know where to include it or what it means.

if(radio.available()){
  radio.read(&data,sizeof(data));
}

I also tried triggering the code by having '*' trigger all of my radio code and '#' trigger all the security code, but that didn't work at all! So I really don't know what to do! I honestly thought that combining these two sketches would be super easy! I also tried experimenting with the read_payload( buf, len );, but I couldn't make it change anything.

Maybe start with a full description of what your project needs to do; that radio was a new addition to the story. I have no experience with the nRF24 (did not get mine to work (yet)).

Oh Ok. So essentially I want to create a Hub that does 2 things check/display the state of my chicken coop's door via nrf and a security system that is protected by a password. I’m currently debating whether I should attach a pir sensor to the hub or use the nrf module to have a second transmitter trigger the alarm from somewhere else in the house to trigger the actual alarm. It all depends on if I can get this nrf stuff to work well in my combo code, since it did work just fine outside of the combo. Both sketches work fine by themselves, so I don’t understand why it just freezes up when I try to combine them. I mean the password code isn’t that taxing right? Should I maybe post this as another forum topic?

On my system (IDE 1.8.5), your combo code in reply #43 does not compile with the following error

C:\Users\sterretje\AppData\Local\Temp\arduino_modified_sketch_560605\sketch_may05a.ino: In function 'void loop()':

sketch_may05a:130: error: void value not ignored as it ought to be

       done = radio.read(msg, 1);

            ^

Same for the oter code in that reply. Maybe you're using a different compiler (IDE) or a different version of the library.

Why did you implement a while loop? There is no need for it unless your message is longer than one byte in which case you anyway have a bug in your code (your transmitter and receiver code don't match in that case).

Just take the done flag out; modified

  // RADIO CODE
  if (radio.available()) {
    radio.read(msg, 1);

    if (msg[0] == 111) {
      DoorIsOpen = true;
      DoorIsClosed = false;
    }

    if (msg[0] == 112) {
      DoorIsClosed = true;
      DoorIsOpen = false;
    }
  }

That simply checks if there is data available and if so, read one byte and process it. If more bytes were received, the next time that your code gets to the if, it sees that there is still data and will read it and process it. That should not pose an issue.

I can't say for sure why the one code works and the other one not.

Ok, I got rid of the while and now I can actually move into the coop screen. I am still locked out of the password screen though. I also don't have any compiling errors. I think we're using different libraries. Attached is the one I used and here's a link too.

RF24-master.zip (203 KB)

I think maniacbug is considered a little outdated. I checked against the library that I linked the documentation for. Will have to look at maniacbug to see what the read method returns.

Will try to look at your code a later to try to find obvious flaws.

Oh ok. So is the radio code still interfering with the password code? Because the radio/coop door stuff works fine, but the password stuff doesn't work at all. I can't even get to the enter password screen.

See Robin's reply in your other thread; pin 10 must be output for the Arduino to work as a SPI master.