Timing bug with Dash.snooze call? [SOLVED]

I’ve recently been playing with the Dash class, using Dash.snooze() instead of delay(). It works as promised; I’ve even verified the claimed energy save vs. delay(). Here’s the problem: For “moderate” time values, it executes too quickly. My 3 minute delay (300,000 ms), for example, comes in at about 37 seconds (stopwatch error doubtlessly involved here, but I think I’m correct +/- 3 sec). Yet 10 consecutive 1,000 ms statements take the expected 10 seconds to execute. At the other end of the scale, a one-hour Dash.snooze() (3,600,000) pretty much takes an hour (okay, a bit more, but that’s per my earlier note on the clock accuracy).

@MichaelM

You’ve run into the overflow for that timer. I’m working on a fix now so that MAX_ULONG (4,294,967,296) milliseconds will work with snooze(). For now, values up to 71 seconds should work just fine at 120MHz, 85 seconds at 100MHz, and 179 seconds at 48MHz.

I think you have a typo in your question, the 3 minute delay should be 180,000 ms, which would correspond to about 37 seconds accounting for overflow.

I’m not sure why you are seeing the one-hour value working. If you are running at 120MHz, then it should timeout after 20,860 ms.

The snooze() function uses a different timer than millis(), but the clock drift would affect both clocks. We are looking into reducing that drift. The snooze() function will snooze for at least the given number of milliseconds. The setup/teardown overhead should be on the order of microseconds though.

Thanks, Erik, and sorry about the typo. I was going a bit crazy wondering what I was seeing; must have had had a leftover delay call in there.

While we’re on the subject, What do the various megahertz settings do? Is something being adjusted onthe board, or is it merely a function of values that are uploaded from the IDE?

@MichaelM

Selecting a CPU Speed from the Arduino IDE Tools menu sets the system clock speed for the processor. The default and highest speed is 120MHz, but 100MHz and 48MHz are also available. There is a tradeoff between speed and power usage. For many applications, 48MHz would work just fine, and you would save some power during run mode. On the other hand, if your application spends most of the time sleeping/snoozing, but when you wake up you need to do intensive calculations as fast as possible, the higher system clock would be useful. The system clock is turned off when you call snooze/sleep, so you’ll only get the power savings during run time by using a slower speed.

If you have a battery powered device and are doing mostly IO operations (like Serial reads and writes) when awake, the 48MHz clock should work fine.

We may provide even lower clock values in the future, but 48MHz is the slowest clock that works with SerialUSB, so for now that is the minimum.

1 Like

Thanks, Erik, it’s good to know what those settings do – ultimately giving users a choice of “fast” and “power conserve” modes. Clever design.