AndrewMascolo / CountUpDownTimer

MIT License
28 stars 20 forks source link

micros() Rollover? #11

Open MechaNickW opened 8 years ago

MechaNickW commented 8 years ago

First off, thank you Andrew for making this helpful library. I'm trying to use this library for a sketch that involves keeping time over the course of 2-3 days. Everything in the sketch works properly when I test it on short timescales (less than an hour), but when I try to bump up to longer time periods it's acting like there's a rollover going on that is not handled.

Looking at the master code, it seems like you are accounting for the microsecond rollover period of 71.6 minutes. Has anyone tried using this code for anything on longer timescales and encountered the same issue? Since I don't need microsecond resolution or care at all about high accuracy in timekeeping, would changing the part of the library that uses microseconds for tracking time (boolean Timer() ) over to milliseconds work? Then I'd get a rollover period of 49.7 days, which shouldn't be an issue.

I'm currently running the timer on my Arduino with the serial monitor for a couple of days to see if this is indeed the case. Any help is appreciated.

AndrewMascolo commented 8 years ago

Interesting request, I haven't come across this kind thing before but yes I can make it have precision which will give you more days. I come up with something.

Sent from my iPhone

On Jun 22, 2016, at 2:15 PM, MechaNickW notifications@github.com wrote:

First off, thank you Andrew for making this helpful library. I'm trying to use this library for a sketch that involves keeping time over the course of 2-3 days. Everything in the sketch works properly when I test it on short timescales (less than an hour), but when I try to bump up to longer time periods it's acting like there's a rollover going on that is not handled.

Looking at the master code, it seems like you are accounting for the microsecond rollover period of 71.6 minutes. Has anyone tried using this code for anything on longer timescales and encountered the same issue? Since I don't need microsecond resolution or care at all about high accuracy in timekeeping, would changing the part of the library that uses microseconds for tracking time (boolean Timer() ) over to milliseconds work? Then I'd get a rollover period of 49.7 days, which shouldn't be an issue.

I'm currently running the timer on my Arduino with the serial monitor for a couple of days to see if this is indeed the case. Any help is appreciated.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

MechaNickW commented 8 years ago

Wow. That was a quick reply. Yeah, there's something going on with the rollover. I ran your count up timer example code and commented out the 30 second stop. I just let it sit since I last commented, and here's the output from the serial monitor at the 71.6 minute mark:

1:11:34:4294030:4294029577 1:11:35:63:62289 1:11:36:1063:1062293 1:11:37:2063:2062301 1:11:38:3063:3062309 1:11:39:4063:4062317 1:11:40:5063:5062321 1:11:41:6063:6062329 1:11:42:7063:7062333 1:11:43:8063:8062341 1:11:44:9063:9062357 1:11:45:10063:10062361 1:11:46:11063:11062365

I understand that it has to rollover micros() because of the nature of unsigned long, but here it is also rolling over the milliseconds as well. I wonder if implementing some sort of overflow similar to what you did with hours, minutes, seconds in the code for microseconds to milliseconds will do the trick. That way it can roll over the microseconds before the limitation of the variable type at some defined point (1000000, say) and bump that number up to the microseconds. It will still run into the rollover of milliseconds at 49.7 days again because of the limitations of unsigned long, but for most applications this will work. Although, it should be possible to do the same thing with milliseconds to seconds. I will let it keep running.

MechaNickW commented 8 years ago

Additionally, my sketch is using ShowTotalSeconds() as a way to do stuff based on the time. Full code is below. I'm running your example again and printing the total seconds to serial monitor to see if it's rolling this over as well.

/*
Cat Pan Code
*/
#include <CountUpDownTimer.h>

CountUpDownTimer T(UP);

int redPin = 1; // red pin of RGB LED
int greenPin = 4; // green leg of RGB LED
volatile int sensor = 0; // magnetic reed switch on Pin 2 (external interrupt pin)
unsigned long greenTime = 86400; // duration of time for LED to be green in seconds
unsigned long yellowTime = 86401; // duration of time for LED to be yellow in seconds
unsigned long redTime = 172800; // duration of time for LED to be red in seconds

void setup()
{
  PCMSK = 0b00000100;    // turn on interrupts on pins PB2
  //PCMSK = 0b00010011;
  sei();                 // enables interrupts
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(sensor, INPUT);
  attachInterrupt(sensor, pin_ISR, CHANGE); // If the state of the switch on pin 2 changes, go to interrupt
  T.SetTimer(0);
  T.StartTimer();

}

void loop()
{ 
  T.Timer(); //run the timer
 if ( T.ShowTotalSeconds() <= greenTime) //If time elapsed is equal to or less than greenTime
  {setColor(0, 255); //set RGB to green
  }
  else if((T.ShowTotalSeconds() >= yellowTime) && ( T.ShowTotalSeconds() <= redTime)) //If time elapsed is equal to or greater than yellowTime but not more than redTime
  {setColor(125, 125); //set RGB to yellow
  }
  else if( T.ShowTotalSeconds() >= redTime) //If time elapsed is equal to or greater than redTime
 {setColor(255, 0);  // set RGB to red
}
}
void pin_ISR(){
 static unsigned long last_interrupt_time = 0; //For debounce
 unsigned long interrupt_time = millis();  // For debounce
 if (interrupt_time - last_interrupt_time > 200) // If interrupts come faster than 200ms, assume it's a bounce and ignore
 {
   T.ResetTimer(); //if the state of the reed switch changes, reset the timer to 0
 }
 last_interrupt_time = interrupt_time;
  }

void setColor(int red, int green) //To set the colors of the RGB led
{
  analogWrite(redPin, red); 
  analogWrite(greenPin, green); 
}
AndrewMascolo commented 8 years ago

Updated the code, give it try.

jhwang107 commented 8 years ago

Awesome, I have similar uses running 1-2 weeks. Thanks Andrew~

AndrewMascolo commented 8 years ago

??? Uses or issues?

Sent from my iPhone

On Jul 5, 2016, at 1:16 PM, jhwang107 notifications@github.com wrote:

Awesome, I have similar uses running 1-2 weeks. Thanks Andrew~

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.