Guidance on project using ds1307 rtc

Hello all, I have just started playing around with my Arduino Uno. I have hooked up two RFID-RC522 shields, and one RTC shield with a DS1307 (using the DS1307RTC libary).
My question is about the RTC, and I have been looking around on cpluplus.com for any clues on how to accomplish what I am after, but maybe I am not searching for the correct thing.

Background:
The two RFID readers (will be three soon) will be used to read cards at three different doors, and opening the associated doorlock when an allowed card is presented (still have to work out reading a database with card serials from an SD card). I have used a delay(); to keep the lock open for a period of time, but the bad thing with that is that the program halts until the delay is finished. So I thought of introducing an RTC. I will log the time when the card is presented and the doorlock unlocks, and then just use a check to lock it again when 5 minutes has passed. That's the idea anyways, and I have changed the idea a couple of times already ;).

So, I have made both RC522's work fine, and I can get the time and date from the RTC, so everything is connected and working in the code, just not completely ;).

I have used this as a reference for my code: DS1307RTC Library, For Accessing Real Time Clock (RTC) Chips

I can read the different parts of the time and date using the tm.Hour to get the hour, and tm.minute to get the minutes... Really not that helpful as I need a timestamp sort of function where I get the complete time in one go (or build it using the pieces) so that I can use that value to check when 2 minutes has passed. I also need to make sure it works fine over midnight. It would be best if all the parts of the time and date could be converted into a single number, so that I could easily do the math to see when 2 minutes has passed...

Any ideas?

Also, sorry if this is listed anywhere in the forums. I haven't been able to find the solution for the past day and a half, and thought I'd try here :).

I will post the sketch if needed, but it's kind of messy ;).

Have you looked at using the Scheduler library?

http://playground.arduino.cc/Code/Scheduler

cool, thanks. Will look into it, looks promising. I could issue a lock in 2 minutes after it has been unlocked. brilliant :).
Then I can use the RTC to get tume and date of the events in the log ;).

In case you are using the time.h library - Arduino Playground - HomePage

 time_t t = now(); // Store the current time in time variable t

t is an "unix" time in seconds, so you may use it easily for your calculations..
You may consider TimeAlarms library as well..

Note: Also, you can have more than one instance if needed.

Scheduler scheduler1 = Scheduler(); //create a scheduler 1
Scheduler scheduler2 = Scheduler(); //create a scheduler 2
Scheduler scheduler3 = Scheduler(); //create a scheduler 3
etc.

void loop(){
scheduler1.update(); //update the scheduler1, maybe it is time to execute a function?
scheduler2.update(); //update the scheduler2, maybe it is time to execute a function?
scheduler3.update(); //update the scheduler3, maybe it is time to execute a function?
//other stuff
}

Thanks, I have made one scheduler to be certain it works before I make the rest.

I have put this before the void setup():

Scheduler lock1_lock = Scheduler();

Then in void loop() I have added this:

lock1_lock.update();
//some stuff
.
.
.
lock1_lock.schedule(lock_lock1(),120000);

And, the function lock_lock1 looks like this:

void lock_lock1(){
digitalWrite(lock1_pin,LOW);
Serial.println("Lock1 was locked again at: ");
timestamp();  
}

When I compile this, I get this error:

In function 'void loop()':
71: error: invalid use of void expression

So it appears it does not like the way I create the scheduler, could it be because I am calling a function?

Uhm, figured it out. In the defining of the scheduler I used this: lock_lock1**()**. Removed the () and then it moved on in the compilation.

However, now I receive a lot of other errors… About the Scheduler library itself:

