Skip to content

system_timer_current_time_us drifts behind us_ticker_read at a variable rate #451

@martinwork

Description

@martinwork

system_timer_current_time_us loses time relative to us_ticker_read at a variable rate. This affects system_timer_current_time and uBit.systemTime. The drift is usually 1.5 to 4.5 ms/s, but can be higher. Very occasionally, system_timer suddenly catches up by about 60ms.

Reading the system_timer more often speeds up the drift. I suspect interrupts occurring inside update_time cause ticks to be dropped.

This could be improved by only resetting the Timer when timer->read_us() > 2000000000.

Maybe a better solution is to ditch Timer and use us_ticker_read directly?

The example below sends to serial, when button A is clicked or B held down, the times, the difference between them and the rate of drift in microseconds per second.

#include "MicroBit.h"
#include "MicroBitCompat.h"

MicroBit uBit;

uint64_t sys0;
uint64_t sys1;
uint64_t sys;

uint64_t tic0;
uint64_t tic1;
uint64_t tic;

int64_t dif;
double speed;
uint64_t uspers;


void sendTimes()
{
  sys1 = system_timer_current_time_us();
  tic1 = us_ticker_read();

  sys  = sys1 - sys0;
  tic  = tic1 - tic0;

  // difference between us_ticker_read and system_timer_current_time_us
  dif = tic >= sys ? tic - sys : -(sys - tic);

  // calculate drift in us/s
  speed = (double)dif / (double)tic;
  uspers = speed * 1000000.0;

  ManagedString st( (int)tic);
  ManagedString ss( (int)sys);
  ManagedString sd( (int)dif);
  ManagedString sv( (int)uspers);

  ManagedString s = st + "," + ss + "," + sd + "," + sv + "\n";

  uBit.serial.send( s);
}



void onButtonA(MicroBitEvent)
{
  sendTimes();
}



void onButtonB(MicroBitEvent)
{
  while ( uBit.buttonB.isPressed())
  {
    uBit.sleep(10);
    sendTimes();
  }
}


int main()
{
  uBit.init();

  uBit.serial.send( "\n\ntick,sys,tick-sys,speed (us/s)\n");

  sys0 = system_timer_current_time_us();
  tic0 = us_ticker_read();

  sys = 0;
  tic = 0;
  dif = 0;

  uBit.serial.send( "\n\n");

  uBit.messageBus.listen( MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA);
  uBit.messageBus.listen( MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_DOWN, onButtonB);

  release_fiber();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions