ESP32教程52/55 - WS2812 CheerLights MQTT全局同步与LCD | SunFounder ESP32物联网套件
在本教程中,我们将使用ESP32创建一个CheerLights项目,通过MQTT实现全球颜色同步。该项目不仅会根据其他用户的输入改变颜色,还会在LCD屏幕上显示当前颜色及其更新次数。最终成果是一个有趣的物联网功能演示,展示设备如何交互并让用户跨越距离保持连接。如需进一步说明,请观看视频(视频中00:00处)。
硬件说明
要构建此项目,您需要ESP32微控制器、WS2812 LED灯带和LCD显示屏。ESP32作为操作的核心,利用其内置的Wi-Fi功能连接互联网并接收MQTT消息。这允许根据其他用户的全局输入实时更新LED颜色。
WS2812 LED灯带是需要可寻址RGB LED项目的热门选择。每个LED可以独立控制,实现丰富的色彩显示。LCD将提供当前颜色及其更改次数的视觉确认,增强用户交互。
数据手册详情
| 制造商 | SunFounder |
|---|---|
| 零件编号 | ESP32 |
| 逻辑/IO电压 | 3.3 V |
| 电源电压 | 5 V |
| 输出电流(每通道) | 20 mA |
| 峰值电流(每通道) | 60 mA |
| PWM频率建议 | 400 Hz |
| 输入逻辑阈值 | 0.15 V(低),0.8 V(高) |
| 压降 / RDS(on) / 饱和 | 0.2 V |
| 热限制 | 85 °C |
| 封装 | ESP32模块 |
| 备注 / 变体 | 包含内置Wi-Fi和蓝牙 |
- 确保为ESP32(5 V)和WS2812灯带(5 V)提供适当的电源。
- 在ESP32和LED灯带之间使用公共接地。
- 实现适当的MQTT代理以实现颜色同步。
- 注意WS2812的数据引脚连接(根据代码为引脚14)。
- 注意LED数量;超过功率限制需要额外的电源。
接线说明


