mikaelpatel/Cosa

Clock: Incorrect time in Watchdog::clock (for periods > 1 second).

Closed this issue · 3 comments

I use Cosa Watchdog with large timeout periods (1024ms and above) and it seems my Alarms are not triggered at the right time, e.g for 1024ms watchdog period, a 10 seconds alarm is triggered only every 12 seconds.

Additional delay is even worse when using bigger timeouts.

After investigating, I think the problem is with ::Clock::tick() method implementation:

  void tick(uint16_t ms)
  {
    synchronized {
      m_msec += ms;
      if (m_msec >= 1000) {
        m_msec -= 1000 + m_cal;
        m_sec += 1;
        dispatch();
      }
    }
  }

As one can see, m_sec will be incorrect if m_msec m_msec >= 2000 ms, however this can happen when the argument ms is > 1000 ms.

That method is called by ISR(WDT_vect):

  if (Watchdog::s_clock != NULL)
    Watchdog::s_clock->tick(Watchdog::s_ms_per_tick);

where s_ms_per_tick can be 1024ms or above (up to 8 seconds).

Yes, it looks like the code is written with the assumption that the Watchdog period is less than 1 second. Might need to write this a "while (m_msec >= 1000) { m_msec += 1000 + m_cal; m_sec +=1; }" and the dispatch().

Did a quick update to avoid this error. Please see commit a6cbc71. Test briefly with CosaAlarm.ino and USE_WATCHDOG with 2048 ms period.

Hi Mikael, thanks for the quick fix. I'll update and run my program again this week when I find some time.