ESP32教程54/55 - 通过WiFi设置WS2812 LED灯带颜色 | SunFounder的ESP32物联网学习套件
在本教程中,我们将学习如何使用ESP32微控制器通过Wi-Fi控制WS2812 RGB LED灯带的颜色。通过使用颜色选择器,您可以从移动设备或桌面选择不同的颜色,并将该信息发送到LED灯带。该项目展示了ESP32的功能,通过网页界面实现与LED照明的无缝交互。
ESP32微控制器同时具备Wi-Fi和蓝牙功能,使其成为物联网应用的多功能选择。在本项目中,我们将专注于Wi-Fi功能来控制LED灯带。用户将能够动态选择颜色,创造视觉上引人入胜的体验。为了更清楚地了解此项目,请务必观看视频(视频中00:00处)。
硬件说明
本项目的主要组件包括ESP32微控制器和WS2812 LED灯带。ESP32是一款功能强大的微控制器,内置Wi-Fi功能,可实现无线通信和控制。
WS2812 LED灯带由可单独寻址的RGB LED组成,允许您独立设置每个LED的颜色。每个LED在单个封装内集成了控制电路和RGB LED,简化了多个LED的接线和控制。
数据手册详情
| 制造商 | Worldsemi |
|---|---|
| 零件编号 | WS2812B |
| 逻辑/IO电压 | 3.5–5.3 V |
| 电源电压 | 5 V |
| 输出电流(每通道) | 20 mA |
| 峰值电流(每通道) | 60 mA |
| PWM频率建议 | 400 Hz |
| 输入逻辑阈值 | 0.3 × VDD(低),0.7 × VDD(高) |
| 压降 / RDS(on) / 饱和 | 0.5 V |
| 热限制 | –40 至 +80 °C |
| 封装 | 5050 SMD |
| 备注 / 变体 | 提供各种长度和配置。 |
- 确保电源供应适当,以避免损坏LED。
- 在ESP32和LED灯带之间使用公共接地。
- 保持数据线短,以防止信号衰减。
- 考虑在电源两端添加电容器(1000 µF)以增强稳定性。
- 在数据线上使用电阻(470 Ω)以确保信号完整性。
接线说明

