搜索代码

ESP32教程52/55 - WS2812 CheerLights MQTT全局同步与LCD | SunFounder ESP32物联网套件

ESP32教程52/55 - WS2812 CheerLights MQTT全局同步与LCD | SunFounder ESP32物联网套件

在本教程中,我们将使用ESP32创建一个CheerLights项目,通过MQTT实现全球颜色同步。该项目不仅会根据其他用户的输入改变颜色,还会在LCD屏幕上显示当前颜色及其更新次数。最终成果是一个有趣的物联网功能演示,展示设备如何交互并让用户跨越距离保持连接。如需进一步说明,请观看视频(视频中00:00处)。

esp32-52-cheer-light-lcd-main

硬件说明

要构建此项目,您需要ESP32微控制器、WS2812 LED灯带和LCD显示屏。ESP32作为操作的核心,利用其内置的Wi-Fi功能连接互联网并接收MQTT消息。这允许根据其他用户的全局输入实时更新LED颜色。

WS2812 LED灯带是需要可寻址RGB LED项目的热门选择。每个LED可以独立控制,实现丰富的色彩显示。LCD将提供当前颜色及其更改次数的视觉确认,增强用户交互。

cheeLights_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数量;超过功率限制需要额外的电源。

接线说明

ESP32-11_LCD-wiring
esp32-47-cheer-light-wiring

要连接组件,首先连接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 演示

图像

ESP32-11_LCD-wiring
ESP32-11_LCD-wiring
esp32-47-cheer-light-wiring
esp32-47-cheer-light-wiring
esp32-52-cheer-light-lcd-main
esp32-52-cheer-light-lcd-main
cheeLights_LCD
cheeLights_LCD
853-ESP32 Tutorial 52/55- CheerLight MQTT and LCD
语言: C++
/*
 * 这是来自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); // 我们必须有延迟才能读懂显示屏。







}

资源与参考

文件📁

没有可用的文件。