醬是創客的ESP32教學主題第七篇,以Ai-Thinker安信可NodeMCU-32S(使用Arduino語言)來實作教學,本篇教學將著單核多工Task事件處理,也就是我們常說如何用multi-task(多工處理)的方法在單核心下去跑,且不以delay的方式來卡住其他function函數,這個適用於需要同時跑MQTT、TTL訊號或RS232/485/422發送與讀取、亮滅LED、如何安排程式在單核心程式碼跑,並準時在某個時間點跑,請參考此篇
以下是我們今天的目標
- LED亮與滅的操作與電子元件接線
- 使用millis()函數來取得系統時間
- 使用unsigned long來減去時間,並取得絕對時間。因為unsigned long(範圍是0 ~ 4294967295)循環特性,不論溢位與否,相減都可以取得絕對正數時間。所以不會有
N天後程式碼就不會動的問題 - 使用pinMode來定義21與22的output模式
- 使用digitalWrite來亮滅LED
NodeMCU-32S電路接線圖如下
- GPIO21–(長腳)LED(短腳)–電阻(220歐姆)–GND
- GPIO22–(長腳)LED(短腳)–電阻(220歐姆)–GND

Arduino 範例程式碼如下
//醬是創客 開發實作的好夥伴
#include "WiFi.h"
//task
unsigned long currentMillis = 0;
unsigned long previousMillisLED21 = 0;
unsigned long previousMillisLED22 = 0;
int intervalLED21 = 1000;
int intervalLED22 = 1500;
boolean LED21state = false;
boolean LED22state = false;
void setup() {
Serial.begin(115200);
//LED
pinMode(21, OUTPUT);
pinMode(22, OUTPUT);
}
void loop() {
currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillisLED21) >= intervalLED21) {
LED21state = !LED21state;
digitalWrite(21, LED21state);
// previousMillisLED21存入最後執行的時間
previousMillisLED21 = currentMillis;
Serial.println("In LED 21 Current time:");
Serial.println(previousMillisLED21);
}
if ((unsigned long)(currentMillis - previousMillisLED22) >= intervalLED22) {
LED22state = !LED22state;
digitalWrite(22, LED22state);
// previousMillisLED22存入最後執行的時間
previousMillisLED22 = currentMillis;
Serial.println("In LED 22 Current time:");
Serial.println(previousMillisLED22);
}
}
Arduino 序列埠監控視窗 輸出如下
In LED 21 Current time: 31000 In LED 22 Current time: 31500 In LED 21 Current time: 32000 In LED 21 Current time: 33000 In LED 22 Current time: 33000