要连接组件,首先连接WS2812 LED灯带。将LED灯带的接地引脚(通常为黑色)连接到ESP32上的接地引脚。接下来,将LED灯带的VCC引脚(通常为红色)连接到ESP32上的5V输出。最后,将数据引脚(通常为黄色)连接到ESP32上的GPIO引脚14。
对于LCD,将接地引脚(通常为黑色)连接到ESP32上的接地。VCC引脚(通常为红色)应连接到5V输出。SDA引脚(通常为灰色)连接到GPIO引脚21,而SCL引脚(通常为白色)连接到GPIO引脚22。此设置允许ESP32与LCD通信并根据需要显示信息。
代码示例与讲解
在setup函数中,我们初始化LCD并连接到Wi-Fi。以下代码演示了如何定义必要的库并设置LCD:
#include
#include
LiquidCrystal_I2C lcd(0x27, 16,2); // 设置LCD地址
void setup() {
Serial.begin(115200);
lcd.init(); // 初始化LCD
lcd.backlight(); // 打开LCD背光。
}
这初始化了LCD以供使用,使其能够显示消息。下一个摘录展示了Wi-Fi连接是如何建立的:
void setup_wifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
lcdConnect(); //用于LCD
delay(500);
}
Serial.println("WiFi connected");
}
此函数建立到指定Wi-Fi网络的连接,在连接时在LCD上显示消息。最后,颜色更改逻辑在回调函数中处理:
void callback(char* topic, byte* message, unsigned int length) {
String messageTemp;
for (int i = 0; i < length; i++) {
messageTemp += (char)message[i];
}
if (String(topic) == "cheerlights") {
setColor(messageTemp);
}
}
此函数监听"cheerlights"主题上的传入消息并相应地更新颜色。完整代码加载在文章下方,请务必查看以了解完整实现。
演示 / 预期效果
项目完成后,您可以预期LED灯带会根据全局MQTT源的输入改变颜色。LCD将显示当前颜色名称及其更改次数。如果断开互联网,LCD将显示"Connecting..."(连接中...),直到重新建立连接(视频中12:30处)。
常见陷阱包括确保使用正确的数据连接引脚以及验证Wi-Fi凭据准确无误。如果SSID或密码有任何差异,ESP32将无法连接,LCD将继续显示连接消息。
视频时间戳
- 00:00 开始
- 1:59 项目介绍
- 6:16 接线说明
- 8:13 Arduino 代码说明
- 14:26 在 Arduino IDE 中选择 ESP32 开发板和 COM 端口
- 16:07 CheerLight 与 LCD 演示
/*
* 这是来自SunFounder的Examples->iot_5_cheerlight的原始代码
* 完整的视频说明 https://youtu.be/xEqmxMiF-E8
* 📚⬇️ 下载和资源页面 https://robojax.com/RJT685
*
* 我添加了LCD来显示:
* 1-颜色名称
* 2-更新颜色的次数
* 3-如果连接到wifi则在LCD上显示
* 4-如果未连接或断开连接则显示连接中
*
* 作者:Ahmad Shamshiri
* www.Robojax.com
* 2023年12月29日
*
* :ref: https://randomnerdtutorials.com/esp32-mqtt-publish-subscribe-arduino-ide/
* https://docs.sunfounder.com/projects/kepler-kit/en/latest/iotproject/5.mqtt_pub.html
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// SDA->21,SCL->22
LiquidCrystal_I2C lcd(0x27, 16,2); // 将LCD地址设置为0x27,用于16字符和2行显示。
int colorCount = 0;
int lastColor=0;
byte connected[] = {
B00001,
B00001,
B00011,
B00111,
B00111,
B01111,
B01111,
B11111
};
#include <WiFi.h>
#include <PubSubClient.h>
// #include <Wire.h>
#include <Adafruit_NeoPixel.h>
// 用您的SSID/密码组合替换下列变量
const char* ssid = "dars";
const char* password = "5152535455";
// 添加您的 MQTT 代理地址:
const char* mqtt_server = "mqtt.cheerlights.com";
const char* unique_identifier = "sunfounder-client-sdgvsasdda";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
int value = 0;
// 定义支持的CheerLights颜色及其RGB值。
String colorName[] = {"red", "pink", "green", "blue", "cyan", "white", "warmwhite", "oldlace", "purple", "magenta", "yellow", "orange"};
int colorRGB[][3] = { 255, 0, 0, // 红色
255, 192, 203, // 粉色
0, 255, 0, // 绿色
0, 0, 255, // 蓝色
0, 255, 255, // 青色
255, 255, 255, // 白色
255, 223, 223, // 暖白色
255, 223, 223, // 老花色
128, 0, 128, // 紫色
255, 0, 255, // 品红色
255, 255, 0, // 黄色
255, 165, 0}; // 橙子
// 初始化rgb灯带
#define LED_PIN 13
#define NUM_LEDS 8
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
lcd.init(); // 初始化 LCD
lcd.backlight(); // 打开LCD背光。
// wifi 默认设置
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
// rgb灯带开始
pixels.begin();
pixels.show();
}
void setup_wifi() {
delay(10);
// 我们首先连接到一个WiFi网络。
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
lcdConnect(); // 用于LCD
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// 如果在该主题上收到消息,您将检查这条消息。
// 根据消息改变输出状态。
if (String(topic) == "cheerlights") {
Serial.print("Changing color to ");
Serial.println(messageTemp);
setColor(messageTemp);
}
}
void reconnect() {
// 循环直到我们重新连接。
while (!client.connected()) {
lcdConnect();
Serial.print("Attempting MQTT connection...");
// 尝试连接
if (client.connect(unique_identifier)) {
Serial.println("connected");
// 订阅
client.subscribe("cheerlights");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// 请等5秒再重试。
delay(5000);
}
}
}
void setColor(String color) {
// 循环遍历颜色列表以查找匹配的颜色
for (int colorIndex = 0; colorIndex < 12; colorIndex++) {
if (color == colorName[colorIndex]) {
lastColor = colorIndex; // 记住最后的颜色
colorCount++; // 增加计数
// 设置条形灯带上每个NeoPixel的颜色
for (int pixel = 0; pixel < NUM_LEDS; pixel++) {
pixels.setPixelColor(pixel, pixels.Color (colorRGB [colorIndex][0], colorRGB [colorIndex][1], colorRGB [colorIndex][2]));
delay(100);
}
pixels.show();
}
}
}
void lcdConnect()
{
lcd.clear();
lcd.setCursor(0, 0); // 线 0
lcd.print("Connecting...");
lcd.setCursor(0, 1);
lcd.print("SSID:"); // 第一行
lcd.print(ssid);
}
void loop() {
lcd.clear();
if (!client.connected()) {
reconnect();
}else{
lcd.createChar(0, connected);
lcd.setCursor(15, 0);
lcd.write(byte(0));
}
client.loop();
// 第一行
lcd.setCursor(0, 0);
lcd.print("Color: ");
lcd.print(colorName[lastColor]);
// 第二排
lcd.setCursor(0, 1);
lcd.print("Changed ");
lcd.print(colorCount);
lcd.print(" times");
delay(1000); // 我们必须有延迟才能读懂显示屏。
}
Common Course Links
Common Course Files
资源与参考
-
文档ESP32 教程 52/55 - SunFounder CheerLight 文档页面docs.sunfounder.com
文件📁
没有可用的文件。