Hi all,
got here from thread entitled the same(ish).
I have a functioning RFID reader that I use for immobilising / alarm for classic cars, the one issue I was having was that as or when the alarm was triggered, it was a little pot luck as to the timing when I passed the RFID card over the reader as to if it would turn the alarm off.
As you may have guessed I was using delay()'s which are causing the issue, so this led me onto the thread in question and my further thoughts, as this program will be running continuously for long periods millis() will overspill and return to 0, this will trigger negative values in the time checks every 49 days (ish)
So was thinking that I could simply reset millis(), but I cannot find anything that referred to doing that, I have simplified the original code for my novice head before re-writing my original code, and was looking at checking if millis() is about to overspill and resetting it before it does.
Is this the correct approach, or do I ignore this issue and let it overspill / reset or will either approach create another issue ?
Many thanks in advance
Jon
// SeveralThingsAtTheSameTime.ino
// An expansion of the BlinkWithoutDelay concept to illustrate how a script
// can appear to do several things at the same time
// this sketch has been adapted from the above written by Robin2
//========================================
// ----------LIBRARIES--------------
// --------CONSTANTS (won't change)---------------
const int OutputPin1 = 13; // the pin numbers for the outputs
const int OutputPin2 = 12;
const int OutputPin3 = 11;
const int OutputPin4 = 10;
const int buttonPin = 7; // the pin number for the button
const int Delay1 = 500; // number of millisecs between blinks Delay 1
const int Delay2 = 2500; //Delay 2
const int Delay3 = 4500; //Delay 3
const int Delay4 = 500; // number of millisecs that Outputs are on - all three use this (Delay 4)
const int Delay5 = 300; // number of millisecs between button readings (Delay 5)
//------------ VARIABLES (will change)---------------------
byte State1 = LOW; // used to set pins
byte State2 = LOW; // LOW = off
byte State3 = LOW;
byte buttonLed_State = LOW;
unsigned long timeNow = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousTime1 = 0; // will store last time the Output was updated
unsigned long previousTime2 = 0;
unsigned long previousTime3 = 0;
unsigned long previousButtonMillis = 0; // time when button press last checked
//========================================
void setup() {
Serial.begin(9600);
Serial.println("Starting SeveralThingsAtTheSameTimeRev1.ino"); // so we know what sketch is running
// set the Led pins as output:
pinMode(OutputPin1, OUTPUT);
pinMode(OutputPin2, OUTPUT);
pinMode(OutputPin3, OUTPUT);
pinMode(OutputPin4, OUTPUT);
// set the button pin as input with a pullup resistor to ensure it defaults to HIGH
pinMode(buttonPin, INPUT_PULLUP);
}
//========================================
void loop() {
// Notice that none of the action happens in loop() apart from reading millis()
// it just calls the functions that have the action code
timeNow = millis(); // capture the latest value of millis()
// this is equivalent to noting the time from a clock
// use the same time for all LED flashes to keep them synchronized
if timeNow >= (4294967295 - 5000) { // max 4294967295
Delay(5000); // wait 5000mS millis will go to 0 this should avoid overspill of previousTime(s)as long as this delay is greater than any of the Delay(s)
previousTime1 = 0; // resets previousTime(s)
previousTime2 = 0;
previousTime3 = 0;
// there will be a slight error depending when timeNow ACTUALLY reaches this point but this ensure there is no negative value created in time tests in the functions
}
readButton(); // call all the functions that do the work
UpdateState1();
UpdateState2();
UpdateState3();
SwitchStates();
}
//========================================
void UpdateState1() {
if (State1 == LOW) {
// if the Output is off, we must wait for the (delay)interval to expire before turning it on
if (timeNow - previousTime1 >= Delay1) { //Delay1 = 500mS
// if time is up, change the state to HIGH
// say we check every 100mS then this is checked 5 times before State1 changes timeNow would have been 100 then 200 - 300 - 400 -500
State1 = HIGH;
// and save the time when we made the change
previousTime1 += Delay1; // say we check every 100mS on the 5th loop state switches to high and previousTime1 them becomes 0 + 500 next time the state changes it will become 1000 (500 +500)
// NOTE: The previous line could alternatively be
// previousTime1 = timeNow if this is used and it takes 1mS to get this far then the new previousTime1 would be (501mS this is the latency ?) timeNow resets to 0 after it exceeds 4.29 billion -- making their range from 0 to 4,294,967,295 (2^32 - 1).
// which is the style used in the BlinkWithoutDelay example sketch
// Adding on the interval is a better way to ensure that succesive periods are identical
}
}
else { // i.e. if State1 is HIGH
// if the Led is on, we must wait for the ON duration (Delay4) to expire before turning it off
if (timeNow - previousTime1 >= Delay4) {
// time is up, so change the state to LOW
State1 = LOW;
// and save the time when we made the change
previousTime1 += Delay4;
// NOTE: The previous line could alternatively be
// previousTime1 = timeNow
}
}
}
//========================================
void UpdateState2() {
if (State2 == LOW) {
if (timeNow - previousTime2 >= Delay2) {
State2 = HIGH;
previousTime2 += Delay2;
}
}
else {
if (timeNow - previousTime2 >= Delay4) {
State2 = LOW;
previousTime2 += Delay4;
}
}
}
//========================================
void UpdateState3() {
if (State3 == LOW) {
if (timeNow - previousTime3 >= Delay3) {
State3 = HIGH;
previousTime3 += Delay3;
}
}
else {
if (timeNow - previousTime3 >= Delay4) {
State3 = LOW;
previousTime3 += Delay4;
}
}
}
//========================================
void SwitchStates() {
// this is the code that actually switches the LEDs on and off
digitalWrite(OutputPin1, State1);
digitalWrite(OutputPin2, State2);
digitalWrite(OutputPin3, State3);
digitalWrite(OutputPin4, buttonLed_State);
}
//========================================
void readButton() {
// this only reads the button state after the button interval has elapsed
// this avoids multiple flashes if the button bounces
// every time the button is pressed it changes buttonLed_State causing the Led to go on or off
// Notice that there is no need to synchronize this use of millis() with the flashing Leds
if (millis() - previousButtonMillis >= Delay5) {
if (digitalRead(buttonPin) == LOW) {
buttonLed_State = ! buttonLed_State; // this changes it to LOW if it was HIGH
// and to HIGH if it was LOW
previousButtonMillis += Delay5;
}
}
}
//========================================END