LuoTianyi_HOLOMAIN/HOLOMAIN.ino

784 lines
24 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <SPI.h>
#include <MFRC522.h>
#include <FastLED.h>
#include <Arduino.h>
#include <driver/ledc.h>
// RFID引脚定义
#define RFID_RST_PIN 14 // RC522 复位引脚
#define RFID_SS_PIN 10 // RC522 片选引脚
#define RFID_MISO_PIN 13 // MISO 引脚
#define RFID_MOSI_PIN 12 // MOSI 引脚
#define RFID_SCK_PIN 11 // SCK 引脚
// LED定义
#define LED_PIN_1 4 // 1颗WS2812灯珠引脚
#define LED_PIN_2 5 // 160颗WS2812灯带引脚
#define LED_PIN_3 48 // 1颗WS2812灯珠引脚新增
#define LED_COUNT_1 1 // 1颗灯珠
#define LED_COUNT_2 186 // 160颗灯带
#define LED_COUNT_3 1 // 1颗灯珠新增
// PWM定义
#define PWM_PIN 6 // PWM输出引脚
#define PWM_CHANNEL 0 // PWM通道
#define PWM_FREQ 1000 // PWM频率(Hz)
#define PWM_RESOLUTION 10 // PWM分辨率(位)
#define DEFAULT_DUTY 819 // 默认占空比(80%)
// 按钮和输入引脚定义
#define BTN0_PIN 15 // 按钮0引脚
#define WAKEUP1_PIN 16 // 唤醒引脚1
#define BTN1_PIN 17 // 按钮1引脚
#define BTN2_PIN 18 // 按钮2引脚
// 任务句柄
TaskHandle_t TaskRFID, TaskLED1, TaskLED2, TaskLED3, TaskPWM, TaskBTN0, TaskWAKEUP1, TaskBTN1, TaskBTN2;
// 全局变量
MFRC522 rfid(RFID_SS_PIN, RFID_RST_PIN); // 创建RFID实例
CRGB leds1[LED_COUNT_1]; // 1颗灯珠数组
CRGB leds2[LED_COUNT_2]; // 160颗灯带数组
CRGB leds3[LED_COUNT_3]; // 1颗灯珠数组新增
CRGB frozenLeds2[LED_COUNT_2]; // 保存冻结时的颜色数据模式5专用
uint8_t frozenBrightness = 255; // 保存冻结时的亮度值,用于计算相对亮度比例
String lastCardData = ""; // 上次读取的RFID卡数据
int ledMode = 1; // 灯带模式默认为1(白色)
int pwmDuty = DEFAULT_DUTY; // PWM占空比
bool btn0State = HIGH; // 按钮0状态
bool btn0LongPress = false; // 按钮0长按标志
bool wakeup1State = LOW; // 唤醒引脚1状态
bool btn1State = LOW; // 按钮1状态
bool btn2State = LOW; // 按钮2状态
int singleLedMode = 7; // 单颗LED模式默认为7(白色)
// 灯带动画全局变量
static uint8_t rainbowHue = 0;
static int trainPos = 0;
static unsigned long lastUpdate = 0;
static const int TRAIN_LENGTH = 16; // 火车灯长度
static int trainPhase = 0; // 火车阶段0-正向出站1-正向前进2-正向进站3-反向出站4-反向前进5-反向进站
static const int VIRTUAL_LED_COUNT = LED_COUNT_2 + TRAIN_LENGTH; // 虚拟灯带长度
// LED亮度线性映射表 (0~100 → 26~255) - 最小阈值10%
// 用于将用户输入的0-100%亮度值映射到实际的PWM值
// 避免过低亮度导致LED完全不可见的问题
const uint8_t brightnessMapLinear[101] = {
0, 28, 31, 33, 36, 38, 41, 43, 46, 48, // 0-9
51, 54, 56, 59, 61, 64, 66, 69, 71, 74, // 10-19
77, 79, 82, 84, 87, 89, 92, 94, 97, 99, // 20-29
102, 105, 107, 110, 112, 115, 117, 120, 122, 125, // 30-39
128, 130, 133, 135, 138, 140, 143, 145, 148, 150, // 40-49
153, 156, 158, 161, 163, 166, 168, 171, 173, 176, // 50-59
179, 181, 184, 186, 189, 191, 194, 196, 199, 201, // 60-69
204, 207, 209, 212, 214, 217, 219, 222, 224, 227, // 70-79
230, 232, 235, 237, 240, 242, 245, 247, 250, 252, // 80-89
253, 254, 254, 254, 255, 255, 255, 255, 255, 255, // 90-99
255 // 100%
};
// 全局选择映射表
const uint8_t* brightnessMap = brightnessMapLinear;
// LED2亮度控制0-255
// 用于控制LED灯带的整体亮度影响模式1、2、4和5
// 模式3使用独立的呼吸算法基于此值计算动态亮度范围
uint8_t led2Brightness = 102; // 默认40%左右102/255≈40%
// 单颗LED颜色数组
CRGB singleLedColors[8] = {
CRGB::Black, // 0: 熄灭
CRGB::Blue, // 1: 蓝色
CRGB::Green, // 2: 绿色
CRGB::Orange, // 3: 橙色
CRGB::Red, // 4: 红色
CRGB::Purple, // 5: 紫色
CRGB::Yellow, // 6: 黄色
CRGB::White // 7: 白色
};
// RFID读取任务
void TaskRFIDcode(void* pvParameters) {
for (;;) {
// 寻找新卡片
if (!rfid.PICC_IsNewCardPresent()) {
delay(10);
continue;
}
// 验证NUID是否可读
if (!rfid.PICC_ReadCardSerial()) {
delay(10);
continue;
}
// 读取卡片数据(用户数据区)
String cardData = "";
MFRC522::MIFARE_Key key;
// 准备认证密钥
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
// 选择卡片
MFRC522::StatusCode status;
status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(rfid.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Authentication failed: "));
Serial.println(rfid.GetStatusCodeName(status));
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
delay(100);
continue;
}
// 读取数据块
byte buffer[18];
byte size = sizeof(buffer);
status = rfid.MIFARE_Read(4, buffer, &size);
if (status != MFRC522::STATUS_OK) {
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();
// 卡片数据处理
if (cardData != lastCardData && !cardData.isEmpty()) {
lastCardData = cardData;
Serial.println("SORC_" + cardData);
}
}
// 使放置在读卡区的IC卡进入休眠状态不再重复读卡
rfid.PICC_HaltA();
// 停止加密PCD
rfid.PCD_StopCrypto1();
delay(100);
}
}
// 注意以下两个函数已被TaskLEDUnifiedCode替代保留仅供参考
// 实际运行中不会被调用因为setup()中没有创建对应的任务
// LED1控制任务已废弃由TaskLEDUnifiedCode统一处理
void TaskLED1code(void* pvParameters) {
// 此函数已被废弃,不再使用
// LED1的控制已集成到TaskLEDUnifiedCode中
vTaskDelete(NULL); // 如果意外创建了此任务,立即删除
}
// LED3控制任务已废弃由TaskLEDUnifiedCode统一处理
void TaskLED3code(void* pvParameters) {
// 此函数已被废弃,不再使用
// LED3的控制已集成到TaskLEDUnifiedCode中
vTaskDelete(NULL); // 如果意外创建了此任务,立即删除
}
// PWM控制任务
void TaskPWMcode(void* pvParameters) {
for (;;) {
// 设置PWM占空比
ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty);
ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL);
delay(100);
}
}
// 按钮0检测任务
void TaskBTN0code(void* pvParameters) {
static unsigned long pressStartTime = 0;
static bool lastState = HIGH;
for (;;) {
bool currentState = digitalRead(BTN0_PIN);
// 检测下降沿(按下)
if (lastState == HIGH && currentState == LOW) {
pressStartTime = millis();
btn0State = LOW;
Serial.println("SO_BT0_HIGH");
btn0LongPress = false;
}
// 检测上升沿(释放)
else if (lastState == LOW && currentState == HIGH) {
btn0State = HIGH;
Serial.println("SO_BT0_LOW");
btn0LongPress = false;
}
// 检测长按
else if (currentState == LOW && millis() - pressStartTime >= 2000 && !btn0LongPress) {
btn0LongPress = true;
Serial.println("SO_BT0_HIGHL");
}
lastState = currentState;
delay(10);
}
}
// WAKEUP1检测任务
void TaskWAKEUP1code(void* pvParameters) {
static bool lastState = LOW;
for (;;) {
bool currentState = digitalRead(WAKEUP1_PIN);
// 检测上升沿
if (lastState == LOW && currentState == HIGH) {
wakeup1State = HIGH;
Serial.println("SO_WAKEUP1");
}
// 检测下降沿
else if (lastState == HIGH && currentState == LOW) {
wakeup1State = LOW;
Serial.println("SO_WAKEUP0");
}
lastState = currentState;
delay(10);
}
}
// 按钮1检测任务
void TaskBTN1code(void* pvParameters) {
static bool lastState = LOW;
for (;;) {
bool currentState = digitalRead(BTN1_PIN);
// 检测上升沿
if (lastState == LOW && currentState == HIGH) {
btn1State = HIGH;
Serial.println("SO_BT1_HIGH");
}
// 检测下降沿
else if (lastState == HIGH && currentState == LOW) {
btn1State = LOW;
Serial.println("SO_BT1_LOW");
}
lastState = currentState;
delay(10);
}
}
// 按钮2检测任务
void TaskBTN2code(void* pvParameters) {
static bool lastState = LOW;
for (;;) {
bool currentState = digitalRead(BTN2_PIN);
// 检测上升沿
if (lastState == LOW && currentState == HIGH) {
btn2State = HIGH;
Serial.println("SO_BT2_HIGH");
}
// 检测下降沿
else if (lastState == HIGH && currentState == LOW) {
btn2State = LOW;
Serial.println("SO_BT2_LOW");
}
lastState = currentState;
delay(10);
}
}
// 串口命令处理
void handleSerialCommand() {
static String command = "";
while (Serial.available()) {
// 先检查命令长度(新增的防护代码)
if (command.length() > 64) {
Serial.println("错误: 命令过长最大64字符");
command = ""; // 清空当前命令
while (Serial.available()) Serial.read(); // 清空串口缓冲区
continue;
}
char c = Serial.read();
if (c == '\n') {
// 处理命令
if (command.startsWith("MO_LED_")) {
String modeStr = command.substring(7);
int newMode = modeStr.toInt();
// 控制单颗LED
if (newMode >= 0 && newMode <= 7) {
singleLedMode = newMode;
Serial.print("Single LED set to mode: ");
Serial.println(newMode);
} else {
Serial.println("Invalid single LED mode command");
}
} else if (command.startsWith("MO_LEDN_")) {
String modeStr = command.substring(8);
int newMode = modeStr.toInt();
// 控制灯带只有亮度不为0时才允许
if (newMode >= 0 && newMode <= 5) {
if (led2Brightness == 0) {
Serial.println("当前亮度为0请先将亮度调整至0以上再切换显示模式");
} else {
ledMode = newMode;
// 重置火车灯状态
if (newMode == 4) {
trainPos = -TRAIN_LENGTH;
trainPhase = 0;
rainbowHue = random8();
}
// 新增切换到模式5时复制当前LED2状态和亮度
if (newMode == 5) {
memcpy(frozenLeds2, leds2, sizeof(leds2));
frozenBrightness = led2Brightness; // 保存冻结时的亮度
}
Serial.print("LED strip set to mode: ");
Serial.println(newMode);
}
} else {
Serial.println("Invalid LED strip mode command");
}
} else if (command.startsWith("MO_PWM_")) {
String dutyStr = command.substring(7);
int newDuty = dutyStr.toInt();
// 检查PWM百分比
if (newDuty == 1) {
pwmDuty = 1023; // 100%
} else if (newDuty == 0 || newDuty == 20 || newDuty == 40 || newDuty == 60 || newDuty == 80) {
pwmDuty = (newDuty * 1023) / 100; // 转换为实际占空比
} else {
Serial.println("Invalid PWM command");
}
Serial.print("PWM set to: ");
Serial.print((pwmDuty * 100) / 1023);
Serial.println("%");
}
else if (command.startsWith("MO_BRI_")) {
// 提取亮度参数(跳过"MO_BRI_"前缀)
String levelStr = command.substring(7);
levelStr.trim();
command = ""; // 清空命令缓冲区
// 空参数检查
if (levelStr.length() == 0) {
Serial.println("错误: 缺少亮度值");
return; // 终止处理
}
// 严格数字验证(拒绝非数字字符)
bool isNumeric = true;
for (char c : levelStr) {
if (!isdigit(c)) {
isNumeric = false;
break; // 发现非数字立即退出
}
}
// 非数字错误处理
if (!isNumeric) {
Serial.println("错误: 亮度值必须为整数");
return;
}
// 转换为整数并验证范围
int level = levelStr.toInt();
if (level >= 0 && level <= 100) {
// 更新亮度值映射到PWM范围
led2Brightness = brightnessMap[level]; // 使用预定义映射表
Serial.print("LED亮度: ");
Serial.print(level);
Serial.println("%");
// // 亮度为0时输出警告
// if (level == 0) {
// Serial.println("亮度已设置为0所有灯光将熄灭");
// }
} else {
Serial.println("错误: 亮度值需在0-100之间");
}
command = ""; // 清空命令
}
command = ""; // 清空命令
} else {
// 累积非换行符字符
command += c;
}
}
}
// 统一LED控制任务防闪烁优化版本
// 集中管理LED1单颗、LED2灯带、LED3强制关闭的显示逻辑
// 优化特性:
// 1. 30FPS稳定更新频率防止闪烁
// 2. 修复模式5的双重亮度衰减问题
// 3. 统一亮度处理机制
// 4. 内存优化,减少不必要的数据拷贝
// 5. 防闪烁机制确保LED显示稳定
void TaskLEDUnifiedCode(void* pvParameters) {
static unsigned long lastLEDUpdate = 0;
const unsigned long LED_UPDATE_INTERVAL = 33; // ~30FPS降低更新频率减少闪烁
for (;;) {
unsigned long currentTime = millis();
// 控制更新频率避免过度占用CPU和闪烁问题
if (currentTime - lastLEDUpdate < LED_UPDATE_INTERVAL) {
delay(5); // 增加延时,确保任务调度稳定
continue;
}
lastLEDUpdate = currentTime;
// ---- LED1 控制(单颗 LED----
if (singleLedMode >= 0 && singleLedMode <= 7) {
leds1[0] = singleLedColors[singleLedMode];
} else {
leds1[0] = CRGB::Blue;
}
// ---- LED3 控制(熄灭)----
leds3[0] = CRGB::Black;
// ---- LED2 控制(灯带)----
switch (ledMode) {
case 0: // 模式0全部熄灭关闭所有LED灯珠
fill_solid(leds2, LED_COUNT_2, CRGB::Black);
break;
case 1: // 模式1纯白色静态光亮度可通过led2Brightness调节
fill_solid(leds2, LED_COUNT_2, CHSV(0, 0, led2Brightness));
break;
case 2: // 模式2彩虹流水灯颜色沿灯带流动速度和亮度可调
for (int i = 0; i < LED_COUNT_2; i++) {
leds2[i] = CHSV(rainbowHue + i * 256 / LED_COUNT_2, 255, led2Brightness);
}
rainbowHue++;
break;
case 3: // 模式3彩虹呼吸灯优化版本缓慢变色配合呼吸效果
{
static unsigned long lastHueUpdate = 0;
static unsigned long lastBreathUpdate = 0;
static uint8_t breathingHue = 0;
static uint8_t breathPhase = 0;
unsigned long currentTime = millis();
// 每300ms更新一次色相实现非常缓慢的颜色变化
if (currentTime - lastHueUpdate > 300) {
breathingHue += 1;
lastHueUpdate = currentTime;
}
// 每30ms更新一次呼吸相位控制亮度变化节奏
if (currentTime - lastBreathUpdate > 30) {
breathPhase += 2;
lastBreathUpdate = currentTime;
}
// 计算呼吸亮度基于led2Brightness的60%-100%范围,避免过暗
uint8_t minBrightness = led2Brightness * 60 / 100;
uint8_t maxBrightness = led2Brightness;
uint8_t breathValue = map(sin8(breathPhase), 0, 255, minBrightness, maxBrightness);
for(int i = 0; i < LED_COUNT_2; i++) {
leds2[i] = CHSV(breathingHue, 200, breathValue);
}
}
break;
case 4: // 模式4彩虹火车灯模拟火车往返运行的动态效果
if (millis() - lastUpdate > 30) { // 30ms更新间隔控制火车移动速度
lastUpdate = millis();
fill_solid(leds2, LED_COUNT_2, CRGB::Black);
switch (trainPhase) {
case 0: // 阶段0正向出站火车从起点逐渐显现
for (int i = 0; i < TRAIN_LENGTH; i++) {
int pos = trainPos + i;
if (pos >= 0 && pos < LED_COUNT_2) {
uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH);
leds2[pos] = CHSV(hue, 255, led2Brightness);
}
}
trainPos++;
if (trainPos >= 0) {
trainPhase = 1; // 切换到正向前进阶段
trainPos = 0;
}
break;
case 1: // 阶段1正向前进火车完整显示并向终点移动
for (int i = 0; i < TRAIN_LENGTH; i++) {
int pos = trainPos + i;
if (pos >= 0 && pos < LED_COUNT_2) {
uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH);
leds2[pos] = CHSV(hue, 255, led2Brightness);
}
}
trainPos++;
if (trainPos >= LED_COUNT_2 - TRAIN_LENGTH) {
trainPhase = 2; // 切换到正向进站阶段
trainPos = LED_COUNT_2 - TRAIN_LENGTH;
}
break;
case 2: // 阶段2正向进站火车从尾部开始消失
for (int i = 0; i < TRAIN_LENGTH; i++) {
int displayPos = LED_COUNT_2 - 1 - i;
if (displayPos >= trainPos) {
uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH);
leds2[displayPos] = CHSV(hue, 255, led2Brightness);
}
}
trainPos++;
if (trainPos >= LED_COUNT_2) {
trainPhase = 3; // 切换到反向出站阶段
trainPos = 0;
rainbowHue += 64; // 改变彩虹颜色,增加视觉变化
}
break;
case 3: // 阶段3反向出站火车从终点逐渐显现
for (int i = 0; i < trainPos + 1; i++) {
int pos = LED_COUNT_2 - 1 - i;
if (pos >= 0) {
uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH);
leds2[pos] = CHSV(hue, 255, led2Brightness);
}
}
trainPos++;
if (trainPos >= TRAIN_LENGTH) {
trainPhase = 4; // 切换到反向前进阶段
trainPos = TRAIN_LENGTH;
}
break;
case 4: // 阶段4反向前进火车完整显示并向起点移动
for (int i = 0; i < TRAIN_LENGTH; i++) {
int pos = LED_COUNT_2 - trainPos + i;
if (pos >= 0 && pos < LED_COUNT_2) {
uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH);
leds2[pos] = CHSV(hue, 255, led2Brightness);
}
}
trainPos++;
if (trainPos >= LED_COUNT_2) {
trainPhase = 5; // 切换到反向进站阶段
trainPos = 0;
}
break;
case 5: // 阶段5反向进站火车从头部开始消失
for (int i = 0; i < TRAIN_LENGTH - trainPos; i++) {
int pos = i;
if (pos < LED_COUNT_2) {
uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH);
leds2[pos] = CHSV(hue, 255, led2Brightness);
}
}
trainPos++;
if (trainPos >= TRAIN_LENGTH) {
trainPhase = 0; // 重新开始正向出站,形成循环
trainPos = -TRAIN_LENGTH;
rainbowHue += 64; // 再次改变彩虹颜色
}
break;
}
}
break;
case 5: // 模式5冻结当前灯效保持切换时的图像但允许调节亮度内存优化版本
if (led2Brightness == 0) {
fill_solid(leds2, LED_COUNT_2, CRGB::Black); // 亮度为0时完全熄灭
} else {
// 计算相对亮度比例,避免双重衰减问题
uint16_t brightnessRatio = (uint16_t)led2Brightness * 255 / frozenBrightness;
if (brightnessRatio > 255) brightnessRatio = 255;
// 直接计算并设置像素颜色内存优化避免使用memcpy
for (int i = 0; i < LED_COUNT_2; i++) {
leds2[i].r = (frozenLeds2[i].r * brightnessRatio) >> 8;
leds2[i].g = (frozenLeds2[i].g * brightnessRatio) >> 8;
leds2[i].b = (frozenLeds2[i].b * brightnessRatio) >> 8;
}
}
break;
}
// ---- 最终统一刷新LED ----
// 添加FastLED刷新保护确保数据稳定后再显示
FastLED.show();
// ---- 稳定的延时机制 ----
// 使用固定延时确保LED显示稳定避免闪烁
delay(10); // 10ms延时确保LED数据传输完成
}
}
void setup() {
// 初始化串口
Serial.begin(115200);
Serial.println("System starting...");
// 初始化SPI总线
SPI.begin(RFID_SCK_PIN, RFID_MISO_PIN, RFID_MOSI_PIN, RFID_SS_PIN);
// 初始化RFID
rfid.PCD_Init();
Serial.println("RFID initialized.");
// 初始化LED
FastLED.addLeds<WS2812, LED_PIN_1, GRB>(leds1, LED_COUNT_1);
FastLED.addLeds<WS2812, LED_PIN_2, GRB>(leds2, LED_COUNT_2);
FastLED.addLeds<WS2812, LED_PIN_3, GRB>(leds3, LED_COUNT_3); // 新增LED3
// 初始化LED状态
fill_solid(leds1, LED_COUNT_1, singleLedColors[singleLedMode]);
fill_solid(leds2, LED_COUNT_2, CHSV(0, 0, led2Brightness)); // 初始化白色
fill_solid(leds3, LED_COUNT_3, CRGB::Black); // 强制GPIO48的灯珠熄灭
FastLED.show();
Serial.println("LED initialized.");
// 初始化PWM
// 创建LED控制器配置
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = (ledc_timer_bit_t)PWM_RESOLUTION,
.timer_num = (ledc_timer_t)PWM_CHANNEL,
.freq_hz = PWM_FREQ,
.clk_cfg = LEDC_AUTO_CLK
};
ledc_timer_config(&ledc_timer);
// 创建LED通道配置
ledc_channel_config_t ledc_channel = {
.gpio_num = PWM_PIN,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = (ledc_channel_t)PWM_CHANNEL,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = (ledc_timer_t)PWM_CHANNEL,
.duty = 0,
.hpoint = 0
};
ledc_channel_config(&ledc_channel);
// 设置初始占空比
ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty);
ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL);
Serial.println("PWM initialized.");
// 初始化输入引脚
pinMode(BTN0_PIN, INPUT_PULLUP);
pinMode(WAKEUP1_PIN, INPUT);
pinMode(BTN1_PIN, INPUT);
pinMode(BTN2_PIN, INPUT);
Serial.println("Inputs initialized.");
// 创建任务
xTaskCreatePinnedToCore(
TaskRFIDcode, /* 任务函数 */
"TaskRFID", /* 任务名称 */
4096, /* 任务栈大小 */
NULL, /* 传递给任务的参数 */
1, /* 任务优先级 */
&TaskRFID, /* 任务句柄 */
1); /* 运行在核心1上 */
xTaskCreatePinnedToCore(
TaskLEDUnifiedCode,
"TaskLEDUnified",
8192, // 建议栈大一点
NULL,
3, // 提高优先级确保LED更新不被其他任务干扰
NULL,
1);
xTaskCreatePinnedToCore(
TaskPWMcode,
"TaskPWM",
1024,
NULL,
1,
&TaskPWM,
1);
xTaskCreatePinnedToCore(
TaskBTN0code,
"TaskBTN0",
2048,
NULL,
1,
&TaskBTN0,
0);
xTaskCreatePinnedToCore(
TaskWAKEUP1code,
"TaskWAKEUP1",
2048,
NULL,
1,
&TaskWAKEUP1,
0);
xTaskCreatePinnedToCore(
TaskBTN1code,
"TaskBTN1",
2048,
NULL,
1,
&TaskBTN1,
0);
xTaskCreatePinnedToCore(
TaskBTN2code,
"TaskBTN2",
2048,
NULL,
1,
&TaskBTN2,
0);
Serial.println("Tasks created. System ready.");
}
void loop() {
// 处理串口命令
handleSerialCommand();
// 让出CPU时间
delay(1);
}