This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Suggestions for low power time keeping on nRF51?

I'm trying to decide the best way to be able to have sub millisecond time keeping, but keep the processor sleeping until it gets a hardware interrupt.

Basically I need to time the period of pulse signals, e.g from a flow meter. Where I may get one pulse every 20 or 30 secs, or possibly several pulses on one second.

Timing to the nearest millisecond would be adequate, but sub millisecond e.g. 100nS would be preferable for accuracy.

The hardware has the external 32kHz crystal, so I was hoping simply to somehow use the hardware counter of the RTC, I'm not sure if that is possible.

On other MCU's I've been able to configure the divider on the 32kHz clock into a hardware counter register, and then simply read the value of the register, to get a fairly accurate time.

(I realise that the counters can roll over, so I need to trigger an interrupt on rollover to handle this)

Is there a way to do something like this on either the nRF51 or even the nRF52?

BTW. I have seen some solutions where the RTC triggers an interrupt which wakes the processor and increments a counter, but I think this would not work for me because I'd need at least 1000 interrupts per second, and the processor would spend most of its time wake in the ISR

  • Hi Roger

    You can definitely use the RTC counter value to keep track of the 32kHz clock. The RTC counter is 24 bits, which means it will overflow every 512 seconds when using the smallest prescaler (for maximum accuracy).

    When it overflows you can wake up, and increment a counter in RAM.

    To read out the current value you just have to concatenate the counter with the current RTC value:

    total_time = RAM_counter << 24 | RTC_counter;
    

    The time of each 32kHz clock is ~30.5us, so this will be the limit of your accuracy. If you want to keep track of absolute time you also have to consider the drift of your clock source. As an example a 20ppm 32k crystal would introduce a potential drift of 1.7 seconds per day.

    Best regards
    Torbjørn

  • Thanks Torbjørn.

    I will try using that method.

    Re: Time drift

    I think the drift in the crystal is well within the limits of what I need, and I am not using the value to calculate an accumulated value, but only to broadcast an instantaneous indication of flow rate, based on frequency of pulses, which would normally occur at a maximum frequency of 10Hz

    This data is encoded into the manufacturer data of the advertising packet, which is broadcast once per second ( to give longer battery life)

  • Doing the following can result in error when the RTC overflow:

    total_time = RAM_counter << 24 | RTC_counter;
    

    If you are doing the read in a lower interrupt priority than RTC overflow interrupt, you can do this:

    do {
      RAM_counter_copy = RAM_counter;
      total_time = RAM_counter_copy << 24 | RTC_counter;
    } while (RAM_counter_copy != RAM_counter);
    
Related