ESP8266 软 WDT 错误
ESP8266 Soft WDT Error
如何避免此循环中的 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);
}
}
WDT 是“watchdog timer”。看门狗定时器用于在系统出现问题时取回控制权 - 例如,无限循环或其他一些意外情况。当底层系统重新获得控制权时,它会重置这些计时器,以便它们再次从零开始计数。当它们达到最大值时,它们会触发芯片上的硬件复位。
您的代码测量 ESP8266 软件看门狗定时器的持续时间 - 在本例中为 3.19 秒。
ESP8266 有硬件和软件看门狗定时器。 loop()
并不打算无限期地 运行 - 它旨在做少量工作然后 return。当 returns 时,ESP8266 SDK 开始重置看门狗定时器。
delay()
和 yield()
函数都让 SDK 有机会说 "things are okay" 并重置计时器。如果你需要在 loop()
中有很长的 运行ning 代码,你应该偶尔调用其中一个代码,让系统的其余部分有机会 运行.
保持loop()
简短不仅仅是看门狗定时器的问题。它还让网络堆栈有机会 运行 并进行它需要做的处理。
您应该始终设计您的程序,以便 loop()
执行一小批重复处理,然后 returns。它永远不应包含无限循环或长循环代码。
例如,假设您需要每 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()
内部做的工作最少,只有在该做的时候才做。
如何避免此循环中的 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);
}
}
WDT 是“watchdog timer”。看门狗定时器用于在系统出现问题时取回控制权 - 例如,无限循环或其他一些意外情况。当底层系统重新获得控制权时,它会重置这些计时器,以便它们再次从零开始计数。当它们达到最大值时,它们会触发芯片上的硬件复位。
您的代码测量 ESP8266 软件看门狗定时器的持续时间 - 在本例中为 3.19 秒。
ESP8266 有硬件和软件看门狗定时器。 loop()
并不打算无限期地 运行 - 它旨在做少量工作然后 return。当 returns 时,ESP8266 SDK 开始重置看门狗定时器。
delay()
和 yield()
函数都让 SDK 有机会说 "things are okay" 并重置计时器。如果你需要在 loop()
中有很长的 运行ning 代码,你应该偶尔调用其中一个代码,让系统的其余部分有机会 运行.
保持loop()
简短不仅仅是看门狗定时器的问题。它还让网络堆栈有机会 运行 并进行它需要做的处理。
您应该始终设计您的程序,以便 loop()
执行一小批重复处理,然后 returns。它永远不应包含无限循环或长循环代码。
例如,假设您需要每 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()
内部做的工作最少,只有在该做的时候才做。