Hay una cosa importante que debe recordar al trabajar con tiempo en un Arudino de cualquier forma:
- Cada operación lleva tiempo.
Su función foo () tomará una cantidad de tiempo. Cuál es ese momento, no podemos decir.
La forma más confiable de lidiar con el tiempo es confiar solo en el tiempo de activación, no en determinar cuándo debería ser la próxima activación.
Por ejemplo, tome lo siguiente:
if (millis() - last > interval) {
doSomething();
last = millis();
}
La variable last
será el tiempo que se activó la rutina * más el tiempo que doSomething
tardó en ejecutarse. Digamos que interval
es 100, y doSomething
tarda 10 ms en ejecutarse, obtendrá disparos a 101 ms, 212 ms, 323 ms, etc. No los 100 ms que esperaba.
Entonces, una cosa que puede hacer es usar siempre el mismo tiempo, independientemente de recordarlo en un momento específico (como sugiere Juraj):
uint32_t time = millis();
if (time - last > interval) {
doSomething();
last = time;
}
Ahora el tiempo que doSomething()
lleva no tendrá efecto en nada. Por lo tanto, obtendrá disparos a 101 ms, 202 ms, 303 ms, etc. Aún no alcanza los 100 ms que deseaba, porque está buscando que hayan pasado más de 100 ms, y eso significa 101 ms o más. En su lugar, debe usar >=
:
uint32_t time = millis();
if (time - last >= interval) {
doSomething();
last = time;
}
Ahora, suponiendo que no suceda nada más en su bucle, obtiene disparos a 100 ms, 200 ms, 300 ms, etc. Pero tenga en cuenta ese bit: "mientras no suceda nada más en su bucle" ...
¿Qué sucede si una operación que dura 5 ms ocurre a 99 ms ...? Su próximo disparo se retrasará hasta 104 ms. Eso es una deriva. Pero es fácil de combatir. En lugar de decir "El tiempo grabado es ahora", usted dice "El tiempo grabado es 100 ms más tarde de lo que era". Eso significa que, independientemente de los retrasos que obtenga en su código, su activación siempre será a intervalos de 100 ms, o se desplazará dentro de un tic de 100 ms.
if (millis() - last >= interval) {
doSomething();
last += interval;
}
Ahora obtendrá disparos a 100 ms, 200 ms, 300 ms, etc. O si hay retrasos en otros bits de código, puede obtener 100 ms, 204 ms, 300 ms, 408 ms, 503 ms, 600 ms, etc. Siempre intenta ejecutarlo lo más cerca posible el intervalo posible, independientemente de los retrasos. Y si tiene retrasos que son mayores que el intervalo, ejecutará automáticamente su rutina suficientes veces para ponerse al día con la hora actual.
Antes de que tuvieras deriva . Ahora tienes nerviosismo .