ESP8266单片机无阻塞延时函数实现方法咨询(C++新手)
用ESP8266实现无阻塞延迟的解决方案
嘿,我完全懂你的需求——想在初始化过程中不卡主流程的前提下,让一段代码在5秒后自动执行,对吧?作为刚接触C++和ESP8266的新手,避开阻塞式的delay()是关键,我给你一套简单易上手的方案:
核心思路:利用millis()实现非阻塞计时
ESP8266的millis()函数会返回从设备启动到当前的毫秒数,而且它不会阻塞程序运行。我们只需要记录下计时的起始时间,然后在主循环里不断检查“当前时间 - 起始时间”是否达到5000毫秒(5秒),一旦满足条件就执行打印操作,完全不影响初始化和其他代码的运行。
具体代码实现
首先在你的代码文件顶部定义两个全局变量(方便初始化函数和主循环都能访问):
unsigned long delayStartTime = 0; bool hasRun = false; // 用来标记是否已经执行过打印,避免重复输出
然后修改你的meInit()函数,在初始化流程里记录计时的起始点:
void meInit() { if (total > 20) total = 20; value = EEPROM.read(1); Serial.begin(115200); Serial.setTimeout(10); // 记录当前时间,作为5秒计时的起点 delayStartTime = millis(); hasRun = false; // 你的其他初始化代码... }
最后在loop()函数里添加检查逻辑:
void loop() { // 检查是否满足5秒条件,且还没执行过目标操作 if (!hasRun && (millis() - delayStartTime >= 5000)) { // 这里替换成你要打印的内容 Serial.println("5秒已过!我是后台执行的内容~"); hasRun = true; // 标记为已执行,防止重复打印 } // 这里放你原本的主循环代码,比如处理传感器、串口数据等 // 这些代码会和计时逻辑并行运行,完全不会被阻塞 }
关键细节说明
- 为什么不用
delay()?:delay()会让整个程序暂停指定时间,期间无法处理任何其他任务;而millis()是“查询式”计时,程序可以继续做其他事,只是每隔一小段时间检查一下是否到点。 - 关于溢出问题:
millis()返回的是unsigned long类型,即使运行超过49天后数值溢出,millis() - delayStartTime的计算依然是正确的,不用担心计时出错。 - 如果想重复执行?:如果希望每隔5秒就打印一次,只需要去掉
hasRun的判断,每次执行完后重置delayStartTime = millis()就行。
内容的提问来源于stack exchange,提问作者peter




