Clock hangs after 25 days

More
6 months 1 week ago - 6 months 1 week ago #9711 by Ty_Eeberfest
Found another one...

In checkPIR there's a math overflow aka wraparound that occurs when millis() is returning big numbers. Specifically if pirLastSeen + (pirTimeout * 1000) evaluates to anything greater than 4294967295 it wraps around and this line will not do what is wanted:

if (nowMillis > (pirLastSeen + (pirTimeout * 1000))) {

The result is that the display blanks immediately when the PIR stops sensing motion instead of remaining on for pirTimeout seconds.

Maybe I'm being too much of a perfectionist by bringing this up? Problem only happens once every ~50 days and resolves itself after pirTimeout seconds.

Look into it later when the dust is clearing off the crater.
Last edit: 6 months 1 week ago by Ty_Eeberfest.

Please Log in or Create an account to join the conversation.

More
6 months 1 week ago #9712 by Ian
Replied by Ian on topic Clock hangs after 25 days
well if we're going to try to get it right, we might as well try to get it right.

Thanks Ty...

Please Log in or Create an account to join the conversation.

More
6 months 1 week ago #9715 by Ty_Eeberfest
However, I think you will find another related issue involving blankSuppressedSelectionTimoutMillis since it is calculated by adding nowMillis() to TEMP_DISPLAY_MODE_DUR_MS.

Look into it later when the dust is clearing off the crater.

Please Log in or Create an account to join the conversation.

More
6 months 6 days ago #9716 by judge
Replied by judge on topic Clock hangs after 25 days
Got annoyed by being bitten by this, so I implemented a timer class to encapsulate the logic and state. Saves having to remember how to do it and also saves all those different global variables littering the place up.

See SoftMSTimer class here: github.com/judge2005/NixieMisc

Please Log in or Create an account to join the conversation.

More
6 months 6 days ago - 6 months 6 days ago #9720 by Ty_Eeberfest
Paul, can you tell me if code below is the correct way of using your timer class? I've got it doing stuff but am not confident I'm doing it right. For one thing, I see a for loop in your SoftMSTimer::loop() method that seems to iterate thru an array of timers but I can't quite grasp how to get several timers into that array. So I end up calling loop() on every timer. Don't think I'm doing it right.

I'm also not sure why the callback gets run when loop() is called on a timer that has lastCallTick == 0. I understand it initializes lastCallTicks to nowMs but why run the callback then?
#include "SoftMSTimer.h"

SoftMSTimer::TimerInfo myInfo, *p_myInfo = &myInfo;
SoftMSTimer myTimer(&p_myInfo);

SoftMSTimer::TimerInfo myInfo2, *p_myInfo2 = &myInfo2;
SoftMSTimer myTimer2(&p_myInfo2);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.begin(9600);
  
  delay(100); // If I don't do this millis() returns 0 in
              // next lines & timers run callbacks
              //  immediately when loop() is called below.
  *p_myInfo = {250L, millis(), true, &myCall};
  *p_myInfo2 = {5000L, millis(), true, &myCall2};
}

void loop() {
  myTimer.loop();
  myTimer2.loop();
}

void myCall() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

void myCall2() {
  p_myInfo2->enabled = false;
  Serial.println("myCall2 ran");
}

Look into it later when the dust is clearing off the crater.
Last edit: 6 months 6 days ago by Ty_Eeberfest.

Please Log in or Create an account to join the conversation.

More
6 months 6 days ago #9721 by Torsten Lang
Hi judge,
IMHO that code doesn't work either. I don't know the Arduino system so I don't know when the loop() function will be called (is it a background container called by some automagic?), but even without knowing the details I see the following flaws:

1. When lastCallTick is updated while the current tick count delivered by millis() is 0 (which will happen sooner or later if the time delivered by millis() simply is a 1ms free running counter) the function will fire immediately at the next loop after millis() returned 0. If loop() is a background task it will even fire repeatedly until the system time finally advances to 1. It will not happen often as the millis() wrap every approx. 49.72 days, but when it happens...

2. under load (when the loop() may be sporadically called slower than every 1ms) your code will loose ticks. If the only goal is to provide a callback mechanism no faster than 1s the loss of ticks might not be a problem. If the code shall provide a mechanism that is precise at least on average than that is problem.

Just my general thoughts without knowing anything about the Arduino system.

Regards,
Torsten

Please Log in or Create an account to join the conversation.

Moderators: AccutronTy_EeberfestIan
Time to create page: 0.237 seconds

Search

Tube Suppliers

Go to top
JSN Boot template designed by JoomlaShine.com