如何避免此循环出现Soft WDT reset
错误。
到达数字3190时,始终会发生错误。
unsigned long TimeFrame = 10000;
void setup() {
Serial.begin(9600);
}
void loop() {
unsigned long StartTime = millis();
while (millis() - StartTime <= TimeFrame){
Serial.println(millis() - StartTime);
}
}
我可以数4次到2500,但这是否是解决此错误的正确方法?
感谢您的解释。我在代码中添加了delay(10)
,它可以正常工作。
void setup() {
Serial.begin(9600);
}
void loop() {
unsigned long StartTime = millis();
while (millis() - StartTime <= TimeFrame){
Serial.println(millis() - StartTime);
delay(10);
}
}
答案 0 :(得分:2)
WDT是“ watchdog timer”。看门狗定时器用于在系统出现问题(例如无限循环或某些其他意外情况)时重新获得控制权。当底层系统获得控制权时,它将重置这些计时器,以便它们再次从零开始计数。当它们达到最大值时,将触发芯片上的硬件复位。
您的代码测量ESP8266软件看门狗定时器的时长-在这种情况下为3.19秒。
ESP8266具有硬件和软件看门狗定时器。 loop()
并非旨在无限期运行-旨在进行少量工作然后返回。返回时,ESP8266 SDK会重置看门狗定时器。
通过delay()
和yield()
函数,SDK都有机会说“事情没事”并重置计时器。如果您需要在loop()
中运行长时间的代码,则应偶尔调用其中之一,以使系统的其余部分有运行的机会。
保持loop()
简短也不仅仅是看门狗计时器。它还为网络堆栈提供了运行和执行所需处理的机会。
您应该始终设计程序,以便loop()
进行一小批重复处理,然后返回。它不应包含无限循环或长循环代码。
例如,假设您需要每20秒执行一次操作。这是错误的方法:
void loop() {
unsigned long start = millis();
while(millis() - start < 20*1000) ;
do_something();
}
这会破坏软件的设计工作方式-短暂执行loop()
。它不允许任何其他软件在等待时运行。看门狗定时器将启动并重置您的CPU。
这更好:
void loop() {
delay(20*1000);
do_something();
}
因为delay()
使底层系统重新获得控制权,重置看门狗计时器并进行与网络相关的处理。
我认为这是最好的:
static unsigned long start_time;
void setup() {
start_time = millis();
}
void loop() {
if(millis() - start_time > 20*1000) {
do_something();
start_time = millis();
}
}
因为只有在需要的时候,它在loop()
内部所做的工作最少。