打印
[Arduino资料]

零知开源——网页控制WS2812B

[复制链接]
43|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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






使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

6

帖子

0

粉丝