每次执行loop
函数时,我都试图让我的Arduino sketch睡1秒。
循环中涉及的方法可能会改变它们的执行时间,这就是我实现millis的原因。
我正在做以下事情:
unsigned long ejecucionExcedida = 0;
int calcularExceso(int tiempo) {
if (tiempo>1000) {
ejecucionExcedida = ejecucionExcedida + (tiempo-1000);
// TO DO agregar alarma si el exceso se incrementa mucho
if(ejecucionExcedida > 20000) {
alertas(9);
}
// Listo las alertas :D
return 1000;
}
else {
if(ejecucionExcedida == 0) {
return tiempo;
}
else {
if (ejecucionExcedida + tiempo < 1000) {
ejecucionExcedida = 0;
return ejecucionExcedida + tiempo;
}
else {
int exceso = ejecucionExcedida + tiempo - 1000;
ejecucionExcedida = exceso;
return 1000;
}
}
}
}
void loop() {
unsigned long comienzo = millis();
// A couple of methods
unsigned long final = millis();
delay(calcularExceso(final-comienzo));
}
预计草图在每次执行时都会延迟一秒钟,但我已经用时钟计时,每次执行的时间超过一秒。
答案 0 :(得分:5)
循环功能与您的代码结合导致了问题。
void loop() {
// B
unsigned long comienzo = millis();
// a couple of methods
unsigned long final = millis();
// C
delay(calcularExceso(final-comienzo));
// A
}
您没有考虑从A到B使用的时间。您也没有考虑测量和延迟(C)之间的时间。
最大的原因是A到B.如果你查看arduino / hardware / arduino / cores / arduino,你会发现main.cpp。一旦你查看这个文件,就会清楚为什么这需要很长时间。
#include <Arduino.h>
int main(void)
{
init();
#if defined(USBCON)
USB.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
它实际上不仅仅是“没有”。
我建议切换到以下方法来补偿这个
void loop() {
static unsigned long start = millis();
// a couple of methods
while (millis() - start < 1000) {
// busy wating
}
// do NOT read again as this would cummulate the drift
// instead add just one second to start
start += 1000;
}
与您的代码不同,它将变量start声明为static。这意味着在loop()的第一次传递期间将从millis()初始化start。在loop()的每次传递之后,它的值将保留用于loop()的下一次传递。在后续通过期间,它将不再被初始化。因此,在第一次通过中,启动可能具有任何巧合值,例如42.紧接着,最后的while将等到millis()达到1042,总计运行时间为1s。然后start将增加1000.所以在第二次传递中它将是1042而最后一次将等到millis()达到2042.在第三次传递开始将是2042并且最后一次将等到millis()到达3042等。正如你所看到的那样,最终的结束时间总是相隔1000毫秒。接下来,loop()的开始将间隔1000毫秒(平均),除了处理serialEventRun()可能引入的一些抖动。
如果您在此更改后仍然遇到大量漂移,那么代码中的某些内容会阻止中断很长时间。由于Arduino的时间是中断的,所以你不能长时间阻止它们。不幸的是,有些功能可能会阻止中断作为副作用。您必须删除代码段才能找出导致此问题的部分。通常最好每次添加一些LED并将其状态切换一次。
尽管如此,根据您的Arduino型号,您最终仍会遇到一些漂移。较旧的型号有晶体时钟漂移约10ppm(每天几秒)。较新的型号通常具有晶体谐振器(更便宜),可能漂移几千ppm(每小时几秒)。我在一篇关于Arduino crystal deviation
的文章中对此进行了分析答案 1 :(得分:0)
您的代码需要时间才能执行,但您没有考虑到