5000 microsecond delay inaccurate with either delayMicroseconds() or nrf_delay_us()

I'm using a Seeed Xiao BL:E Sense board with nrf52840 on it. I observed the 5 millisecond delay being off a lot. It was often > 8 ms and changed each time. I used both delayMicroseconds() and nrf_delay_us(). The behaviors were the same. I also tried to disable interrupts just in case, but got no effect. BTW, I measured the delay time by sending pulses through a debug pin.

#define DBG_PIN 0

void DBG_pulse(void) {
  digitalWrite(DBG_PIN, HIGH);
  digitalWrite(DBG_PIN, LOW);
  return;
}

void onBLEWrite(uint8_t* buffer, size_t size) {
    ...
    noInterrupts();
    DBG_pulse();
    delayMicroseconds(5000);
    //nrf_delay_us(5000);
    DBG_pulse();
    interrupts();
    ...
}    

I noticed if I set the delay to under 3 ms, it seemed working fine. But if I set a 3 ms delay followed by a 2 ms delay, the actually delay went back to > 8 ms. Does someone have any ideas?

Parents
  • Hello,

    The processing of BLE protocol events is performed through interrupts. Therefore, if you start BLE advertising, establish a BLE connection, etc., interrupts in the Bluetooth stack may preempt your delay loop. However, I wouldn't expect the additional delay to be as much as you are observing. Maybe it's related to the Arduino code on top of the BLE stack. I'm not familiar with this implementation. Either way, for accurate timing, I would recommend avoiding the use of a busy-wait and instead using an RTC or a TIMER instance with interrupts enabled.

    Best regards,

    Vidar

Reply
  • Hello,

    The processing of BLE protocol events is performed through interrupts. Therefore, if you start BLE advertising, establish a BLE connection, etc., interrupts in the Bluetooth stack may preempt your delay loop. However, I wouldn't expect the additional delay to be as much as you are observing. Maybe it's related to the Arduino code on top of the BLE stack. I'm not familiar with this implementation. Either way, for accurate timing, I would recommend avoiding the use of a busy-wait and instead using an RTC or a TIMER instance with interrupts enabled.

    Best regards,

    Vidar

Children
Related