用ESP32通过红外模块控制全色灯带(如WS2812B RGB灯带)的方案,核心是红外接收解码→指令映射→灯带驱动。以下是详细的硬件连接、代码完成及说明,基于示例基于红外遥控器(NEC协议)和WS2812B灯带。
一、硬件准备
| 组件 | 说明 |
|---|---|
| ESP32开发板 | 主控(如ESP32-WROOM-32) |
| 红外接收模块 | 如VS1838B(3.3V供电) |
| 全色灯带 | 如WS2812B(5V供电,单总线控制) |
| 红外遥控器 | 通用NEC协议遥控器(如电视遥控器) |
| 杜邦线、5V电源 | 灯带需独立5V供电,避免ESP32过载 |
二、硬件连接
1. 红外接收模块 ↔ ESP32
| 红外模块引脚 | ESP32引脚 | 说明 |
|---|---|---|
| VCC | 3.3V | 电源(不可接5V) |
| GND | GND | 共地 |
| OUT | GPIO14 | 红外信号输出(可自定义) |
2. WS2812B灯带 ↔ ESP32
| 灯带引脚 | ESP32/电源 | 说明 |
|---|---|---|
| VCC | 5V电源 | 灯带供电(需足够电流) |
| GND | GND | 共地(与ESP32和电源共地) |
| DATA | GPIO4 | 数据信号线(可自定义) |
注意:
- WS2812B工作电流较大(每颗LED约20mA),若灯带较长(如50颗以上),需单独外接5V电源,避免ESP32的USB供电不足。
- 红外模块与ESP32的GND必须共地,否则信号会受干扰。
三、软件实现(基于Arduino框架)
1. 依赖库
- IRremoteESP8266:用于红外信号接收和解码(支持NEC、RC5等协议)。
- FastLED:用于驱动WS2812B灯带(简化RGB控制)。
在Arduino IDE中安装库:
- 工具 → 管理库 → 搜索“IRremoteESP8266”和“FastLED”并安装。
2. 完整代码
#include <IRremoteESP8266.h>#include <IRrecv.h>#include <FastLED.h>// ==================== 配置参数 ====================// 红外接收配置#define IR_RECEIVE_PIN 14 // 红外信号输入引脚#define IR_TIMEOUT_MS 500 // 红外接收超时时间(ms)// 灯带配置#define LED_PIN 4 // 灯带数据引脚#define NUM_LEDS 10 // 灯带LED数量#define BRIGHTNESS 128 // 初始亮度(0-255)// 红外按键码(需根据实际遥控器修改,通过串口打印获取)#define KEY_POWER 0x00FFA25D // 电源键(开关灯带)#define KEY_RED 0x00FF629D // 红色#define KEY_GREEN 0x00FFE21D // 绿色#define KEY_BLUE 0x00FF22DD // 蓝色#define KEY_WHITE 0x00FF02FD // 白色#define KEY_BRIGHT_UP 0x00FF42BD // 亮度+#define KEY_BRIGHT_DOWN 0x00FFC23D // 亮度-#define KEY_MODE_NEXT 0x00FFA857 // 切换模式(闪烁/渐变)// =================================================// 全局变量IRrecv irrecv(IR_RECEIVE_PIN); // 红外接收对象decode_results irresults; // 红外解码结果CRGB leds[NUM_LEDS]; // 灯带对象// 状态变量bool led_on = true; // 灯带开关状态CRGB current_color = CRGB::Red; // 当前颜色uint8_t current_brightness = BRIGHTNESS; // 当前亮度uint8_t mode = 0; // 模式(0:常亮,1:闪烁,2:渐变)unsigned long mode_timer = 0; // 模式切换定时器void setup() {Serial.begin(115200);// 初始化红外接收irrecv.enableIRIn(); // 启动红外接收Serial.println("红外接收已启动,等待信号...");// 初始化灯带FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);FastLED.setBrightness(current_brightness);fill_solid(leds, NUM_LEDS, current_color); // 初始颜色FastLED.show();}void loop() {// 检测红外信号if (irrecv.decode(&irresults)) {handleIRCode(irresults.value); // 处理接收到的红外码irrecv.resume(); // 继续接收下一个信号}// 处理灯带模式handleLedMode();}/*** 处理红外按键码* @param code:红外解码后的数值*/void handleIRCode(uint32_t code) {Serial.print("收到红外码:0x");Serial.println(code, HEX);switch (code) {case KEY_POWER:led_on = !led_on; // 切换开关状态if (!led_on) fill_solid(leds, NUM_LEDS, CRGB::Black); // 关闭else fill_solid(leds, NUM_LEDS, current_color); // 开启FastLED.show();break;case KEY_RED:current_color = CRGB::Red;if (led_on) {fill_solid(leds, NUM_LEDS, current_color);FastLED.show();}break;case KEY_GREEN:current_color = CRGB::Green;if (led_on) {fill_solid(leds, NUM_LEDS, current_color);FastLED.show();}break;case KEY_BLUE:current_color = CRGB::Blue;if (led_on) {fill_solid(leds, NUM_LEDS, current_color);FastLED.show();}break;case KEY_WHITE:current_color = CRGB::White;if (led_on) {fill_solid(leds, NUM_LEDS, current_color);FastLED.show();}break;case KEY_BRIGHT_UP:current_brightness = min(current_brightness + 20, 255); // 亮度+FastLED.setBrightness(current_brightness);FastLED.show();break;case KEY_BRIGHT_DOWN:current_brightness = max(current_brightness - 20, 0); // 亮度-FastLED.setBrightness(current_brightness);FastLED.show();break;case KEY_MODE_NEXT:mode = (mode + 1) % 3; // 切换模式(0→1→2→0)break;default:Serial.println("未知按键");break;}}/*** 处理灯带模式(常亮/闪烁/渐变)*/void handleLedMode() {if (!led_on) return; // 灯关闭时不处理模式switch (mode) {case 0: // 常亮模式fill_solid(leds, NUM_LEDS, current_color);FastLED.show();break;case 1: // 闪烁模式(500ms切换一次亮灭)if (millis() - mode_timer > 500) {mode_timer = millis();static bool blink_state = false;blink_state = !blink_state;fill_solid(leds, NUM_LEDS, blink_state ? current_color : CRGB::Black);FastLED.show();}break;case 2: // 渐变模式(颜色缓慢变化)if (millis() - mode_timer > 50) { // 每50ms更新一次颜色mode_timer = millis();static uint8_t hue = 0;hue++; // 色相递增(0-255,覆盖全彩)fill_solid(leds, NUM_LEDS, CHSV(hue, 255, current_brightness)); // HSV颜色空间FastLED.show();}break;}}
四、代码说明
1. 红外接收与解码
- 使用
IRrecv库初始化红外接收引脚,通过irrecv.decode(&irresults)获取红外信号,irresults.value为解码后的32位数值(NEC协议)。 - 首次使用时,可通过串口打印
irresults.value获取遥控器各按键的编码,替换代码中KEY_*的宏定义(不同遥控器编码不同)。
2. 灯带控制
- 使用
FastLED库驱动WS2812B,addLeds<WS2812B, LED_PIN, GRB>()指定灯带型号、引脚和颜色格式(WS2812B通常为GRB)。 fill_solid()用于填充全灯带为同一颜色,setBrightness()调整亮度,show()刷新显示。
3. 功能映射
- 红外按键与灯带特性的映射关系可自定义,示例实现了:
- 电源键:开关灯带;
- 颜色键:切换红/绿/蓝/白;
- 亮度键:增减亮度;
- 模式键:切换常亮/闪烁/渐变模式。
五、测试与调试
获取红外按键码:
烧录代码后,打开串口监视器(波特率115200),按遥控器按键,串口会打印对应的红外码(如0x00FFA25D),将这些码值替换到代码的KEY_*宏中。验证灯带控制:
按不同按键,观察灯带是否按预期响应(如切换颜色、亮度变化)。若灯带无反应,检查:- 接线是否正确(尤其DATA线和GND);
- 电流不足);就是5V电源是否供电正常(灯带不亮可能
NUM_LEDS是否与实际灯带数量一致。
解除干扰困难:
若红外接收不稳定(频繁误触发),可在红外模块的VCC与GND间并联104电容(0.1μF),减少电源噪声。
六、扩展功能
- 更多颜色:通过HSV颜色空间(
CHSV)扩展更多颜色,如紫色(CHSV(160, 255, 255))。 - 自定义模式:添加呼吸灯、流水灯等模式,在
handleLedMode()中扩展case分支。 - 记忆功能:使用ESP32的NVS存储上次的颜色、亮度和模式,上电后恢复(需添加NVS操作代码)。
借助此方案,可实现用普通红外遥控器灵活控制全色灯带,适用于智能家居、氛围灯等场景。