如何以最简方式在Arduino中同时运行两个while循环?
Arduino实现摇杆检测+LCD定时闪烁的最简多任务方案
Arduino是单线程单片机,没法同时执行两个while循环(会阻塞其中一个任务),最简的实现方式是用非阻塞延时(借助millis()函数),把两个任务拆成独立的无阻塞函数,在主loop()里轮流执行,模拟“同时运行”的效果。
核心思路
- 放弃用
while死循环包裹单个任务,改为每次loop()循环中分别处理两个任务的单次逻辑 - 用
millis()记录时间戳,替代delay()实现LCD的5分钟定时闪烁,避免阻塞摇杆检测
代码示例
假设使用1602 LCD和普通模拟摇杆,代码如下:
#include <LiquidCrystal.h> // 摇杆引脚定义 const int joystickX = A0; const int joystickY = A1; const int joystickSW = 2; // LCD引脚定义(根据实际接线调整) LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // LCD定时闪烁参数 unsigned long lastBlinkTime = 0; const unsigned long blinkInterval = 5 * 60 * 1000; // 5分钟(毫秒) bool lcdVisible = true; void setup() { // 初始化LCD lcd.begin(16, 2); lcd.print(":)"); // 默认显示表情 // 初始化摇杆引脚 pinMode(joystickSW, INPUT_PULLUP); } // 摇杆检测任务:单次读取并处理信号 void readJoystick() { int xVal = analogRead(joystickX); int yVal = analogRead(joystickY); bool swPressed = !digitalRead(joystickSW); // 处理摇杆逻辑(示例:串口输出状态) Serial.print("X: "); Serial.print(xVal); Serial.print(" | Y: "); Serial.print(yVal); Serial.print(" | SW: "); Serial.println(swPressed ? "Pressed" : "Released"); } // LCD定时闪烁任务:检查时间并更新显示状态 void updateLCD() { unsigned long currentMillis = millis(); // 检查是否到达闪烁时间间隔 if (currentMillis - lastBlinkTime >= blinkInterval) { lastBlinkTime = currentMillis; // 切换LCD显示状态 lcdVisible = !lcdVisible; if (lcdVisible) { lcd.setCursor(0, 0); lcd.print(":)"); } else { lcd.setCursor(0, 0); lcd.print(" "); // 清空表情位置 } } } void loop() { // 依次执行两个任务,无阻塞 readJoystick(); updateLCD(); delay(50); // 可选:添加短延时降低CPU占用,不影响核心逻辑 }
关键说明
- 非阻塞延时:
millis()返回Arduino开机后的毫秒数,通过对比当前时间和上次闪烁时间,判断是否执行闪烁动作,不会阻塞其他任务 - 任务拆分:每个任务只做单次逻辑处理,
loop()循环会反复调用这两个函数,让两个任务持续运行 - 若需要更复杂的多任务,也可以用
TaskScheduler库,但上述代码是最简的手动实现方案
内容的提问来源于stack exchange,提问作者Kersem21 .K
相关产品推荐
相关产品推荐

