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