要将ESP32连接到WS2812 LED灯带,请按以下方式连接组件:首先,将LED灯带的5V引脚连接到ESP32的5V输出。接下来,将LED灯带的接地(GND)引脚连接到ESP32上的GND引脚。最后,将LED灯带的数据引脚(通常标记为DI或Data In)连接到ESP32上的GPIO 13引脚。确保所有连接牢固,以确保功能正常。
在视频中,简要提到了替代接线方法,但此处描述的设置是推荐配置,以获得最佳性能(视频中03:00处)。
代码示例与讲解
代码首先包含控制WS2812 LED灯带和设置Web服务器所需的库。LED引脚定义为LED_PIN,灯带中的LED数量通过NUM_LEDS设置。
#define LED_PIN 13 // NeoPixel LED灯带
#define NUM_LEDS 8 // LED数量
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
此代码片段初始化NeoPixel库,并在指定引脚上设置LED灯带。Adafruit_NeoPixel对象strip将用于控制LED颜色。
接下来,代码初始化Wi-Fi并设置Web服务器以处理传入请求。定义了网络的SSID和密码,使ESP32能够连接到Wi-Fi。
const char *ssid = "your_SSID";
const char *password = "your_PASSWORD";
WebServer server(80);
在此代码片段中,将your_SSID和your_PASSWORD替换为您的实际Wi-Fi凭据。此连接使ESP32能够与同一网络上的设备通信,从而实现对LED灯带的远程控制。
更改LED颜色的主要函数是setColor(),它遍历每个LED并根据选定的RGB值设置其颜色。
void setColor() {
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, valueR, valueG, valueB); // 设置第i个LED的颜色
strip.show(); // 使用新颜色更新LED灯带
delay(10); // 等待10毫秒
}
}
此函数确保灯带中的每个LED都更新为选定的颜色。延迟允许LED平滑地改变颜色。当您与网页界面交互时,将调用此函数以反映您的颜色选择。
演示 / 预期效果
当设置完成后,您应该能够通过ESP32的IP地址访问网页界面。您会看到一个颜色选择器,允许您选择任意颜色,该颜色随后会被发送到LED灯带。如果ESP32失去Wi-Fi连接,灯带会闪烁警告颜色,以指示问题(视频中14:30处)。
常见的陷阱包括接线错误,这可能导致LED不亮,或者使用错误的SSID/密码组合,导致ESP32无法连接到网络。请务必仔细检查您的连接和凭据。
视频时间戳
- 00:00 开始
- 2:01 项目介绍
- 3:09 文档
- 3:47 RGB颜色详解
- 7:47 接线
- 8:40 带WIFI的WS2812 Arduino代码详解
- 19:35 在Arduino IDE中选择ESP32开发板和COM端口
- 21:17 通过WiFi控制LED灯带演示
/*
* 通过ESP32使用WiFi控制RGB LED
*
* 完整视频说明 https://youtu.be/J_UFHk_T9aE
* 📚⬇️ 下载和资源页面 https://robojax.com/RJT687
* 作者:Ahmad Shamshiri 2023年12月18日
*
* 观看该视频的视频说明:
*
* 我将Adafruit的DHT库与ESP8266 WebServer结合在一起,两个链接如下:
* Adafruit DHT库在GitHub上:https://github.com/adafruit/DHT-sensor-library
* 以及
* ESP8266在GitHub上:https://github.com/esp8266/Arduino
*
* 版权 © 2015,Majenko Technologies
* 版权所有。
*
* 在符合以下条件的情况下,允许以源代码和二进制形式重新分发和使用,带或不带修改:
*
* 源代码的再分发必须保留上述版权声明、此条件列表以及以下免责声明。
*
* 二进制形式的再分发必须在随分发提供的文档和/或其他材料中重现上述版权声明、此条件列表以及以下免责声明。
*
* 未经特别事先书面许可,不得使用Majenko Technologies的名称或其贡献者的名称来认可或推广基于此软件的产品。
*
* 本软件由版权持有者和贡献者按“原样”提供,任何明示或暗示的担保,包括但不限于对适销性和特定用途适用性的暗示担保均被否认。在任何情况下,版权持有者或贡献者均不对因使用本软件而导致的任何直接、间接、偶然、特别、惩戒性或后果性损害负责(包括但不限于替代商品或服务的采购;使用、数据或利润的损失;或业务中断),无论因何原因,包括合同、严格责任或侵权(包括过失或其他方式)而导致,甚至在被告知可能发生此类损害的情况下。
*/
#include <Adafruit_NeoPixel.h> // 包括 Adafruit NeoPixel 库
#define LED_PIN 13 // NeoPixel LED灯条
#define NUM_LEDS 8 // LED的数量
// 创建 Adafruit_NeoPixel 类的实例
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
// LED灯带的初始颜色
int valueR = 178; // 红色范围从0到255
int valueG = 27; // 从 0 到 255 的绿色
int valueB = 84; // 蓝色范围从 0 到 255
bool showSerialData = false;
String theColorR, theColorG, theColorB;
String theColor ="ff0000";
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
const char *ssid = "dars";
const char *password = "hhhhhhhhhhh";
WebServer server(80);
void showColorPicker() {
String page = "<!DOCTYPE html>\n";
page +="<html>\n";
page +="<body>\n";
page +="<div style=\"zoom: 300%;\">\n";
page +="<h2>Robojax RGB Color picker</h2>\n";
page +="<p id=\"result\"></p>\n";
page +="<form action=\"/color\">\n";
page +=" <label for=\"favcolor\">Select your favorite color:</label>\n";
page +=" <input type=\"color\" id=\"favcolor\" name=\"favcolor\" value=\"#";
page += theColor;
page +="\"><br><br>\n";
page +=" <input type=\"submit\" value=\"Set Color\" />\n";
page +="</form> \n</div>\n";
page +="</body>\n";
page +="</html>\n";
server.send(200, "text/html", page);
}
// 从 https://stackoverflow.com/questions/44683071/convert-string-as-hex-to-hexadecimal
uint64_t StrToHex(const char* str)
{
return (uint64_t) strtoull(str, 0, 16);
}
void getColor(){
// server.send(200, "text/plain", message);
if(server.argName(0) == "favcolor")
{
String newColor = String(server.arg(0)); // 获取GET参数0并将其转换为字符串
theColor = newColor.substring(1); // 移除颜色前面的 # 符号,如 #B2a48d。
theColorR = newColor.substring(1, 3); // 从 #B2a48d 中提取 B2 作为示例
theColorG = newColor.substring(3, 5); // 从 #B2a48d 中提取 a4 作为例子
theColorB = newColor.substring(5, 7); // 从 #B2a48d 中提取 8d 作为例子
valueR = StrToHex(theColorR.c_str()); // 将字符串转换为R的十六进制
valueG = StrToHex(theColorG.c_str()); // 将字符串转换为G的十六进制
valueB = StrToHex(theColorB.c_str()); // 将字符串转换为 B 的十六进制形式
if(showSerialData)
{
Serial.print("valueR: ");
Serial.println(valueR);
Serial.print("valueG: ");
Serial.println(valueG);
Serial.print("valueB: ");
Serial.println(valueB );
}
}
showColorPicker(); // 确保颜色选择器显示。
// server.send(200, "text/plain", message);
}
void setColor()
{
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, valueR, valueG, valueB); // 将第i个LED的颜色设置为红色
strip.show(); // 更新LED灯条,使用新颜色。
delay(10); // 等待100毫秒
}
}
void noConnection()
{
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, 255, 45, 0); // 将第i个LED的颜色设置为红色
strip.show(); // 更新LED灯条,使用新颜色。
delay(50); // 等待100毫秒
}
delay(200);
for (int i = NUM_LEDS-1; i >=0; i--) {
strip.setPixelColor(i, 0, 255, 180); // 将第i个LED的颜色设置为红色
strip.show(); // 更新LED灯条,使用新颜色。
delay(50); // 等待100毫秒
}
}
void handleNotFound() {
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
void setup_wifi() {
delay(10);
// 我们首先连接到一个WiFi网络。
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// 等待连接
while (WiFi.status() != WL_CONNECTED) {
noConnection();
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("Open: http: // ");
Serial.print(WiFi.localIP());
Serial.println(" to read temperature");
if (MDNS.begin("robojaxRGB")) {
Serial.println("MDNS responder started");
}
}
void setup(void) {
Serial.begin(115200);
strip.begin(); // 初始化 NeoPixel 灯带
strip.show(); // 将初始颜色设置为黑色
setup_wifi();
server.on("/", showColorPicker); // 显示带有颜色选择器的主页
// server.on("/color", setColor);//更改WS2812 RGB LED的颜色
server.on("/color", HTTP_GET, getColor);
server.on("/inline", []() {
server.send(200, "text/plain", "this works as well");
});
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
// Robojax.com
while (WiFi.status() != WL_CONNECTED) {
setup_wifi();
}
server.handleClient();
// showColorPicker();
setColor();
delay(300); // 如果不需要经常读取,请将此更改为更大的值(1000或更多)。
// Robojax.com 代码用于 ESP32 和 DHT11 DHT22
}
Common Course Links
Common Course Files
资源与参考
尚无可用资源。
文件📁
没有可用的文件。