Character Array Crashing Arduino?

Hi all, I have an Arduino Uno and i'm making a basic project whereby the user uses a keypad to enter the current year, if the current year is correct it will fire a relay. For some reason this code will upload fine but the arduino wont do anything once uploaded. If I leave out the array and just use a static password (Password password = Password ("1234") :wink: it works fine.

This is the code:

#include <Password.h>
#include <Keypad.h>
#include <Wire.h>
#include "RTClib.h"


RTC_DS1307 RTC;
DateTime now = RTC.now();
char passyear[5] = {now.year()};
Password password = Password (passyear) ;



const byte ROWS = 4; // Four rows
const byte COLS = 4; //  columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 7, 6, 5, 4 };// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 12, 11, 10, 8 };


// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

#define relay 3
#define speakerPin 13


void setup(){
  Wire.begin();
    RTC.begin();
    
 
    
     pinMode (3, OUTPUT);
  pinMode (13, OUTPUT);
  Serial.begin(9600);
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
  


}

void loop()

  


{
  keypad.getKey();
  
}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  Serial.print("Pressed: ");
  Serial.println(eKey);
  switch (eKey){
    case '*': guessPassword(); break;
    case '#': password.reset();  break;
     default:
	     password.append(eKey);
  }
}

void guessPassword(){
     Serial.print("Guessing password... ");
     if (password.evaluate()){
	      digitalWrite(speakerPin,HIGH);
              digitalWrite(relay,HIGH);
              delay (2000);
              digitalWrite(relay,LOW);
	     Serial.print("Correct");
     }else{
	     Serial.print("false");
     }
}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

DateTime now = RTC.now();
char passyear[5] = {now.year()};
Password password = Password (passyear) ;

Two problems with that snippet...

  1. If RTC relies on any hardware, the hardware is unlikely to be initialized at the point where RTC.now() and now.year() are called. That code needs to be moved into setup.

  2. I promise that char passyear[5] = {now.year()}; does not do what you expect it to do. now.year() returns an integer value that is converted to a char which becomes the first character of the array. You need to convert the integer value to a string. The itoa function should be exactly what you need.

Yes, RTC Depends on external hardware. I have replaced the code block at the top with this:

RTC_DS1307 RTC;
DateTime now = RTC.now();
char passyear[5];
itoa( now.year(), passyear, 10);
Password password = Password (passyear) ;

I Then get this error:
sketch_jun16a:9: error: expected constructor, destructor, or type conversion before '(' token

I Suspect it's coming from the location of the code, yet If i move this into void_setup

sketch_jun16a.cpp: In function 'void keypadEvent(KeypadEvent)':
sketch_jun16a:67: error: 'password' was not declared in this scope
sketch_jun16a.cpp: In function 'void guessPassword()':
sketch_jun16a:75: error: 'password' was not declared in this scope
sketch_jun16a:82: error: 'passyear' was not declared in this scope

This is the current code:

#include <Password.h>
#include <Keypad.h>
#include <Wire.h>
#include "RTClib.h"





const byte ROWS = 4; // Four rows
const byte COLS = 4; //  columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 7, 6, 5, 4 };// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 12, 11, 10, 8 };


// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

#define relay 3
#define speakerPin 13


void setup(){
  RTC_DS1307 RTC;
  Wire.begin();
    RTC.begin();
    

 DateTime now = RTC.now(); 
  char passyear[5];
itoa( now.year(), passyear, 10);
  Password password = Password (passyear) ;  

 
     pinMode (3, OUTPUT);
  pinMode (13, OUTPUT);
  Serial.begin(9600);
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
  


}

void loop()

  


{
  keypad.getKey();

}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  Serial.print("Pressed: ");
  Serial.println(eKey);
  switch (eKey){
    case '*': guessPassword(); break;
    case '#': password.reset();  break;
     default:
	     password.append(eKey);
  }
}

void guessPassword(){
     Serial.print("Guessing password... ");
     if (password.evaluate()){
	      digitalWrite(speakerPin,HIGH);
              digitalWrite(relay,HIGH);
              delay (2000);
              digitalWrite(relay,LOW);
	     Serial.print("Correct");
     }else{
	     Serial.print(passyear);
     }
}

Thanks for all of your help, this is my first arduino project (as you can probably tell!).

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

Try this modification...

Password password;

void setup(){
RTC_DS1307 RTC;
Wire.begin();
RTC.begin();

DateTime now = RTC.now();
char passyear[5];
itoa( now.year(), passyear, 10);
password.set(passyear) ;

Ok, With that modification, These errors occur:

sketch_jun16a:29: error: no matching function for call to 'Password::Password()'
C:\Users\Luke\Desktop\Programs\Arduino\libraries\Password/Password.h:51: note: candidates are: Password::Password(char*)
C:\Users\Luke\Desktop\Programs\Arduino\libraries\Password/Password.h:49: note: Password::Password(const Password&)
sketch_jun16a.cpp: In function 'void guessPassword()':
sketch_jun16a:82: error: 'passyear' was not declared in this scope

Code is:

#include <Password.h>
#include <Keypad.h>
#include <Wire.h>
#include "RTClib.h"





const byte ROWS = 4; // Four rows
const byte COLS = 4; //  columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 7, 6, 5, 4 };// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 12, 11, 10, 8 };


// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

#define relay 3
#define speakerPin 13

Password password;

void setup(){
  RTC_DS1307 RTC;
  Wire.begin();
    RTC.begin();

 DateTime now = RTC.now(); 
  char passyear[5];
itoa( now.year(), passyear, 10);
  password.set(passyear) ; 

 
     pinMode (3, OUTPUT);
  pinMode (13, OUTPUT);
  Serial.begin(9600);
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
  


}

void loop()

  


{
  keypad.getKey();

}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  Serial.print("Pressed: ");
  Serial.println(eKey);
  switch (eKey){
    case '*': guessPassword(); break;
    case '#': password.reset();  break;
     default:
	     password.append(eKey);
  }
}

