8 years, 1 month ago.

NRF51822 more accurate micro second timer.

Hi all,

Since I found out that the wait_us for the NRF51822 is limited to an accuracy of 30 microseconds, Im trying to work out an alternative so that I can implement the OneWire protocol. The most obvious means, though inefficient, is to do a while loop until the required time has expired. However I cannot find any obvious way of accurately calculating how long I have been looping.

The Timer object has a read_us method, but again, this only returns multiples of 30us. I cant seem to find any easy way to get the clock ticks.

The method doesn't have to be too power efficient, because it is only needed briefly to query the device every few seconds.

Any ideas?

Thanks

1 Answer

8 years, 1 month ago.

Quote:

The most obvious means, though inefficient, is to do a while loop until the required time has expired

The normal wait is just as inefficient, with as main advantage that it is (besides accurate) compensating for interrupts that happen during the wait, although this depends on the length and starting time of the interrupt.

I would go for this option, and then calculate how long your while loop needs to be using a Timer:

int i = 1000000;
Timer timey;
timey.start();
while(i > 0) {
  i--;
} //Or one of the other options to make this loop
timey.stop();

Now either print the value of the timer, and manually calculate the required number of loops for different delays, or make your program automatically calculate the required number.

Accepted Answer

Thanks.

When I do that though, printing out the value of read_us returns either 0,30 or 60 etc based on the duration, and nothing in between. :(

posted by Kapila De Silva 13 Mar 2016

That is supposed to happen, thats because of that 30us resolution. But if yuo make it loop a million times, as in my example, you should go quite a bit higher than microseconds. Lets say the million loops is done in a 100ms, then you know a single loop is done in 100ns, and if you want 4us delay you need (roughly) 40 loops.

posted by Erik - 13 Mar 2016

Hmmm. Well I got it working by hacking a function shown below, which approximates the micro second timing close enough for the one wire protocol to work with the DS18B20 sensor. So thanks for that, but UGH it pains me to do this....

Ugly Hack

void fakeWaitUs(int delay)
{
    for(int i = 0; i<delay*3; i++)
    {
        long i = 2000000;
        while(i > 0) {
            i--;
        } 
    }
}
posted by Kapila De Silva 13 Mar 2016