In file included from C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:30:
C:\Program Files (x86)\Arduino\libraries\Scheduler\/Scheduler.h:62: error: 'byte' does not name a type
C:\Program Files (x86)\Arduino\libraries\Scheduler\/Scheduler.h:64: error: 'NUMBER_OF_SCHEDULED_ACTIONS' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\/Scheduler.h:65: error: 'byte' does not name a type
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp: In constructor 'Scheduler::Scheduler()':
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:33: error: 'action' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:33: error: 'NULL' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:36: error: 'currentSize' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp: In member function 'void Scheduler::update()':
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:42: error: 'byte' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:42: error: expected `;' before 'i'
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:42: error: 'i' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:42: error: 'currentSize' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:44: error: 'millis' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:44: error: 'action' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp: In member function 'void Scheduler::schedule(void (*)(), unsigned int)':
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:65: error: 'currentSize' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:65: error: 'NUMBER_OF_SCHEDULED_ACTIONS' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:66: error: 'action' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:68: error: 'millis' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp: In member function 'void Scheduler::defragment()':
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:75: error: 'byte' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:75: error: expected `;' before 'defrag'
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:76: error: expected `;' before 'i'
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:76: error: 'i' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:76: error: 'currentSize' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:77: error: 'action' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler\Scheduler.cpp:78: error: 'defrag' was not declared in this scope

Does the scheduler library work on the Arduino Uno? Read in a post in this forum somewhere that the scheduler only worked on the Due…

I looked for answers around the net, and then downloaded the library again to see if it somehow had become corrupted in any way. Removed it from the libraries folder, and added it back in again.
Looks better, but still has errors:

C:\Program Files (x86)\Arduino\libraries\Scheduler/Scheduler.h:62: error: 'byte' does not name a type
C:\Program Files (x86)\Arduino\libraries\Scheduler/Scheduler.h:64: error: 'NUMBER_OF_SCHEDULED_ACTIONS' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Scheduler/Scheduler.h:65: error: 'byte' does not name a type

Edit:
Resolved it, it appears the library is not 1.0.0+ compliant. Ref.: http://stackoverflow.com/questions/16433802/arduino-time-scheduler-is-not-working

I changed the below in Scheduler.h:

< #include <WProgram.h>  
---  
> #if defined(ARDUINO) && ARDUINO >= 100  
> #include "Arduino.h"  
> #else  
> #include "WProgram.h"  
> #endif

Did you place the unzipped file in your C:\Users\YouUserName\Documents\Arduino\libraries folder? (restart the IDE after)
Do you have #include <Scheduler.h> in your sketch?

Would you share your complete sketch with us?

Make these changes to the Scheduler.h file for the Arduino IDE 1.05
//#include <WProgram.h>
#include <Arduino.h>

Does the scheduler library work on the Arduino Uno?

Yes

Does this example code work?

/*
||
|| @file DelayedSignal.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact alexanderbrevig@gmail.com
||
|| @description
|| | Display a way to delay a led signal on serial recieve.
|| #
*/

#include <Scheduler.h> // [url=http://www.arduino.cc/playground/uploads/Code/Scheduler.zip]Scheduler.zip[/url]

Scheduler scheduler = Scheduler();      //create a scheduler

const byte ledPin = 13;               //LED on pin 13

void setup(){
  Serial.begin(9600);                 //Iitialize the UART
  pinMode(ledPin,OUTPUT);             //set pin 13 to OUTPUT
}

void loop(){
  scheduler.update();                 //update the scheduler, maybe it is time to execute a function?
  
  if (Serial.available()){            //if we have recieved anything on the Serial
    scheduler.schedule(setHigh,500);  //schedule a setHigh call in 500 milliseconds
//    Serial.flush();                   //flush Serial so we do not schedule multiple setHigh calls
    char X = Serial.read();           //flush Serial so we do not schedule multiple setHigh calls
  }
}

void setHigh(){
  digitalWrite(ledPin,HIGH);          //set ledPin HIGH
  scheduler.schedule(setLow,500);     //schedule setLow to execute in 500 milliseconds
}

void setLow(){
  digitalWrite(ledPin,LOW);           //set ledPin LOW
}

Thanks, I made it work, LarryD. It was because the library was not 1.0.0+ compliant.
Everything working fine now :).

I can now successfully open the two "locks" and they will lock again after a period of time :). The scheduler works perfectly.

Good to hear you had success!

Then again, this brungs me to my next question… Not sure it is even possible though, have been looking online but no idea still.

This is basically to minimize the code. As you know, I have two rfid readers and two locks. I have in my loop section, an if statement that checks if a card has been presented on either reader, and reads the serialnumber of the card, opens the lock and creates a schedule that calls a function to lock it again. I aldso logthe time and date. All works good, but it kind of bugs me that the only difference in the code are the names of the variables… Reader1, lock1, reader2, lock2 etc. Would it be possible to move the code into one function and just call it two times with different number inputs?

Something like this:

In void loop() call the function like this:
checkreader(1);
checkreader(2);

And have a function like this (bear with me, writing this on my mobile and code may be a bit off…)

Void checkreader(readernumber);
If (rfid.iscard) {
\do stuff
}

My idea is to call the function with a number as input, and then use that number the variables used for the different readers etc…
should be substituted with 1 and 2 (rfid1.iscard, and rfid2.iscard)
Possible?

Possible?

No. Variables are assigned to addresses, and then the names are discarded. Only the addresses matter. You can not reconstruct, at run time, the name to address mapping that occurred at compile time.

Without resorting to arrays, this is the best you can do:

if(someNumber == 1)
   rfid1.someFunction();
else if(someNumber == 2)
   rfid2.someFunction();

However, since the UNO only has one hardware serial port, and you are using that to talk to the PC, you must be using SoftwareSerial to listen to the RFID readers. Only one instance of SoftwareSerial can listen at a time. So, if rfid1 is listening, waving a card in front of rfid2 will not make anything happen. Similarly, if rfid2 is listening, waving a card in front of rfid1 will not make anything happen.

You really need a Mega, with its 4 hardware serial ports.