ESP32 教學 52/55 - WS2812 CheerLights MQTT 全球同步連 LCD | SunFounder ESP32 IoT 套件
喺呢個教學入面,我哋會用ESP32整一個CheerLights項目,透過MQTT令顏色全球同步。呢個項目唔單止會根據其他用戶嘅輸入嚟轉顏色,仲會喺LCD屏幕上面顯示而家嘅顏色同埋佢更新咗幾多次。最後嘅成果係一個有趣嘅IoT能力示範,展示裝置點樣互動同埋令用戶喺唔同距離都可以保持聯繫。想再清楚啲嘅話,可以睇吓條片(片入面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 broker嚟做顏色同步。
- 留意WS2812嘅數據引腳連接(根據程式碼係引腳14)。
- 要小心LED嘅數量;超過功率限制就需要額外電源。
接線指示


要接線啲零件,首先連接WS2812 LED燈帶。將燈帶嘅接地引腳(通常係黑色)連去ESP32嘅接地引腳。跟住,將燈帶嘅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); // set the LCD address
void setup() {
Serial.begin(115200);
lcd.init(); // initialize the lcd
lcd.backlight(); // Turns on the LCD backlight.
}
咁就初始化咗LCD嚟用,等佢可以顯示訊息。下一段摘錄示範點樣建立Wi-Fi連接:
void setup_wifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
lcdConnect(); //for LCD
delay(500);
}
Serial.println("WiFi connected");
}
呢個函數建立同指定Wi-Fi網絡嘅連接,連接期間會喺LCD上面顯示訊息。最後,顏色轉換嘅邏輯喺callback函數入面處理:
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 feed嘅輸入嚟轉顏色。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 嘅示範
/*********
This is the origianl code from Examples->iot_5_cheerlight of SunFounder
full video instrucions https://youtu.be/xEqmxMiF-E8
📚⬇️ Download and resource page https://robojax.com/RJT685
I have added LCD to display:
1-Color name
2-Count the number of times the color is updated
3-Showon LCD if wifi is connected
4-Show connecting if not connected or disconnected
Written by Ahmad Shamshiri
www.Robojax.com
Dec 29, 2023
: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); // set the LCD address to 0x27 for a 16 chars and 2 line display
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>
// Replace the next variables with your SSID/Password combination
const char* ssid = "dars";
const char* password = "5152535455";
// Add your MQTT Broker address:
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;
// Define the supported CheerLights colors and their RGB values
String colorName[] = {"red", "pink", "green", "blue", "cyan", "white", "warmwhite", "oldlace", "purple", "magenta", "yellow", "orange"};
int colorRGB[][3] = { 255, 0, 0, // "red"
255, 192, 203, // "pink"
0, 255, 0, // "green"
0, 0, 255, // "blue"
0, 255, 255, // "cyan"
255, 255, 255, // "white"
255, 223, 223, // "warmwhite"
255, 223, 223, // "oldlace"
128, 0, 128, // "purple"
255, 0, 255, // "magenta"
255, 255, 0, // "yellow"
255, 165, 0}; // "orange"
// init rgb strip
#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();// initialize the lcd
lcd.backlight(); // Turns on the LCD backlight.
// wifi default settings
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
// rgb strip begin
pixels.begin();
pixels.show();
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
lcdConnect();//for 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 a message is received on the topic, you will check this message.
// Changes the output state according to the message
if (String(topic) == "cheerlights") {
Serial.print("Changing color to ");
Serial.println(messageTemp);
setColor(messageTemp);
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
lcdConnect();
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(unique_identifier)) {
Serial.println("connected");
// Subscribe
client.subscribe("cheerlights");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setColor(String color) {
// Loop through the list of colors to find the matching color
for (int colorIndex = 0; colorIndex < 12; colorIndex++) {
if (color == colorName[colorIndex]) {
lastColor = colorIndex;//remeber the last color
colorCount++;//increment the count
// Set the color of each NeoPixel on the strip
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); //line 0
lcd.print("Connecting...");
lcd.setCursor(0, 1);
lcd.print("SSID:"); //line 1
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();
//first row
lcd.setCursor(0, 0);
lcd.print("Color: ");
lcd.print(colorName[lastColor]);
//second row
lcd.setCursor(0, 1);
lcd.print("Changed ");
lcd.print(colorCount);
lcd.print(" times");
delay(1000);//we must have delay to able to read the display
}
Common Course Links
Common Course Files
資源與參考資料
-
文件记录ESP32 Tutorial 52/55 - SunFounder doc page for CheerLightdocs.sunfounder.com
文件📁
冇文件可用。