关于millis()函数50天限制下孵化器风扇代码有效性的问询
关于millis()溢出后孵化器风扇定时代码的有效性分析
我正在制作一款孵化器,需要每隔数分钟运行进排气风扇,因此决定采用millis()函数实现该功能,但得知该函数存在50天的运行限制。请问我编写的以下代码能否不受此限制正常工作?
#define in_out_fan 5 unsigned long interval=1000*30; unsigned long previousMillis=0; void setup(void){ Serial.begin(9600); pinMode(5, OUTPUT); } void loop(void){ unsigned long currentMillis = millis(); if (currentMillis<previousMillis){ previousMillis=0; } if ((currentMillis - previousMillis) >= interval) { digitalWrite(in_out_fan, HIGH); delay(15000); digitalWrite(in_out_fan, LOW); previousMillis = currentMillis; Serial.println("cycle completed"); } }
你的代码可以在millis()溢出后继续正常工作,但其中处理溢出的逻辑是多余的,而且代码里的delay(15000)是个明显的问题,得注意:
millis()溢出无需手动处理:millis()返回的是32位无符号整数,满50天左右会溢出归零,但无符号整数的减法特性会自动处理这种情况——哪怕currentMillis比previousMillis小(溢出后),
currentMillis - previousMillis依然能算出正确的时间差,完全不需要你写的if(currentMillis<previousMillis)那段逻辑,反而这段代码可能在极端情况下打乱定时周期。delay()会阻塞整个程序:你用
delay(15000)让风扇运行15秒,这15秒里整个程序会完全卡住,loop()里的其他逻辑(比如孵化器的温度检测、其他控制)都没法执行,要是孵化器有其他依赖实时响应的功能,这会出问题。建议把风扇的通断也改成非阻塞的millis()实现。
给你改了个优化版代码,完全用非阻塞逻辑,而且自动处理millis()溢出:
#define in_out_fan 5 const unsigned long FAN_INTERVAL = 1000 * 30; // 30分钟的间隔 const unsigned long FAN_RUN_TIME = 15000; // 风扇运行15秒 unsigned long lastCycleStart = 0; unsigned long fanStartTime = 0; bool isFanRunning = false; void setup(void){ Serial.begin(9600); pinMode(in_out_fan, OUTPUT); digitalWrite(in_out_fan, LOW); } void loop(void){ unsigned long now = millis(); // 到了该启动风扇的时间 if (!isFanRunning && (now - lastCycleStart) >= FAN_INTERVAL) { isFanRunning = true; fanStartTime = now; digitalWrite(in_out_fan, HIGH); Serial.println("风扇启动"); } // 风扇运行时间到了,关闭 if (isFanRunning && (now - fanStartTime) >= FAN_RUN_TIME) { isFanRunning = false; lastCycleStart = now; digitalWrite(in_out_fan, LOW); Serial.println("周期完成"); } // 这里可以加任何其他孵化器的逻辑,不会被阻塞 }
内容的提问来源于stack exchange,提问作者Hani Roshan CK
相关产品推荐
相关产品推荐

