查看: 132|回复: 0
打印 上一主题 下一主题

[经验] 零知开源——网页控制WS2812B

[复制链接]

该用户从未签到

跳转到指定楼层
楼主
发表于 2025-2-20 10:13:07 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
分享到:
零知-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的参数

  1. // 引入Adafruit_NeoPixel库
  2. #include <Adafruit_NeoPixel.h>
  3. #include <WiFi.h>
  4. // 连接的WS2812B的引脚,根据实际情况修改
  5. #define PIN 23
  6. // 灯珠数量,根据实际情况修改
  7. #define NUM_LEDS 8

  8. // 创建Adafruit_NeoPixel对象
  9. Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

  10. // 用于解析HTTP GET值的字符串
  11. String redString = "0";
  12. String greenString = "0";
  13. String blueString = "0";
  14. int pos1 = 0;
  15. int pos2 = 0;
  16. int pos3 = 0;
  17. int pos4 = 0;
  18. // 存储HTTP请求的变量
  19. String header;

  20. // 设置web服务器端口号为80
  21. 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上显示不同颜色
  1. void loop() {
  2.     WiFiClient client = server.available();   // 监听传入的客户端
  3.     if (client) {                             // 如果有新客户端连接
  4.         String currentLine = "";
  5.         while (client.connected()) {
  6.             if (client.available()) {
  7.                 char c = client.read();
  8.                 Serial.write(c);
  9.                 header += c;
  10.                 if (c == '\n') {
  11.                     if (currentLine.length() == 0) {
  12.                         client.println("HTTP/1.1 200 OK");
  13.                                 client.println("Content-type:text/html");
  14.                                 client.println("Connection: close");
  15.                                 client.println();
  16.                                 // Display the HTML web page
  17.                                 client.println("<!DOCTYPE html><html>");
  18.                                 client.println("<head><meta name="viewport" content="width=device-width, initial-scale=1">");
  19.                                 client.println("<link rel="icon" href="data:,">");
  20.                                 client.println("<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">");
  21.                                 client.println("<script src="https://cdnjs.cloudflare.com/ajax/libs/jscolor/2.0.4/jscolor.min.js"></script>");
  22.                                 client.println("</head><body><div class="container"><div class="row"><h1>ESP Color Picker</h1></div>");
  23.                                 client.println("<a class="btn btn-primary btn-lg" href="#" id="change_color" role="button">Change Color</a> ");
  24.                                 client.println("<input class="jscolor {onFineChange:'update(this)'}" id="rgb"></div>");
  25.                                 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]);");
  26.                                 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>");
  27.                         if (header.indexOf("GET /?r") >= 0) {
  28.                             pos1 = header.indexOf('r');
  29.                             pos2 = header.indexOf('g');
  30.                             pos3 = header.indexOf('b');
  31.                             pos4 = header.indexOf('&');
  32.                             redString = header.substring(pos1 + 1, pos2);
  33.                             greenString = header.substring(pos2 + 1, pos3);
  34.                             blueString = header.substring(pos3 + 1, pos4);
  35.                             // 设置WS2812B的颜色
  36.                             pixels.clear();

  37.                             // 将RGB值转换为整数
  38.                             if (redString.startsWith("0x")) {
  39.                                 redString = redString.substring(2);
  40.                             }
  41.                             int red = strtol(redString.c_str(), NULL, 16);
  42.                             // 对green和blue值也进行同样的操作
  43.                             int green = strtol(greenString.c_str(), NULL, 16);
  44.                             int blue = strtol(blueString.c_str(), NULL, 16);

  45.                             for (int i = 0; i < NUM_LEDS; i++) {
  46.                                 pixels.setPixelColor(i, pixels.Color(red, green, blue));
  47.                             }
  48.                             pixels.show();                        }
  49.                         break;
  50.                     } else {
  51.                         currentLine = "";
  52.                     }
  53.                 } else if (c!= '\r') {
  54.                     currentLine += c;
  55.                 }
  56.             }
  57.         }
  58.         // 清空header变量
  59.         header = "";
  60.         client.stop();
  61.         Serial.println("Client disconnected.");
  62.         Serial.println("");
  63.     }
  64. }
复制代码

不同点亮效果部分

    实现WS2812RGB闪烁、呼吸灯和流水灯、颜色循环点亮等效果

  1. #include<Arduino.h>
  2. #include <Adafruit_NeoPixel.h>

  3. #define WS2812_PIN 23                  //灯带引脚
  4. #define WS2812_NUM 8                 //灯的数量
  5. #define Bright  255                     //灯珠亮度
  6. #define Delay_T 10                     //延时时间

  7. #define WS2812_C_RED        18  //红色
  8. #define WS2812_C_ORANGE     54  //橙色
  9. #define WS2812_C_YELLOW     90  //**色
  10. #define WS2812_C_GREEN      126 //绿色
  11. #define WS2812_C_CYAN       162 //青色
  12. #define WS2812_C_BIUE       198 //蓝色
  13. #define WS2812_C_PURPIE     234 //紫色

  14. //使用RGB模式控制ws2812类型灯带
  15. Adafruit_NeoPixel strip(WS2812_NUM, WS2812_PIN, NEO_GRB + NEO_KHZ800);

  16. void setup() {
  17.     WS2812_Init();//初始化
  18. }

  19. void loop() {
  20.     for (uint8_t i = 0; i < 3; i++) {
  21.         //---起始灯珠---结束灯珠---灯珠颜色--------//
  22.         WS2812_ColoredLight(0, WS2812_NUM, WS2812_C_PURPIE);
  23.         delay(1000); // 延时1S
  24.         WS2812_StopAppointLight(0, WS2812_NUM);
  25.         delay(1000); // 延时1S
  26.     }

  27.     // 调用新添加的函数
  28.     WS2812_Blink(0, WS2812_NUM % 2, WS2812_C_GREEN, 5, 500);
  29.     WS2812_Fade(WS2812_NUM / 2, WS2812_NUM, WS2812_C_YELLOW, WS2812_C_RED, 100);
  30.     WS2812_RandomBlink(0, WS2812_NUM, 3, 300);

  31.     WS2812_RunningLight(0, WS2812_NUM, 100);
  32.    
  33.     WS2812_BreathingLight_PWM(0, WS2812_NUM, 10);

  34.     // 彩虹灯效(注意注释中的警告)
  35.     WS2812_Start_ContinuousColoredLight(0, 16);
  36. }

  37. /**
  38.   * @brief  WS2812的初始化
  39.   * @param  无
  40.   * @retval 无
  41. **/

  42. void WS2812_Init(void)
  43. {
  44.     //Adafruit_NeoPixel strip(LED_NUM, LED_PIN, NEO_GRB + NEO_KHZ800);

  45.     strip.begin();              //初始化灯带
  46.     strip.setBrightness(Bright);//设置亮度数值S(max=255)
  47.     strip.show();               //灯带显示

  48. }


  49. /**
  50.   * @brief  点亮第n到m个彩色LED灯(慎用,会进入死循环)
  51.   * @param  Start,开始的灯珠
  52.   * @param  Stop,结束的灯珠
  53.   * @retval 无
  54. **/

  55. void WS2812_Start_ContinuousColoredLight(uint8_t Start, uint8_t Stop)//
  56. {
  57.   uint8_t x=0,y=0;
  58.     for (uint8_t j = 0; j < 256; j++)
  59.     {
  60.         //--------灯珠颜色------起始灯珠-------结束灯珠-------//
  61.         strip.fill(Rainbow(j & 255),  Start, Stop);//连续点亮多个灯珠
  62.        // Serial.println("x=");
  63.        // Serial.println(x);
  64.         //strip.setPixelColor(1, Rainbow(j & 255));//点亮一个灯珠
  65.         strip.show();
  66.         //  Serial.println("y=");
  67.         // Serial.println(y);
  68.         //x++;
  69.        // y++;
  70.         delay(Delay_T);
  71.     }
  72.   //Serial.println("ok");
  73. }


  74. /**
  75.   * @brief  关闭第n到m个彩色LED灯
  76.   * @param  Start,开始的灯珠
  77.   * @param  Stop,结束的灯珠
  78.   * @retval 无
  79. **/

  80. void WS2812_StopAppointLight(uint8_t Start, uint8_t Stop)
  81. {
  82.         strip.fill(strip.Color(0, 0, 0),  Start, Stop);//熄灭点亮多个灯珠
  83.         strip.show();
  84.         delay(Delay_T);
  85. }


  86. /**
  87.   * @brief  设置第n到m个LED灯
  88.   * @param  Start,开始的灯珠
  89.   * @param  Stop,结束的灯珠
  90.   * @param  Color, LED的颜色
  91.   * @retval 无
  92. **/

  93. void WS2812_ColoredLight(uint8_t Start, uint8_t Stop, uint8_t Color)//
  94. {
  95.         //--------灯珠颜色------起始灯珠-------结束灯珠-------//
  96.     strip.fill(Rainbow(Color),  Start, Stop);
  97.     strip.show();
  98.     delay(Delay_T);
  99.     //Serial.println("ok");
  100. }

  101. /**
  102.   * @brief  点亮第n个LED灯,颜色自定
  103.   * @param  location,第几个灯珠
  104.   * @param  Colored,色号(0 <= Colored < 256)
  105.   * @retval 无
  106. **/

  107. void WS2812_OneLight(uint8_t location, uint8_t Colored)
  108. {
  109.     strip.setPixelColor(location, Rainbow(Colored));//点亮一个灯珠
  110.     strip.show();
  111.     delay(Delay_T);
  112. }

  113. /**
  114.   * @brief  关闭所以灯
  115.   * @param  无
  116.   * @retval 无
  117. **/
  118. void WS2812_Clear(void)
  119. {
  120.     strip.clear();
  121.     strip.show();
  122.     strip.fill(strip.Color(0, 0, 0),  0, WS2812_NUM);//熄灭点亮多个灯珠
  123.     // strip.show();
  124.     // delay(Delay_T);
  125. }


  126. /**
  127.   * @brief  颜色循环函数
  128.   * @param  WheelPos,颜色
  129.   * @retval 无
  130. **/

  131. uint32_t Rainbow(byte WheelPos)
  132. {
  133.   WheelPos = 255 - WheelPos;
  134.   if (WheelPos < 85) {
  135.     return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  136.   }
  137.   if (WheelPos < 170) {
  138.     WheelPos -= 85;
  139.     return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  140.   }
  141.   WheelPos -= 170;
  142.   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  143. }

  144. // 闪烁效果函数
  145. void WS2812_Blink(uint8_t Start, uint8_t Stop, uint8_t Color, uint8_t times, uint16_t blinkDelay) {
  146.     for (uint8_t i = 0; i < times; i++) {
  147.         WS2812_ColoredLight(Start, Stop, Color);
  148.         delay(blinkDelay);
  149.         WS2812_StopAppointLight(Start, Stop);
  150.         delay(blinkDelay);
  151.     }
  152. }

  153. // 渐变效果函数
  154. void WS2812_Fade(uint8_t Start, uint8_t Stop, uint8_t startColor, uint8_t endColor, uint16_t stepDelay) {
  155.     for (uint8_t i = startColor; i <= endColor; i++) {
  156.         WS2812_ColoredLight(Start, Stop, i);
  157.         delay(stepDelay);
  158.     }
  159.     for (uint8_t i = endColor; i >= startColor; i--) {
  160.         WS2812_ColoredLight(Start, Stop, i);
  161.         delay(stepDelay);
  162.     }
  163. }

  164. // 随机颜色闪烁函数
  165. void WS2812_RandomBlink(uint8_t Start, uint8_t Stop, uint8_t times, uint16_t blinkDelay) {
  166.     for (uint8_t i = 0; i < times; i++) {
  167.         uint8_t randomColor = random(0, 256);
  168.         WS2812_ColoredLight(Start, Stop, randomColor);
  169.         delay(blinkDelay);
  170.         WS2812_StopAppointLight(Start, Stop);
  171.         delay(blinkDelay);
  172.     }
  173. }

  174. // 流水灯效果函数
  175. void WS2812_RunningLight(uint8_t Start, uint8_t Stop, uint16_t stepDelay) {
  176.     for (uint8_t i = Start; i < Stop; i++) {
  177.         WS2812_OneLight(i, WS2812_C_PURPIE);
  178.         delay(stepDelay);
  179.         WS2812_OneLight(i, 0);
  180.     }
  181. }

  182. // 呼吸灯效果函数(使用PWM概念,通过改变占空比来实现亮度变化)
  183. void WS2812_BreathingLight_PWM(uint8_t Start, uint8_t Stop, uint16_t stepDelay) {
  184.     for (int dutyCycle = 0; dutyCycle < 255; dutyCycle++) {
  185.         for (uint8_t i = Start; i < Stop; i++) {
  186.             uint32_t color = strip.Color(0, 0, dutyCycle);
  187.             strip.setPixelColor(i, Rainbow(color));
  188.         }
  189.         strip.show();
  190.         delay(stepDelay);
  191.     }
  192.     for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
  193.         for (uint8_t i = Start; i < Stop; i++) {
  194.             uint32_t color = strip.Color(0, 0, dutyCycle);
  195.             strip.setPixelColor(i, Rainbow(color));
  196.         }
  197.         strip.show();
  198.         delay(stepDelay);
  199.     }
  200. }       
复制代码
4、成果展示
打开esp32的ip地址,显示调色板
点击Change Color后串口打印输出
WS2812RGB被点亮成红色
不同点亮效果的视频
https://live.csdn.net/v/436104?spm=1001.2014.3001.5501

回复

举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 2/4 下一条

【预约|参会享"豪"礼】2025慕尼黑上海设备展
“2025慕尼黑上海电子生产设备展”将于2025年03月26-28日上海新国际博览中心开幕诚邀您的光临!

查看 »



手机版|小黑屋|与非网

GMT+8, 2025-4-15 13:20 , Processed in 0.112621 second(s), 19 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.5

Copyright © 2001-2024, Tencent Cloud.