我正在尝试执行闪烁(之字形)计时器,其中计时器间隔在每次执行后都会更改。下面是我的代码:
unsigned long timer; // the timer
unsigned long interval_A = 1000; // first interval
unsigned long interval_B = 2000; // second interval
unsigned long cur_interval = 0; // current interval
bool timer_on = false; // flag for timer first initialization
int count = 0; // for alternating interval
void loop()
{
if (!timer_on) {
timer = millis();
count = 1;
cur_interval = interval_A;
timer_on = true;
} else {
if ((millis() - timer) >= cur_interval) {
if (count % 2 == 0 ){ // even
cur_interval = interval_A;
} else { // odd
cur_interval = interval_B;
}
timer += cur_interval;
//do something
Serial.println(millis(), 10);
Serial.println(timer, 10);
Serial.println((millis() - timer), 10);
Serial.println("Time up !");
Serial.println("");
count++;
}
}
上面的计时器不起作用。运行时,它将在串行监视器中产生以下结果:
1000
2000
4294966296
Time up !
1000
4000
4294964297
Time up !
但是,如果我删除以下据称要使其替代的代码,它可以工作:
if (count % 2 == 0){ // even
cur_interval = interval_A;
} else { // odd
cur_interval = interval_B;
}
结果如下:
9000
9000
0
Time up !
10000
10000
0
Time up !
问题是为什么原始代码不起作用,为什么它会产生有趣的结果?任何帮助将不胜感激,因为我已经被困在这里一段时间了:(
问题:您更改此行之前cur_interval
的值:
timer += cur_interval
如果timer
和cur_interval
的初始值分别为5000
和1000
,则在执行上一条指令后,它们的值分别为7000
和2000
。由于您刚刚输入了该代码区域,因此您可以期望millis()
返回一个略大于5000 + 1000 = 6000
的值。因此,当你计算millis() - timer
时,你会得到6000 - 7000 = some large number
,因为所有计时器都是unsigned
类型。
解决方案:移动
timer += cur_interval;
在更新cur_interval
的值之前,才能得到合理的结果。
注意:与其在代码中调用millis()
十几次,不如将其返回值存储在变量cur_time
中并改用该值。