更新旧开发板代码备份
This commit is contained in:
parent
87926e48a4
commit
90105a60ea
@ -35,43 +35,6 @@
|
|||||||
// 任务句柄
|
// 任务句柄
|
||||||
TaskHandle_t TaskRFID, TaskLED1, TaskLED2, TaskLED3, TaskPWM, TaskBTN0, TaskWAKEUP1, TaskBTN1, TaskBTN2;
|
TaskHandle_t TaskRFID, TaskLED1, TaskLED2, TaskLED3, TaskPWM, TaskBTN0, TaskWAKEUP1, TaskBTN1, TaskBTN2;
|
||||||
|
|
||||||
// 双串口架构:
|
|
||||||
// - Serial = USB-Serial-JTAG (USB2 口),连 Windows 做调试日志
|
|
||||||
// - SerialLinux = UART0 (CH343/USB1 口),连 Linux 开发板接收业务数据
|
|
||||||
// UART0 默认引脚:TX=GPIO43、RX=GPIO44(对应 CH343P 的 RXD/TXD)
|
|
||||||
HardwareSerial SerialLinux(0);
|
|
||||||
|
|
||||||
// Serial 输出互斥锁:防止多任务并发写串口导致数据交错/截断
|
|
||||||
SemaphoreHandle_t serialMutex = NULL;
|
|
||||||
|
|
||||||
// 带互斥保护的双串口输出:同时发到 USB CDC (Windows) 和 UART0 (Linux)
|
|
||||||
// 调用方:RFID 任务发 SORC_xxx,按键任务发 SO_xxx
|
|
||||||
// 机制:1) 互斥锁避免多任务交错 2) 两个串口并发传输 3) flush 等待传输完成
|
|
||||||
void serialPrintlnSafe(const String& msg) {
|
|
||||||
if (serialMutex && xSemaphoreTake(serialMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
|
|
||||||
// ---- 发到 USB CDC (Windows 调试) ----
|
|
||||||
// 等待 TX 缓冲区有足够空间,避免 USB CDC 缓冲区满导致截断(最多等 50ms)
|
|
||||||
size_t needed = msg.length() + 2;
|
|
||||||
uint32_t waitStart = millis();
|
|
||||||
while ((size_t)Serial.availableForWrite() < needed && (millis() - waitStart) < 50) {
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(2));
|
|
||||||
}
|
|
||||||
Serial.println(msg);
|
|
||||||
Serial.flush();
|
|
||||||
|
|
||||||
// ---- 发到 UART0 (Linux 业务) ----
|
|
||||||
// UART0 硬件有独立 128 字节 FIFO,115200 波特率下发送 12 字节约 1ms,几乎不阻塞
|
|
||||||
SerialLinux.println(msg);
|
|
||||||
SerialLinux.flush();
|
|
||||||
|
|
||||||
xSemaphoreGive(serialMutex);
|
|
||||||
} else {
|
|
||||||
// 拿不到锁的降级路径(正常情况下几乎不触发)
|
|
||||||
Serial.println(msg);
|
|
||||||
SerialLinux.println(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 全局变量
|
// 全局变量
|
||||||
MFRC522 rfid(RFID_SS_PIN, RFID_RST_PIN); // 创建RFID实例
|
MFRC522 rfid(RFID_SS_PIN, RFID_RST_PIN); // 创建RFID实例
|
||||||
CRGB leds1[LED_COUNT_1]; // 1颗灯珠数组
|
CRGB leds1[LED_COUNT_1]; // 1颗灯珠数组
|
||||||
@ -170,12 +133,11 @@ void TaskRFIDcode(void* pvParameters) {
|
|||||||
MFRC522::StatusCode status;
|
MFRC522::StatusCode status;
|
||||||
status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(rfid.uid));
|
status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(rfid.uid));
|
||||||
if (status != MFRC522::STATUS_OK) {
|
if (status != MFRC522::STATUS_OK) {
|
||||||
// 调试日志用普通 Serial.println:失败频率较高时,避免 flush 阻塞拖慢 RFID 响应
|
Serial.print(F("Authentication failed: "));
|
||||||
// 偶尔截断可接受(Linux 端用正则 ^SORC_HA\d+$ 过滤业务数据即可)
|
Serial.println(rfid.GetStatusCodeName(status));
|
||||||
Serial.println(String("Authentication failed: ") + rfid.GetStatusCodeName(status));
|
|
||||||
rfid.PICC_HaltA();
|
rfid.PICC_HaltA();
|
||||||
rfid.PCD_StopCrypto1();
|
rfid.PCD_StopCrypto1();
|
||||||
delay(30); // 从 100ms 降到 30ms,提升刷卡响应速度
|
delay(100);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,47 +146,23 @@ void TaskRFIDcode(void* pvParameters) {
|
|||||||
byte size = sizeof(buffer);
|
byte size = sizeof(buffer);
|
||||||
status = rfid.MIFARE_Read(4, buffer, &size);
|
status = rfid.MIFARE_Read(4, buffer, &size);
|
||||||
if (status != MFRC522::STATUS_OK) {
|
if (status != MFRC522::STATUS_OK) {
|
||||||
Serial.println(String("Reading failed: ") + rfid.GetStatusCodeName(status));
|
Serial.print(F("Reading failed: "));
|
||||||
rfid.PICC_HaltA();
|
Serial.println(rfid.GetStatusCodeName(status));
|
||||||
rfid.PCD_StopCrypto1();
|
} else {
|
||||||
delay(30); // 从 100ms 降到 30ms
|
// 转换为ASCII字符串
|
||||||
continue;
|
for (byte i = 0; i < 16; i++) {
|
||||||
}
|
if (buffer[i] >= 32 && buffer[i] <= 126) { // 可打印ASCII字符
|
||||||
|
cardData += (char)buffer[i];
|
||||||
// 转换为ASCII字符串
|
}
|
||||||
for (byte i = 0; i < 16; i++) {
|
|
||||||
if (buffer[i] >= 32 && buffer[i] <= 126) { // 可打印ASCII字符
|
|
||||||
cardData += (char)buffer[i];
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 移除空白字符
|
// 移除空白字符
|
||||||
cardData.trim();
|
cardData.trim();
|
||||||
|
|
||||||
// 卡片数据格式校验:规则 "HA" + 阿拉伯数字
|
// 卡片数据处理
|
||||||
// 过滤掉卡片读取异常或数据损坏的情况,避免发送无效数据给 Linux
|
if (cardData != lastCardData && !cardData.isEmpty()) {
|
||||||
auto isValidCardData = [](const String& d) -> bool {
|
lastCardData = cardData;
|
||||||
if (d.length() < 3) return false; // 至少 "HA" + 1 位数字
|
Serial.println("SORC_" + cardData);
|
||||||
if (!d.startsWith("HA")) return false; // 必须以 HA 开头
|
|
||||||
for (size_t i = 2; i < d.length(); i++) {
|
|
||||||
if (!isdigit(d[i])) return false; // HA 后面必须全是数字
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 3 秒去重窗口:同一张卡 3 秒内只发送一次,超过后允许重发
|
|
||||||
// 切换到不同卡立即发送
|
|
||||||
static String lastSentCard = "";
|
|
||||||
static unsigned long lastSentTime = 0;
|
|
||||||
const unsigned long DUPLICATE_WINDOW_MS = 3000;
|
|
||||||
|
|
||||||
if (!cardData.isEmpty() && isValidCardData(cardData)) {
|
|
||||||
unsigned long now = millis();
|
|
||||||
bool isDuplicate = (cardData == lastSentCard) && (now - lastSentTime < DUPLICATE_WINDOW_MS);
|
|
||||||
if (!isDuplicate) {
|
|
||||||
serialPrintlnSafe("SORC_" + cardData);
|
|
||||||
lastSentCard = cardData;
|
|
||||||
lastSentTime = now;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,19 +216,19 @@ void TaskBTN0code(void* pvParameters) {
|
|||||||
if (lastState == HIGH && currentState == LOW) {
|
if (lastState == HIGH && currentState == LOW) {
|
||||||
pressStartTime = millis();
|
pressStartTime = millis();
|
||||||
btn0State = LOW;
|
btn0State = LOW;
|
||||||
serialPrintlnSafe("SO_BT0_HIGH");
|
Serial.println("SO_BT0_HIGH");
|
||||||
btn0LongPress = false;
|
btn0LongPress = false;
|
||||||
}
|
}
|
||||||
// 检测上升沿(释放)
|
// 检测上升沿(释放)
|
||||||
else if (lastState == LOW && currentState == HIGH) {
|
else if (lastState == LOW && currentState == HIGH) {
|
||||||
btn0State = HIGH;
|
btn0State = HIGH;
|
||||||
serialPrintlnSafe("SO_BT0_LOW");
|
Serial.println("SO_BT0_LOW");
|
||||||
btn0LongPress = false;
|
btn0LongPress = false;
|
||||||
}
|
}
|
||||||
// 检测长按
|
// 检测长按
|
||||||
else if (currentState == LOW && millis() - pressStartTime >= 2000 && !btn0LongPress) {
|
else if (currentState == LOW && millis() - pressStartTime >= 2000 && !btn0LongPress) {
|
||||||
btn0LongPress = true;
|
btn0LongPress = true;
|
||||||
serialPrintlnSafe("SO_BT0_HIGHL");
|
Serial.println("SO_BT0_HIGHL");
|
||||||
}
|
}
|
||||||
|
|
||||||
lastState = currentState;
|
lastState = currentState;
|
||||||
@ -308,12 +246,12 @@ void TaskWAKEUP1code(void* pvParameters) {
|
|||||||
// 检测上升沿
|
// 检测上升沿
|
||||||
if (lastState == LOW && currentState == HIGH) {
|
if (lastState == LOW && currentState == HIGH) {
|
||||||
wakeup1State = HIGH;
|
wakeup1State = HIGH;
|
||||||
serialPrintlnSafe("SO_WAKEUP1");
|
Serial.println("SO_WAKEUP1");
|
||||||
}
|
}
|
||||||
// 检测下降沿
|
// 检测下降沿
|
||||||
else if (lastState == HIGH && currentState == LOW) {
|
else if (lastState == HIGH && currentState == LOW) {
|
||||||
wakeup1State = LOW;
|
wakeup1State = LOW;
|
||||||
serialPrintlnSafe("SO_WAKEUP0");
|
Serial.println("SO_WAKEUP0");
|
||||||
}
|
}
|
||||||
|
|
||||||
lastState = currentState;
|
lastState = currentState;
|
||||||
@ -331,12 +269,12 @@ void TaskBTN1code(void* pvParameters) {
|
|||||||
// 检测上升沿
|
// 检测上升沿
|
||||||
if (lastState == LOW && currentState == HIGH) {
|
if (lastState == LOW && currentState == HIGH) {
|
||||||
btn1State = HIGH;
|
btn1State = HIGH;
|
||||||
serialPrintlnSafe("SO_BT1_HIGH");
|
Serial.println("SO_BT1_HIGH");
|
||||||
}
|
}
|
||||||
// 检测下降沿
|
// 检测下降沿
|
||||||
else if (lastState == HIGH && currentState == LOW) {
|
else if (lastState == HIGH && currentState == LOW) {
|
||||||
btn1State = LOW;
|
btn1State = LOW;
|
||||||
serialPrintlnSafe("SO_BT1_LOW");
|
Serial.println("SO_BT1_LOW");
|
||||||
}
|
}
|
||||||
|
|
||||||
lastState = currentState;
|
lastState = currentState;
|
||||||
@ -354,12 +292,12 @@ void TaskBTN2code(void* pvParameters) {
|
|||||||
// 检测上升沿
|
// 检测上升沿
|
||||||
if (lastState == LOW && currentState == HIGH) {
|
if (lastState == LOW && currentState == HIGH) {
|
||||||
btn2State = HIGH;
|
btn2State = HIGH;
|
||||||
serialPrintlnSafe("SO_BT2_HIGH");
|
Serial.println("SO_BT2_HIGH");
|
||||||
}
|
}
|
||||||
// 检测下降沿
|
// 检测下降沿
|
||||||
else if (lastState == HIGH && currentState == LOW) {
|
else if (lastState == HIGH && currentState == LOW) {
|
||||||
btn2State = LOW;
|
btn2State = LOW;
|
||||||
serialPrintlnSafe("SO_BT2_LOW");
|
Serial.println("SO_BT2_LOW");
|
||||||
}
|
}
|
||||||
|
|
||||||
lastState = currentState;
|
lastState = currentState;
|
||||||
@ -382,8 +320,6 @@ void handleSerialCommand() {
|
|||||||
|
|
||||||
char c = Serial.read();
|
char c = Serial.read();
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
// 去掉命令末尾可能的 \r,兼容不同行尾符设置(\n 或 \r\n)
|
|
||||||
command.trim();
|
|
||||||
// 处理命令
|
// 处理命令
|
||||||
if (command.startsWith("MO_LED_")) {
|
if (command.startsWith("MO_LED_")) {
|
||||||
String modeStr = command.substring(7);
|
String modeStr = command.substring(7);
|
||||||
@ -489,13 +425,6 @@ void handleSerialCommand() {
|
|||||||
}
|
}
|
||||||
command = ""; // 清空命令
|
command = ""; // 清空命令
|
||||||
}
|
}
|
||||||
// 软复位命令:串口发送 "RESET" 触发 ESP32 重启
|
|
||||||
else if (command == "RESET") {
|
|
||||||
Serial.println("System resetting...");
|
|
||||||
Serial.flush(); // 等待串口数据发送完成
|
|
||||||
delay(100); // 留时间让串口打印完
|
|
||||||
ESP.restart(); // 触发软复位
|
|
||||||
}
|
|
||||||
|
|
||||||
command = ""; // 清空命令
|
command = ""; // 清空命令
|
||||||
} else {
|
} else {
|
||||||
@ -518,9 +447,7 @@ void handleSerialCommand() {
|
|||||||
// 5. 防闪烁机制,确保LED显示稳定
|
// 5. 防闪烁机制,确保LED显示稳定
|
||||||
void TaskLEDUnifiedCode(void* pvParameters) {
|
void TaskLEDUnifiedCode(void* pvParameters) {
|
||||||
static unsigned long lastLEDUpdate = 0;
|
static unsigned long lastLEDUpdate = 0;
|
||||||
// 20FPS 更新频率:兼顾视觉流畅度和 RFID 稳定性
|
const unsigned long LED_UPDATE_INTERVAL = 33; // ~30FPS,降低更新频率减少闪烁
|
||||||
// 每秒 20 次 WS2812 传输(每次 ~5.6ms 关中断),相比 30FPS 减少 33% 干扰窗口
|
|
||||||
const unsigned long LED_UPDATE_INTERVAL = 50;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
unsigned long currentTime = millis();
|
unsigned long currentTime = millis();
|
||||||
@ -722,20 +649,9 @@ void TaskLEDUnifiedCode(void* pvParameters) {
|
|||||||
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// 初始化 USB CDC 串口(Windows 调试)
|
// 初始化串口
|
||||||
// 增大 TX 缓冲区到 4KB:防止多任务并发写串口时 USB CDC 默认缓冲区溢出导致数据截断
|
|
||||||
Serial.setTxBufferSize(4096);
|
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
|
||||||
// 初始化 UART0(CH343/USB1 → Linux 业务通讯)
|
|
||||||
// 默认引脚:TX=GPIO43、RX=GPIO44,波特率与 Linux 端保持一致
|
|
||||||
SerialLinux.begin(115200);
|
|
||||||
|
|
||||||
// 创建 Serial 输出互斥锁
|
|
||||||
serialMutex = xSemaphoreCreateMutex();
|
|
||||||
|
|
||||||
Serial.println("System starting...");
|
Serial.println("System starting...");
|
||||||
SerialLinux.println("System starting...");
|
|
||||||
|
|
||||||
// 初始化SPI总线
|
// 初始化SPI总线
|
||||||
SPI.begin(RFID_SCK_PIN, RFID_MISO_PIN, RFID_MOSI_PIN, RFID_SS_PIN);
|
SPI.begin(RFID_SCK_PIN, RFID_MISO_PIN, RFID_MOSI_PIN, RFID_SS_PIN);
|
||||||
@ -793,15 +709,14 @@ void setup() {
|
|||||||
Serial.println("Inputs initialized.");
|
Serial.println("Inputs initialized.");
|
||||||
|
|
||||||
// 创建任务
|
// 创建任务
|
||||||
// TaskRFID 放 Core 0:避开 Core 1 上 WS2812 bit-banging 关中断窗口,SPI 通讯更稳定
|
|
||||||
xTaskCreatePinnedToCore(
|
xTaskCreatePinnedToCore(
|
||||||
TaskRFIDcode, /* 任务函数 */
|
TaskRFIDcode, /* 任务函数 */
|
||||||
"TaskRFID", /* 任务名称 */
|
"TaskRFID", /* 任务名称 */
|
||||||
4096, /* 任务栈大小 */
|
4096, /* 任务栈大小 */
|
||||||
NULL, /* 传递给任务的参数 */
|
NULL, /* 传递给任务的参数 */
|
||||||
2, /* 任务优先级(提高到 2,避免被按键任务频繁抢占)*/
|
1, /* 任务优先级 */
|
||||||
&TaskRFID, /* 任务句柄 */
|
&TaskRFID, /* 任务句柄 */
|
||||||
0); /* 运行在核心0上(与 LED 任务物理隔离)*/
|
1); /* 运行在核心1上 */
|
||||||
|
|
||||||
xTaskCreatePinnedToCore(
|
xTaskCreatePinnedToCore(
|
||||||
TaskLEDUnifiedCode,
|
TaskLEDUnifiedCode,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user