作業3,4 的ESP32程式
Arduino IDE 安裝建置ESP32開發板
參考 https://shop.mirotek.com.tw/iot/esp32-start-2/ 或
https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/
- 下載Arduino IDE
- 在 Arduino IDE 設定 ESP32開發板
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
- 安裝 Arduino IDE 程式庫(Library)
#include <MFRC522v2.h>https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
- 使用範例檔Blink: (組譯 上傳 )
ESP32程式 (作業3/4 相同)
- WIFI
- const char* ssid = "alex9ufo"; 需修改
- const char* password = "alex9981"; 需修改
- MQTT Broker
- const char* mqttBroker = "broker.mqtt-dashboard.com";
- int mqttPort = 1883;
- --- MQTT 主題設定 ---
const char* topic_UID_publish = "alex9ufo/rfid/UID";
const char* topic_LED_subscribe = "alex9ufo/rfid/led";
const char* topic_LED_status_publish = "alex9ufo/rfid/ledStatus";
- Signal MFRC522 WROOM-32
- RST/Reset RST 21
- SPI SS SDA 5
- SPI MOSI MOSI 23
- SPI MISO MISO 19
- SPI SCK SCK 18
- LED 13 (陰極) VCC (陽極) LOW亮 HIGH 滅
/***
Signal MFRC522 WROOM-32
RST/Reset RST 21
SPI SS SDA 5
SPI MOSI MOSI 23
SPI MISO MISO 19
SPI SCK SCK 18
***/
// 引入 FreeRTOS 函式庫
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/semphr.h>
#include <freertos/queue.h>
// Wifi 與 MQttClient 程式庫
#include <ArduinoMqttClient.h>
#include <WiFi.h>
// *** 新增: 解決 'esp_task_wdt_deinit' not declared 的問題 ***
#include "esp_task_wdt.h"
// --- MFRC522v2 程式庫 ---
#include <MFRC522v2.h>
#include <MFRC522DriverSPI.h>
#include <MFRC522DriverPinSimple.h>
// ---------------------------------------------
// --- Wi-Fi 和 MQTT 設定 ---
const char* ssid = "alex9ufo";
const char* password = "alex9981";
const char* mqttBroker = "broker.mqtt-dashboard.com";
int mqttPort = 1883;
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
// --- MQTT 主題設定 ---
const char* topic_UID_publish = "alex9ufo/rfid/UID";
const char* topic_LED_subscribe = "alex9ufo/rfid/led";
const char* topic_LED_status_publish = "alex9ufo/rfid/ledStatus";
// --- 硬體腳位設定 ---
#define RST_PIN 21
#define SS_PIN 5
#define LED_PIN 13 // 用於 LED 控制的 GPIO 腳位 (假設使用 GPIO 13)
MFRC522DriverPinSimple ss_pin_v2(SS_PIN);
MFRC522DriverSPI driver{ss_pin_v2};
MFRC522 mfrc522{driver};
// --- 雙核心通訊變數 (使用 FreeRTOS) ---
String new_uid_to_publish = "";
SemaphoreHandle_t xUidMutex;
QueueHandle_t xLedQueue;
String current_led_status = "OFF";
SemaphoreHandle_t xStatusMutex;
// --- MFRC522 狀態變數 (Core 1 使用) ---
byte last_UID[10] = {0};
byte last_UID_Size = 0;
unsigned long last_publish_time = 0;
const unsigned long REPEAT_DELAY_MS = 5000;
// --- 函數宣告 ---
void connectWifi();
void connectMqtt();
void onMqttMessage(int messageSize);
void ledMqttTask(void *pvParameters);
void rfidLedControlTask(void *pvParameters);
String uidToHexString(byte *buffer, byte bufferSize);
// ---------------------------------------------------------------------------------
// ------------------------------ CORE 0: MQTT/控制中心任務 -------------------------
// ---------------------------------------------------------------------------------
void onMqttMessage(int messageSize) {
String topic = mqttClient.messageTopic();
if (topic == topic_LED_subscribe) {
String command = "";
while (mqttClient.available()) {
command += (char)mqttClient.read();
}
command.toUpperCase();
Serial.print("Core 0: Received LED command: ");
Serial.println(command);
if (xQueueSend(xLedQueue, &command, (TickType_t)10) != pdPASS) {
Serial.println("Core 0: Failed to send LED command to Core 1.");
}
}
}
void ledMqttTask(void *pvParameters) {
connectWifi();
vTaskDelay(pdMS_TO_TICKS(1000));
connectMqtt();
mqttClient.onMessage(onMqttMessage);
mqttClient.subscribe(topic_LED_subscribe);
Serial.print("Core 0: Subscribed to ");
Serial.println(topic_LED_subscribe);
Serial.println("Core 0: MQTT UID Publish & LED Command Task Running.");
while (1) {
if (WiFi.status() != WL_CONNECTED) {
connectWifi();
}
if (!mqttClient.connected()) {
connectMqtt();
mqttClient.subscribe(topic_LED_subscribe); // 重連後重新訂閱
}
mqttClient.poll();
// 1. 處理 MFRC522 UID 發佈 (從 Core 1 接收)
if (xSemaphoreTake(xUidMutex, (TickType_t)10) == pdTRUE) {
if (new_uid_to_publish.length() > 0) {
mqttClient.beginMessage(topic_UID_publish, new_uid_to_publish.length(), false, 1, false);
mqttClient.print(new_uid_to_publish);
mqttClient.endMessage();
Serial.print("Core 0: Published UID: ");
Serial.println(new_uid_to_publish);
new_uid_to_publish = "";
}
xSemaphoreGive(xUidMutex);
}
// 2. 處理 LED 狀態發佈 (從 Core 1 接收並發佈)
if (xSemaphoreTake(xStatusMutex, (TickType_t)10) == pdTRUE) {
if (current_led_status != "SENT") {
mqttClient.beginMessage(topic_LED_status_publish, current_led_status.length(), false, 1, false);
mqttClient.print(current_led_status);
mqttClient.endMessage();
Serial.print("Core 0: Published LED Status: ");
Serial.println(current_led_status);
current_led_status = "SENT";
}
xSemaphoreGive(xStatusMutex);
}
vTaskDelay(pdMS_TO_TICKS(50));
}
}
void connectWifi() {
Serial.print("Core 0: Connecting to Wi-Fi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
vTaskDelay(pdMS_TO_TICKS(500));
Serial.print(".");
}
Serial.println("\nCore 0: Wi-Fi connected.");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}
void connectMqtt() {
Serial.print("Core 0: Connecting to MQTT Broker: ");
Serial.println(mqttBroker);
mqttClient.setId("ESP32_MFRC522_LED_Client");
if (!mqttClient.connect(mqttBroker, mqttPort)) {
Serial.print("Core 0: MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
vTaskDelay(pdMS_TO_TICKS(4000));
return;
}
Serial.println("Core 0: MQTT connected.");
}
// ---------------------------------------------------------------------------------
// ------------------------------ CORE 1: RFID/LED 控制任務 -----------------------
// ---------------------------------------------------------------------------------
void rfidLedControlTask(void *pvParameters) {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
vTaskDelay(pdMS_TO_TICKS(500));
mfrc522.PCD_Init();
Serial.println("Core 1: RFID/LED Control Task Running.");
String led_command;
unsigned long flash_timer = 0;
bool led_state = false;
while (1) {
// 1. 處理來自 Core 0 的 LED 命令 (Queue)
if (xQueueReceive(xLedQueue, &led_command, (TickType_t)0) == pdPASS) {
flash_timer = 0;
if (led_command == "ON") {
digitalWrite(LED_PIN,LOW);
} else if (led_command == "OFF") {
digitalWrite(LED_PIN, HIGH);
} else if (led_command == "FLASH") {
flash_timer = millis();
} else if (led_command == "TIMER") {
flash_timer = millis() + 10000; // 10 秒定時
digitalWrite(LED_PIN,LOW);
}
if (xSemaphoreTake(xStatusMutex, (TickType_t)10) == pdTRUE) {
current_led_status = led_command;
xSemaphoreGive(xStatusMutex);
}
}
// 2. 處理 LED 邏輯 (閃爍/定時)
if (flash_timer > 0) {
if (led_command == "FLASH") {
if (millis() - flash_timer >= 500) {
led_state = !led_state;
digitalWrite(LED_PIN, led_state);
flash_timer = millis();
}
} else if (led_command == "TIMER") {
if (millis() >= flash_timer) {
digitalWrite(LED_PIN, HIGH);
flash_timer = 0;
led_command = "OFF";
if (xSemaphoreTake(xStatusMutex, (TickType_t)10) == pdTRUE) {
current_led_status = "OFF";
xSemaphoreGive(xStatusMutex);
}
}
}
}
// 3. 處理 RFID 讀取
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
byte* currentUID = mfrc522.uid.uidByte;
byte currentUIDSize = mfrc522.uid.size;
String hexUID = uidToHexString(currentUID, currentUIDSize);
bool is_same_card = true;
if (currentUIDSize != last_UID_Size) {
is_same_card = false;
} else {
for (int i = 0; i < currentUIDSize; i++) {
if (currentUID[i] != last_UID[i]) {
is_same_card = false;
break;
}
}
}
bool should_publish = false;
if (!is_same_card) {
Serial.println("Core 1: New card detected. Publishing immediately.");
should_publish = true;
} else if (millis() - last_publish_time >= REPEAT_DELAY_MS) {
Serial.println("Core 1: Same card detected after 5s. Publishing.");
should_publish = true;
}
if (should_publish) {
if (xSemaphoreTake(xUidMutex, (TickType_t)10) == pdTRUE) {
new_uid_to_publish = hexUID;
xSemaphoreGive(xUidMutex);
}
last_publish_time = millis();
memcpy(last_UID, currentUID, currentUIDSize);
last_UID_Size = currentUIDSize;
}
mfrc522.PICC_HaltA();
}
vTaskDelay(pdMS_TO_TICKS(10));
}
}
// 將 UID 轉換為十六進位字串 (例如 04C926442A2780)
String uidToHexString(byte *buffer, byte bufferSize) {
String output = "";
for (byte i = 0; i < bufferSize; i++) {
if (buffer[i] < 0x10) {
output += "0";
}
output += String(buffer[i], HEX);
}
output.toUpperCase();
return output;
}
// ---------------------------------------------------------------------------------
// ------------------------------------ SETUP & LOOP -------------------------------
// ---------------------------------------------------------------------------------
void setup() {
Serial.begin(115200);
// *** 最終解決方案: 引入 esp_task_wdt.h 並呼叫 esp_task_wdt_deinit() ***
// 這將完全禁用 Task WDT,解決不斷出現的 'task not found' 錯誤。
esp_task_wdt_deinit();
Serial.println("Task Watchdog Timer (TWDT) completely disabled.");
SPI.begin();
// 初始化 Mutex 和 Queue
xUidMutex = xSemaphoreCreateMutex();
xStatusMutex = xSemaphoreCreateMutex();
xLedQueue = xQueueCreate(5, sizeof(String));
if (xUidMutex == NULL || xStatusMutex == NULL || xLedQueue == NULL) {
Serial.println("FreeRTOS resource creation failed!");
while (1);
}
// 啟動 Core 0 上的 MQTT 任務
xTaskCreatePinnedToCore(
ledMqttTask,
"MQTT_PUB_Task",
10000,
NULL,
1,
NULL,
0 // 核心 ID (Core 0)
);
// 啟動 Core 1 上的 RFID/LED 控制任務
xTaskCreatePinnedToCore(
rfidLedControlTask,
"RFID_LED_Task",
12288,
NULL,
1,
NULL,
1 // 核心 ID (Core 1)
);
}
void loop() {
vTaskDelay(1);
}
//=======================================================
程式碼是一個使用 ESP32 雙核心 (Dual-Core) 架構的專案,結合了 MFRC522 RFID 讀卡器、MQTT 網路通訊以及 LED 控制。它專門為了解決多工處理時可能發生的看門狗計時器 (WDT) 錯誤,並將網路和硬體任務分派到不同的核心上運行。
以下是程式碼的逐行說明:
I. 標頭檔引入 (Includes)
| 程式碼 | 說明 |
#include <freertos/...> | 引入 FreeRTOS 函式庫,用於支援 ESP32 的雙核心操作、任務創建、互斥鎖 (Mutex) 和佇列 (Queue) 等。 |
#include <ArduinoMqttClient.h> | 引入 MQTT 客戶端函式庫,用於連接 MQTT Broker。 |
#include <WiFi.h> | 引入 ESP32 的 Wi-Fi 函式庫。 |
#include "esp_task_wdt.h" | 【關鍵修正】 引入 ESP32 Task Watchdog Timer 相關定義。這是解決您序列埠中 task not found 錯誤的關鍵,允許我們在 setup() 中完全禁用它。 |
#include <MFRC522v2.h> 等 | 引入 MFRC522 RFID 讀卡器函式庫及相關驅動程式。 |
這個程式碼是一個使用 ESP32 雙核心 (Dual-Core) 架構的專案,結合了 MFRC522 RFID 讀卡器、MQTT 網路通訊以及 LED 控制。它專門為了解決多工處理時可能發生的看門狗計時器 (WDT) 錯誤,並將網路和硬體任務分派到不同的核心上運行。
以下是程式碼的逐行說明:
I. 標頭檔引入 (Includes)
| 程式碼 | 說明 |
#include <freertos/...> | 引入 FreeRTOS 函式庫,用於支援 ESP32 的雙核心操作、任務創建、互斥鎖 (Mutex) 和佇列 (Queue) 等。 |
#include <ArduinoMqttClient.h> | 引入 MQTT 客戶端函式庫,用於連接 MQTT Broker。 |
#include <WiFi.h> | 引入 ESP32 的 Wi-Fi 函式庫。 |
#include "esp_task_wdt.h" | 【關鍵修正】 引入 ESP32 Task Watchdog Timer 相關定義。這是解決您序列埠中 task not found 錯誤的關鍵,允許我們在 setup() 中完全禁用它。 |
#include <MFRC522v2.h> 等 | 引入 MFRC522 RFID 讀卡器函式庫及相關驅動程式。 |
II. 設定與硬體初始化
| 程式碼 | 說明 |
const char* ssid = "alex9ufo"; | Wi-Fi 網路名稱。 |
const char* mqttBroker = ... | MQTT Broker (代理人) 的網址 (例如 broker.mqtt-dashboard.com)。 |
MqttClient mqttClient(wifiClient); | 建立 MQTT 客戶端物件,使用 WiFi 連線。 |
const char* topic_UID_publish = ... | 發布 (Publish) RFID UID 的主題 ( |
const char* topic_LED_subscribe = ... | 訂閱 (Subscribe) LED 控制命令的主題 ( |
const char* topic_LED_status_publish = ... | 發布 (Publish) LED 當前狀態的主題 ( |
#define RST_PIN 27 / #define SS_PIN 5 | 定義 MFRC522 讀卡器的 RST (重設) 和 SS (片選) 腳位。 |
#define LED_PIN 2 | 定義 LED 腳位 (GPIO 2)。 |
MFRC522 mfrc522{driver}; | 建立 MFRC522 讀卡器物件。 |
這個程式碼是一個使用 ESP32 雙核心 (Dual-Core) 架構的專案,結合了 MFRC522 RFID 讀卡器、MQTT 網路通訊以及 LED 控制。它專門為了解決多工處理時可能發生的看門狗計時器 (WDT) 錯誤,並將網路和硬體任務分派到不同的核心上運行。
以下是程式碼的逐行說明:
I. 標頭檔引入 (Includes)
| 程式碼 | 說明 |
#include <freertos/...> | 引入 FreeRTOS 函式庫,用於支援 ESP32 的雙核心操作、任務創建、互斥鎖 (Mutex) 和佇列 (Queue) 等。 |
#include <ArduinoMqttClient.h> | 引入 MQTT 客戶端函式庫,用於連接 MQTT Broker。 |
#include <WiFi.h> | 引入 ESP32 的 Wi-Fi 函式庫。 |
#include "esp_task_wdt.h" | 【關鍵修正】 引入 ESP32 Task Watchdog Timer 相關定義。這是解決您序列埠中 task not found 錯誤的關鍵,允許我們在 setup() 中完全禁用它。 |
#include <MFRC522v2.h> 等 | 引入 MFRC522 RFID 讀卡器函式庫及相關驅動程式。 |
II. 設定與硬體初始化
| 程式碼 | 說明 |
const char* ssid = "alex9ufo"; | Wi-Fi 網路名稱。 |
const char* mqttBroker = ... | MQTT Broker (代理人) 的網址 (例如 broker.mqtt-dashboard.com)。 |
MqttClient mqttClient(wifiClient); | 建立 MQTT 客戶端物件,使用 WiFi 連線。 |
const char* topic_UID_publish = ... | 發布 (Publish) RFID UID 的主題 ( |
const char* topic_LED_subscribe = ... | 訂閱 (Subscribe) LED 控制命令的主題 ( |
const char* topic_LED_status_publish = ... | 發布 (Publish) LED 當前狀態的主題 ( |
#define RST_PIN 27 / #define SS_PIN 5 | 定義 MFRC522 讀卡器的 RST (重設) 和 SS (片選) 腳位。 |
#define LED_PIN 2 | 定義 LED 腳位 (GPIO 2)。 |
MFRC522 mfrc522{driver}; | 建立 MFRC522 讀卡器物件。 |
III. FreeRTOS 任務間通訊變數 (IPC)
| 程式碼 | 說明 |
String new_uid_to_publish = ""; | Core 1 讀取到新卡時,將 UID 暫存於此,供 Core 0 發布。 |
SemaphoreHandle_t xUidMutex; | 互斥鎖 (Mutex):保護 new_uid_to_publish,確保 Core 0 和 Core 1 同時存取時不會發生資料衝突。 |
QueueHandle_t xLedQueue; | 佇列 (Queue):Core 0 接收到 MQTT LED 命令後,將命令字串放入佇列,供 Core 1 讀取和執行。 |
String current_led_status = "OFF"; | 紀錄 LED 當前狀態,用於 Core 0 發布狀態確認。 |
SemaphoreHandle_t xStatusMutex; | 互斥鎖:保護 current_led_status 變數。 |
byte last_UID[10] = {0}; | 儲存上次讀取的卡片 UID,用於防止重複發布,並實現 5 秒重複延遲邏輯。 |
這個程式碼是一個使用 ESP32 雙核心 (Dual-Core) 架構的專案,結合了 MFRC522 RFID 讀卡器、MQTT 網路通訊以及 LED 控制。它專門為了解決多工處理時可能發生的看門狗計時器 (WDT) 錯誤,並將網路和硬體任務分派到不同的核心上運行。
以下是程式碼的逐行說明:
I. 標頭檔引入 (Includes)
| 程式碼 | 說明 |
#include <freertos/...> | 引入 FreeRTOS 函式庫,用於支援 ESP32 的雙核心操作、任務創建、互斥鎖 (Mutex) 和佇列 (Queue) 等。 |
#include <ArduinoMqttClient.h> | 引入 MQTT 客戶端函式庫,用於連接 MQTT Broker。 |
#include <WiFi.h> | 引入 ESP32 的 Wi-Fi 函式庫。 |
#include "esp_task_wdt.h" | 【關鍵修正】 引入 ESP32 Task Watchdog Timer 相關定義。這是解決您序列埠中 task not found 錯誤的關鍵,允許我們在 setup() 中完全禁用它。 |
#include <MFRC522v2.h> 等 | 引入 MFRC522 RFID 讀卡器函式庫及相關驅動程式。 |
II. 設定與硬體初始化
| 程式碼 | 說明 |
const char* ssid = "alex9ufo"; | Wi-Fi 網路名稱。 |
const char* mqttBroker = ... | MQTT Broker (代理人) 的網址 (例如 broker.mqtt-dashboard.com)。 |
MqttClient mqttClient(wifiClient); | 建立 MQTT 客戶端物件,使用 WiFi 連線。 |
const char* topic_UID_publish = ... | 發布 (Publish) RFID UID 的主題 ( |
const char* topic_LED_subscribe = ... | 訂閱 (Subscribe) LED 控制命令的主題 ( |
const char* topic_LED_status_publish = ... | 發布 (Publish) LED 當前狀態的主題 ( |
#define RST_PIN 27 / #define SS_PIN 5 | 定義 MFRC522 讀卡器的 RST (重設) 和 SS (片選) 腳位。 |
#define LED_PIN 2 | 定義 LED 腳位 (GPIO 2)。 |
MFRC522 mfrc522{driver}; | 建立 MFRC522 讀卡器物件。 |
III. FreeRTOS 任務間通訊變數 (IPC)
| 程式碼 | 說明 |
String new_uid_to_publish = ""; | Core 1 讀取到新卡時,將 UID 暫存於此,供 Core 0 發布。 |
SemaphoreHandle_t xUidMutex; | 互斥鎖 (Mutex):保護 new_uid_to_publish,確保 Core 0 和 Core 1 同時存取時不會發生資料衝突。 |
QueueHandle_t xLedQueue; | 佇列 (Queue):Core 0 接收到 MQTT LED 命令後,將命令字串放入佇列,供 Core 1 讀取和執行。 |
String current_led_status = "OFF"; | 紀錄 LED 當前狀態,用於 Core 0 發布狀態確認。 |
SemaphoreHandle_t xStatusMutex; | 互斥鎖:保護 current_led_status 變數。 |
byte last_UID[10] = {0}; | 儲存上次讀取的卡片 UID,用於防止重複發布,並實現 5 秒重複延遲邏輯。 |
IV. Core 0 網路任務 (MQTT/控制中心) 函式
| 程式碼 | 說明 |
void connectWifi() | 連接到設定好的 Wi-Fi 網路,直到連線成功為止。 |
void connectMqtt() | 連接到 MQTT Broker,如果連線失敗則印出錯誤代碼並等待。 |
void onMqttMessage(int messageSize) | MQTT 訂閱回調函式:當收到訂閱主題 (alex9ufo/rfid/led) 的訊息時被觸發。它將收到的命令 (例如 "ON", "FLASH") 轉換為大寫,並透過 xQueueSend 傳送到 Core 1 處理。 |
void ledMqttTask(void *pvParameters) | Core 0 主任務:負責所有網路通訊。 |
| 1. 確保 Wi-Fi 和 MQTT 連線正常。 | |
2. 呼叫 mqttClient.poll() 處理連線和接收訊息。 | |
3. 發布 UID: 檢查 | |
4. 發布狀態: 檢查 | |
5. vTaskDelay(pdMS_TO_TICKS(50)):釋放 CPU 給其他任務,保持 Core 0 的系統穩定。 |
V. Core 1 硬體控制任務 (RFID/LED) 函式
| 程式碼 | 說明 |
void rfidLedControlTask(void *pvParameters) | Core 1 主任務:負責所有硬體操作和邏輯控制。 |
1. 初始化 LED 腳位和 MFRC522 讀卡器 (mfrc522.PCD_Init())。 | |
2. 處理 LED 命令: 透過 xQueueReceive 從 Core 0 接收 LED 命令。根據命令執行 ON/OFF/FLASH/TIMER 邏輯。 | |
3. 處理 LED 邏輯: 根據接收到的命令,使用 flash_timer 變數實現 LED 閃爍 (FLASH) 或定時關閉 (TIMER) 的邏輯。 | |
4. 處理 RFID 讀取: 檢查是否有新卡 (PICC_IsNewCardPresent) 並讀取序列號 (PICC_ReadCardSerial)。 | |
5. 卡片去重與計時: 判斷是新卡還是上次讀取的舊卡。新卡立即發布;舊卡則必須等待 REPEAT_DELAY_MS (5000ms) 後才允許再次發布,避免重複洗板。 | |
6. 傳送 UID: 如果滿足發布條件,將 UID 轉為字串並存入 new_uid_to_publish (使用 xUidMutex 保護),等待 Core 0 發布。 | |
String uidToHexString(...) | 輔助函式:將 RFID 讀取的 Byte 陣列 (UID) 轉換為十六進位字串,方便 MQTT 傳輸和資料庫儲存。 |
VI. 主程式設定區塊 (setup() 和 loop())
| 程式碼 | 說明 |
void setup() | 程式開始時只執行一次。 |
Serial.begin(115200); | 設定序列埠輸出速率。 |
| esp_task_wdt_deinit(); | 【最終修正的核心】 這是徹底解決 Task Watchdog Timer 錯誤的指令。它會完全禁用 ESP32 系統內部的任務看門狗,避免網路或 FreeRTOS 任務繁忙時出現錯誤重啟或序列埠報錯。 |
SPI.begin(); | 初始化 SPI 介面,供 MFRC522 使用。 |
xUidMutex = xSemaphoreCreateMutex(); 等 | 初始化 FreeRTOS 資源 (互斥鎖和佇列)。 |
xTaskCreatePinnedToCore(...) | 創建並啟動任務: |
- ledMqttTask 綁定到 Core 0:處理較慢的網路 I/O 操作。 | |
- rfidLedControlTask 綁定到 Core 1:處理即時的硬體 I/O (RFID/LED) 和控制邏輯。 | |
void loop() | 在 FreeRTOS 架構下,loop() 函式通常閒置或只包含極小的延遲。 |
vTaskDelay(1); | 讓 loop 函式維持運作並釋放給系統底層任務 (Idle Task)。 |
















沒有留言:
張貼留言