Closed drf5n closed 3 weeks ago
I've not tested it yet, but #17 should resolve this.
I've not tested it yet, but #17 should resolve this.
& 0xFFFFFFFF
on an unsigned long, so likely will get optimized away and do nothing.The millis() rollover at 0xFFFFFFFF makes the seconds rollover happen with the change from 0xFFFFFFFF/100=4294967sec
to 0sec at 295ms past the time seconds changed into 4294967. Second 4294967 is short by 705ms, and then a 0 - 4294967 comparison might result in unexpectedly huge numbers like 4294967000.
void setup() {
Serial.begin(115200);
unsigned long zero = 0, biggest = -1, second = 1000;
unsigned long rolloverSecond = biggest / 1000;
unsigned long lastSecondMs = rolloverSecond*1000;
Serial.println(biggest);
Serial.println(rolloverSecond);
Serial.println(lastSecondMs);
Serial.println( zero - rolloverSecond );
}
void loop() {
// put your main code here, to run repeatedly:
}
gives these numbers:
4294967295
4294967
4294967000
4290672329
It seems complicated to handle seconds as millis()/1000. Maybe the methods would work better with elapsedSeconds base number as ms?
For example:
class elapsedSeconds
{
private:
unsigned long ms=0;
public:
elapsedSeconds(void) { ms = millis();}
elapsedSeconds(unsigned long val) { ms = millis() - 1000UL*val ; }
elapsedSeconds(const elapsedSeconds &orig) { ms = orig.ms; }
operator unsigned long () const { return (millis()-ms)/1000; }
elapsedSeconds & operator = (const elapsedSeconds &rhs) { ms = rhs.ms; return *this; }
elapsedSeconds & operator = (unsigned long val) { ms = millis() - val*1000; return *this; }
elapsedSeconds & operator -= (unsigned long val) { ms += val*1000 ; return *this; }
elapsedSeconds & operator += (unsigned long val) { ms -= val*1000 ; return *this; }
elapsedSeconds operator - (int val) const { elapsedSeconds r(*this); r.ms += val*1000UL; return r; }
elapsedSeconds operator - (unsigned int val) const { elapsedSeconds r(*this); r.ms += val*1000UL; return r; }
elapsedSeconds operator - (long val) const { elapsedSeconds r(*this); r.ms += val*1000UL; return r; }
elapsedSeconds operator - (unsigned long val) const { elapsedSeconds r(*this); r.ms += val*1000UL; return r; }
elapsedSeconds operator + (int val) const { elapsedSeconds r(*this); r.ms -= val*1000UL; return r; }
elapsedSeconds operator + (unsigned int val) const { elapsedSeconds r(*this); r.ms -= val*1000UL; return r; }
elapsedSeconds operator + (long val) const { elapsedSeconds r(*this); r.ms -= val*1000UL; return r; }
elapsedSeconds operator + (unsigned long val) const { elapsedSeconds r(*this); r.ms -= val*1000UL; return r; }
};
elapsedSeconds secs, secs2(40);
extern volatile unsigned long timer0_millis;
void setup() {
Serial.begin(115200);
unsigned long zero = 0, biggest = -1, second = 1000;
unsigned long rolloverSecond = biggest / 1000;
unsigned long lastSecondMs = rolloverSecond*1000;
Serial.println(biggest);
Serial.println(rolloverSecond);
Serial.println(lastSecondMs);
Serial.println( zero - rolloverSecond );
secs = 10 ; Serial.println(secs);
secs += 10 ; Serial.println(secs);
secs -= 5 ; Serial.println(secs);
secs2; Serial.println(secs2);
Serial.println();
secs = -10;
noInterrupts();
timer0_millis = zero - 10*second;
interrupts();
}
void loop() {
unsigned long now = millis();
static unsigned long lastSec = secs;
if(secs != lastSec){
lastSec = secs;
Serial.print(now);
Serial.print(" ");
Serial.print(secs);
Serial.print(" ");
Serial.print(secs2);
Serial.println();
}
if(secs == 30){
secs = 100;
secs2 = secs;
}
}
Since elapsedSeconds uses millis()/1000, I was curious about how it handles rollover so I took the example and reset the timer0_millis:
This code blinks the elapsedSeconds LEDs a couple times, and then they stick on.
Wokwi simulation:
https://wokwi.com/projects/402859003988453377