void guessPassword(){
     Serial.print("Guessing password... ");
     if (password.evaluate()){
	      digitalWrite(speakerPin,HIGH);
              digitalWrite(relay,HIGH);
              delay (2000);
              digitalWrite(relay,LOW);
	     Serial.print("Correct");
     }else{
	     Serial.print(passyear);
     }
}

So, pass a dummy value to the constructor:

Password password'("0000");
sketch_jun16a.cpp: In function 'void guessPassword()':
sketch_jun16a:82: error: 'passyear' was not declared in this scope

So, quit trying to print the variable outside the scope (setup()) where it is defined. Change the scope to global if you think you need to tell the user the correct password when they enter the wrong one.

Thankyou VERY much everyone, so far so good!

#include <Password.h>
#include <Keypad.h>
#include <Wire.h>
#include "RTClib.h"

Password password("");
  char passyear[5];


const byte ROWS = 4; // Four rows
const byte COLS = 4; //  columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 7, 6, 5, 4 };// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 12, 11, 10, 8 };


// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

#define relay 3
#define speakerPin 13


  
void setup(){

   RTC_DS1307 RTC; 
   RTC.adjust(DateTime(__DATE__, __TIME__));
 RTC.begin();
DateTime now = RTC.now(); 

itoa( now.year(), passyear, 10);
  password.set(passyear) ; 



   Wire.begin();
     pinMode (3, OUTPUT);
  pinMode (13, OUTPUT);
  Serial.begin(9600);
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
  }

void loop()

  


{
  keypad.getKey();

}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  Serial.print("Pressed: ");
  Serial.println(eKey);
  switch (eKey){
    case '*': guessPassword(); break;
    case '#': password.reset();  break;
     default:
	     password.append(eKey);
  }
}

void guessPassword(){
     Serial.print("Guessing password... ");
     if (password.evaluate()){
	      digitalWrite(speakerPin,HIGH);
              digitalWrite(relay,HIGH);
              delay (2000);
              digitalWrite(relay,LOW);
	     Serial.print("Correct");
     }else{
	     Serial.print(passyear);
     }
}

Last problem: The year is being stored as 2165? I have confirmed using the DS1307 example project that the year is correctly set, I've even added some code to set the time based on the compilation date of the project. Could it be the way I am storing the value?

itoa( now.year(), passyear, 10);
  password.set(passyear) ;

I have confirmed using the DS1307 example project that the year is correctly set

Why not confirm, using this code, that the year is set correctly?

Why not confirm that the buffer is valued correctly by itoa()?

I'm still very new to this, what would be the best method to do this?

You could print the values to the serial monitor.

By using

Serial.print(passyear);

It outputs 2165.

Pardon my ignorance but if now.year() equals 2012 why is it being stored as 2165?

Edit:

If I move this chunk of code:

   RTC_DS1307 RTC; 
   RTC.adjust(DateTime(__DATE__, __TIME__));
 RTC.begin();
DateTime now = RTC.now(); 
int nowyear = now.year();
itoa( nowyear, passyear, 10);
  password.set(passyear) ;

From Void Setup to Void guessPassword, passyear now equals 2012. Any reason as to why?


Final Edit

Thankyou everyone very much! I created a new function (Unsure what they are called?) and put my set password code in there, works like a charm.

#include <Password.h>
#include <Keypad.h>
#include <Wire.h>
#include "RTClib.h"

Password password("");
  char passyear[5];


const byte ROWS = 4; // Four rows
const byte COLS = 4; //  columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 7, 6, 5, 4 };// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 12, 11, 10, 8 };


// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

#define relay 3
#define speakerPin 13


  
void setup(){
Wire.begin();
     pinMode (3, OUTPUT);
  pinMode (13, OUTPUT);
  Serial.begin(9600);
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
  }

void loop()
{
  keypad.getKey();
}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  Serial.print("Pressed: ");
  Serial.println(eKey);
  switch (eKey){
    case '*': SetPass(); guessPassword(); break;
    case '#': password.reset();  break;
     default:
	     password.append(eKey);
  }
}

void SetPass(){
  
       RTC_DS1307 RTC; 
   RTC.adjust(DateTime(__DATE__, __TIME__));
 RTC.begin();
DateTime now = RTC.now(); 
int nowyear = now.year();
itoa( nowyear, passyear, 10);
  password.set(passyear) ; 
  
}


void guessPassword(){
     Serial.print("Guessing password... ");
     if (password.evaluate()){
	      digitalWrite(speakerPin,HIGH);
              digitalWrite(relay,HIGH);
              delay (2000);
              digitalWrite(relay,LOW);
	     Serial.print("Correct");
     }else{

	     Serial.print(passyear);
     }
}

Again, Why did the positioning of my code cause an incorrect value to be stored?