【经验】在 ESP8266 长延时中使用 yield 函数-Arduino中文社区 - Powered by Discuz! Archiver

t3486784401 发表于 2020-7-31 18:31

【经验】在 ESP8266 长延时中使用 yield 函数

本帖最后由 t3486784401 于 2020-7-31 18:35 编辑

【背景】
近期用 ESP8266 板验证个 28BYJ 步进电机驱动,遇到了一个蛋疼的问题:
loop 当中包含长延时(总计几秒)以后,会造成 Soft WDT 重启。

查看底层代码、官方文档后了解到:
由于 C/C++ 单线程的特性,loop 不适合使用长延时,单次 loop 运行时间也不宜过长,
否则易造成 8266 后台更新不及时,进而触发 Soft WDT 或是断网等问题。


【解决】
官方提供了一个简单的函数 yield,专用于主动调用运行后台。


【验证】
为了简化过程,特编写如下代码说明 yield 的功能。

代码1:使用 delayMicroseconds 实现长延时(实测 delay 内部包含了 yield 代码,因而测不出重启):
void setup()
{
    Serial.begin(9600);
}
void loop()
{
    Serial.println("Hello");
    for(int i=0; i<5000; i++)
    {
      delayMicroseconds(1000);
    }
}

代码1结果:Soft WDT 重启:




代码2:追加了 yield 的长延时:
void setup()
{
    Serial.begin(9600);
}
void loop()
{
    Serial.println("Hello");
    for(int i=0; i<5000; i++)
    {
      delayMicroseconds(1000);
      yield();
    }
}

代码2结果:重启故障消失。



【结论】
在 ESP8266 当中,如果无可避免的需要长时间运行在 loop 当中(例如解算浮点),
应当时不时调用 yield 保证 8266 后台正常运行,以不重启、不断网为标准。

至于需要多高的调用频率,欢迎大家来测试之 : )



ifeue 发表于 2020-7-31 21:13

学习了,多谢分享。

lcs129 发表于 2020-8-1 21:54

根据你说的我解决了我的问题。

linwqwhu 发表于 2022-4-14 23:28

对的,怪不得我之前看到别人的代码有时候又“莫名其妙”的使用delay()函数。这个问题折腾我一天了,起初我还以为是栈溢出了。

Nills 发表于 2022-6-3 14:14

受教了:P
页: [1]
查看完整版本: 【经验】在 ESP8266 长延时中使用 yield 函数