本帖最后由 lingzhiLab 于 2025-2-20 10:53 编辑
#申请原创#
零知-ESP32
使用ESP32微控制器对8 bit-2812 RGB灯带进行控制,实现了多种不同的灯光效果。实现彩虹颜色轮换函数,连续颜色变换效果。实现闪烁和颜色渐变效果,随机进行颜色闪烁。实现流水灯和呼吸灯效果,利用PWM调整亮度。
ESP32实现Web网页控制WS2812B点亮不同颜色的效果。
1、使用工具电脑、Windows系统
零知-ESP32开发板
Micro-usb线
WS2812RGB灯
2、硬件连接 零知-ESP32开发板
| WS2812B
| 5V
| VCC
| GND
| GND
| 23
| Din
| 硬件连接示意图
3、代码部分
网页控制部分 将Adafruit_NeoPixel.h和WiFi.h导入至项目中
定义一些变量用于存放WS2812RGB和网页HTTP的参数
// 引入Adafruit_NeoPixel库
#include <Adafruit_NeoPixel.h>
#include <WiFi.h>
// 连接的WS2812B的引脚,根据实际情况修改
#define PIN 23
// 灯珠数量,根据实际情况修改
#define NUM_LEDS 8
// 创建Adafruit_NeoPixel对象
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
// 用于解析HTTP GET值的字符串
String redString = "0";
String greenString = "0";
String blueString = "0";
int pos1 = 0;
int pos2 = 0;
int pos3 = 0;
int pos4 = 0;
// 存储HTTP请求的变量
String header;
// 设置web服务器端口号为80
WiFiServer server(80);
设置串口波特率为115200并打开
初始化WS2812B,配置WiFi网络或热点,ESP32连接网络
void setup() {
Serial.begin(115200);
// 初始化WS2812B
pixels.begin();
pixels.setBrightness(86);//设置亮度数值S(max=255)
pixels.show(); //灯带显示
// 连接Wi-Fi网络,这里需要修改成自己的SSID和密码
const char* ssid = "xx";
const char* password = "xx";
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status()!= WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
pixels.show();
}
配置网页,生成调色器控制像素输出到WS2812RGB上显示不同颜色 void loop() {
WiFiClient client = server.available(); // 监听传入的客户端
if (client) { // 如果有新客户端连接
String currentLine = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
header += c;
if (c == '\n') {
if (currentLine.length() == 0) {
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
// Display the HTML web page
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
client.println("<link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\">");
client.println("<script src=\"https://cdnjs.cloudflare.com/ajax/libs/jscolor/2.0.4/jscolor.min.js\"></script>");
client.println("</head><body><div class=\"container\"><div class=\"row\"><h1>ESP Color Picker</h1></div>");
client.println("<a class=\"btn btn-primary btn-lg\" href=\"#\" id=\"change_color\" role=\"button\">Change Color</a> ");
client.println("<input class=\"jscolor {onFineChange:'update(this)'}\" id=\"rgb\"></div>");
client.println("<script>function update(picker) {document.getElementById('rgb').innerHTML = Math.round(picker.rgb[0]) + ', ' + Math.round(picker.rgb[1]) + ', ' + Math.round(picker.rgb[2]);");
client.println("document.getElementById(\"change_color\").href=\"?r\" + Math.round(picker.rgb[0]) + \"g\" + Math.round(picker.rgb[1]) + \"b\" + Math.round(picker.rgb[2]) + \"&\";}</script></body></html>");
if (header.indexOf("GET /?r") >= 0) {
pos1 = header.indexOf('r');
pos2 = header.indexOf('g');
pos3 = header.indexOf('b');
pos4 = header.indexOf('&');
redString = header.substring(pos1 + 1, pos2);
greenString = header.substring(pos2 + 1, pos3);
blueString = header.substring(pos3 + 1, pos4);
// 设置WS2812B的颜色
pixels.clear();
// 将RGB值转换为整数
if (redString.startsWith("0x")) {
redString = redString.substring(2);
}
int red = strtol(redString.c_str(), NULL, 16);
// 对green和blue值也进行同样的操作
int green = strtol(greenString.c_str(), NULL, 16);
int blue = strtol(blueString.c_str(), NULL, 16);
for (int i = 0; i < NUM_LEDS; i++) {
pixels.setPixelColor(i, pixels.Color(red, green, blue));
}
pixels.show(); }
break;
} else {
currentLine = "";
}
} else if (c!= '\r') {
currentLine += c;
}
}
}
// 清空header变量
header = "";
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
不同点亮效果部分实现WS2812RGB闪烁、呼吸灯和流水灯、颜色循环点亮等效果 #include<Arduino.h>
#include <Adafruit_NeoPixel.h>
#define WS2812_PIN 23 //灯带引脚
#define WS2812_NUM 8 //灯的数量
#define Bright 255 //灯珠亮度
#define Delay_T 10 //延时时间
#define WS2812_C_RED 18 //红色
#define WS2812_C_ORANGE 54 //橙色
#define WS2812_C_YELLOW 90 //黄色
#define WS2812_C_GREEN 126 //绿色
#define WS2812_C_CYAN 162 //青色
#define WS2812_C_BIUE 198 //蓝色
#define WS2812_C_PURPIE 234 //紫色
//使用RGB模式控制ws2812类型灯带
Adafruit_NeoPixel strip(WS2812_NUM, WS2812_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
WS2812_Init();//初始化
}
void loop() {
for (uint8_t i = 0; i < 3; i++) {
//---起始灯珠---结束灯珠---灯珠颜色--------//
WS2812_ColoredLight(0, WS2812_NUM, WS2812_C_PURPIE);
delay(1000); // 延时1S
WS2812_StopAppointLight(0, WS2812_NUM);
delay(1000); // 延时1S
}
// 调用新添加的函数
WS2812_Blink(0, WS2812_NUM % 2, WS2812_C_GREEN, 5, 500);
WS2812_Fade(WS2812_NUM / 2, WS2812_NUM, WS2812_C_YELLOW, WS2812_C_RED, 100);
WS2812_RandomBlink(0, WS2812_NUM, 3, 300);
WS2812_RunningLight(0, WS2812_NUM, 100);
WS2812_BreathingLight_PWM(0, WS2812_NUM, 10);
// 彩虹灯效(注意注释中的警告)
WS2812_Start_ContinuousColoredLight(0, 16);
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] WS2812的初始化
* @param 无
* @retval 无
**/
void WS2812_Init(void)
{
//Adafruit_NeoPixel strip(LED_NUM, LED_PIN, NEO_GRB + NEO_KHZ800);
strip.begin(); //初始化灯带
strip.setBrightness(Bright);//设置亮度数值S(max=255)
strip.show(); //灯带显示
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] 点亮第n到m个彩色LED灯(慎用,会进入死循环)
* @param Start,开始的灯珠
* @param Stop,结束的灯珠
* @retval 无
**/
void WS2812_Start_ContinuousColoredLight(uint8_t Start, uint8_t Stop)//
{
uint8_t x=0,y=0;
for (uint8_t j = 0; j < 256; j++)
{
//--------灯珠颜色------起始灯珠-------结束灯珠-------//
strip.fill(Rainbow(j & 255), Start, Stop);//连续点亮多个灯珠
// Serial.println("x=");
// Serial.println(x);
//strip.setPixelColor(1, Rainbow(j & 255));//点亮一个灯珠
strip.show();
// Serial.println("y=");
// Serial.println(y);
//x++;
// y++;
delay(Delay_T);
}
//Serial.println("ok");
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] 关闭第n到m个彩色LED灯
* @param Start,开始的灯珠
* @param Stop,结束的灯珠
* @retval 无
**/
void WS2812_StopAppointLight(uint8_t Start, uint8_t Stop)
{
strip.fill(strip.Color(0, 0, 0), Start, Stop);//熄灭点亮多个灯珠
strip.show();
delay(Delay_T);
}
/**
* @brief 设置第n到m个LED灯
* @param Start,开始的灯珠
* @param Stop,结束的灯珠
* @param Color, LED的颜色
* @retval 无
**/
void WS2812_ColoredLight(uint8_t Start, uint8_t Stop, uint8_t Color)//
{
//--------灯珠颜色------起始灯珠-------结束灯珠-------//
strip.fill(Rainbow(Color), Start, Stop);
strip.show();
delay(Delay_T);
//Serial.println("ok");
}
/**
* @brief 点亮第n个LED灯,颜色自定
* @param location,第几个灯珠
* @param Colored,色号(0 <= Colored < 256)
* @retval 无
**/
void WS2812_OneLight(uint8_t location, uint8_t Colored)
{
strip.setPixelColor(location, Rainbow(Colored));//点亮一个灯珠
strip.show();
delay(Delay_T);
}
/**
* @brief 关闭所以灯
* @param 无
* @retval 无
**/
void WS2812_Clear(void)
{
strip.clear();
strip.show();
strip.fill(strip.Color(0, 0, 0), 0, WS2812_NUM);//熄灭点亮多个灯珠
// strip.show();
// delay(Delay_T);
}
/**
* @brief 颜色循环函数
* @param WheelPos,颜色
* @retval 无
**/
uint32_t Rainbow(byte WheelPos)
{
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
// 闪烁效果函数
void WS2812_Blink(uint8_t Start, uint8_t Stop, uint8_t Color, uint8_t times, uint16_t blinkDelay) {
for (uint8_t i = 0; i < times; i++) {
WS2812_ColoredLight(Start, Stop, Color);
delay(blinkDelay);
WS2812_StopAppointLight(Start, Stop);
delay(blinkDelay);
}
}
// 渐变效果函数
void WS2812_Fade(uint8_t Start, uint8_t Stop, uint8_t startColor, uint8_t endColor, uint16_t stepDelay) {
for (uint8_t i = startColor; i <= endColor; i++) {
WS2812_ColoredLight(Start, Stop, i);
delay(stepDelay);
}
for (uint8_t i = endColor; i >= startColor; i--) {
WS2812_ColoredLight(Start, Stop, i);
delay(stepDelay);
}
}
// 随机颜色闪烁函数
void WS2812_RandomBlink(uint8_t Start, uint8_t Stop, uint8_t times, uint16_t blinkDelay) {
for (uint8_t i = 0; i < times; i++) {
uint8_t randomColor = random(0, 256);
WS2812_ColoredLight(Start, Stop, randomColor);
delay(blinkDelay);
WS2812_StopAppointLight(Start, Stop);
delay(blinkDelay);
}
}
// 流水灯效果函数
void WS2812_RunningLight(uint8_t Start, uint8_t Stop, uint16_t stepDelay) {
for (uint8_t i = Start; i < Stop; i++) {
WS2812_OneLight(i, WS2812_C_PURPIE);
delay(stepDelay);
WS2812_OneLight(i, 0);
}
}
// 呼吸灯效果函数(使用PWM概念,通过改变占空比来实现亮度变化)
void WS2812_BreathingLight_PWM(uint8_t Start, uint8_t Stop, uint16_t stepDelay) {
for (int dutyCycle = 0; dutyCycle < 255; dutyCycle++) {
for (uint8_t i = Start; i < Stop; i++) {
uint32_t color = strip.Color(0, 0, dutyCycle);
strip.setPixelColor(i, Rainbow(color));
}
strip.show();
delay(stepDelay);
}
for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
for (uint8_t i = Start; i < Stop; i++) {
uint32_t color = strip.Color(0, 0, dutyCycle);
strip.setPixelColor(i, Rainbow(color));
}
strip.show();
delay(stepDelay);
}
}
4、成果展示
打开esp32的ip地址,显示调色板
点击Change Color后串口打印输出
WS2812RGB被点亮成红色
不同点亮效果的视频
https://live.csdn.net/v/436104?spm=1001.2014.3001.5501
ESP32控制WS2812RGB

|