4 years, 5 months ago.

Accurate Millisecond Counter

I'm trying to keep an accurate millisecond count on an LPC1549 for several hours using the following code, but for some reason it's not working:

//Previously initialized variables
unsigned int m_PreviousTimestamp;
int m_CurrentTime;

//Time keeping snippet (called periodically)
unsigned int currentTimestamp = us_ticker_read();
m_CurrentTime += (currentTimestamp - m_PreviousTimestamp) / 1000;
m_PreviousTimestamp = currentTimestamp;

In theory this should keep an accurate elapsed millisecond count without any integer rollover problems caused by the 32-bit microsecond ticker, but it seems to be running 10% slower than just reading us_ticker_read() alone. What am I missing here?

P.S. I can't use a Ticker with a 1ms interrupt due to thread safety issues, and a 1ms RtosTimer isn't getting me accurate enough results.

2 Answers

4 years, 5 months ago.

How periodically is that code called? My guess would be that the issue is that integer divisions are rounded down. So the time increases too slow, and you would have to also keep track of the remainder of the division. (Which would most likely be calculated fasted by using the result of the divide by 1000, if you just use the remainder function it will most likely have to re-calculate that division).

I'm polling it every 5ms. I did a little experiment, and it looks like the call to us_ticker_read() is relatively slow on the LPC1549, so I'm losing about 800ms every 10 seconds. I tested the same code on an LPC11U68, and the drift was significantly less although still present. I'm testing out some alternative code that uses a Timer and resets it every 30min to prevent overflows.

posted by Neil Thiessen 29 Apr 2016

If it is the ticker_read time it would take 400us to read its ticker, that would be extreme even on an M0 that has to do integer divisions, let alone on an M3.

But as long as you take the remainder into account and don't throw it away you should still be fine I think.

posted by Erik - 29 Apr 2016

I clocked us_ticker_read() at 40μs per call on the LPC1549 due to some 64-bit math. Whatever the reason, my new method appears to be working so I'm happy.

posted by Neil Thiessen 29 Apr 2016
4 years, 5 months ago.

Not sure if this will be of help, but I put together a Timer64 class that allows for time measurement over long periods (e.g. hundreds of years). The Timer64 class should also be thread safe. Search mbed for Timer64 if you are interested.

Thanks, but I managed to solve my problem by using a regular Timer and resetting it every 30min to prevent overflows.

posted by Neil Thiessen 29 Apr 2016