I have an app that uses the Nano 33 BLE and connects via BLE to a mobile phone. One thing it needs internally is a 10mS tick, so I am creating this by using millis().
The way it works is that it notes the time from millis() in setup() - currentTime = millis(), then in loop() it polls millis() looking for a time 10mS or more further on from currentTime. On finding that it does its 10mS tasks, and increments the currentTime by 10mS, and so on.
What I see is that a cumulative error builds up - some times the gap from the previous 10mS is more than 10mS, maybe 12-13mS, but it never recovers it, so the error builds up.
So, I built a very simple test app for the Nano 33 BLE:
#include <Arduino.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
#define TICKPERIOD (10) // 10mS
#define OUTPUTPIN (12) // DigIO 12
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
unsigned long
currentTime;
boolean toggle;
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static void driveOutput(void)
{
digitalWrite(OUTPUTPIN, toggle ? HIGH : LOW);
toggle = !toggle;
}
///////////////////////////////////////////////////////////////////////////
void setup()
{
currentTime = millis();
pinMode(OUTPUTPIN, OUTPUT);
toggle = false;
driveOutput();
}
///////////////////////////////////////////////////////////////////////////
void loop()
{
unsigned long
newTime = millis();
if (newTime >= (currentTime + TICKPERIOD))
{
driveOutput();
currentTime += TICKPERIOD;
}
}
It worked fine, rock solid square wave on D12 inverting every 10mS. So I changed the library to ArduinoBLE.h to pull in all the BLE code, and exactly the same, works fine.
But, as soon as real BLE services and characteristics are set up, the accumulative error returns. I can only assume that something in the library is blocking out the timer interrupt for too long, and interrupts get missed.
So:
- am I right about that?
- is it a known issue?
- if so, is there any way round it? I was rather relying on the 10mS tick without extra hardware.