Quarta opzione per azzerare il timer.
Se l'operazione di divisione di azzeramento del timer è critico per te, puoi evitare di saltare il timer e le chiamate non necessarie come segue:
#define PERIOD 500
uint32_t timer = 0;
void loop()
{
if (millis() - timer >= PERIOD)
{
// azione
do
{
timer += PERIOD;
if (timer < PERIOD) // uint32_t overflow
break;
}
while (timer < millis() - PERIOD); // protezione per saltare i passaggi
}
}
Forse non dovresti usare un tale mucchio di codice.