搜索代码

ESP32教程54/55 - 通过WiFi设置WS2812 LED灯带颜色 | SunFounder的ESP32物联网学习套件

ESP32教程54/55 - 通过WiFi设置WS2812 LED灯带颜色 | SunFounder的ESP32物联网学习套件

在本教程中,我们将学习如何使用ESP32微控制器通过Wi-Fi控制WS2812 RGB LED灯带的颜色。通过使用颜色选择器,您可以从移动设备或桌面选择不同的颜色,并将该信息发送到LED灯带。该项目展示了ESP32的功能,通过网页界面实现与LED照明的无缝交互。

ESP32-54-movile-screen-main

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-12-WS2812-wiring

要将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_SSIDyour_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-54-movile-screen-1
ESP32-54-movile-screen-t-2

当设置完成后,您应该能够通过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-12-WS2812-wiring
ESP32-12-WS2812-wiring
ESP32-54-movile-screen-1
ESP32-54-movile-screen-1
ESP32-54-movile-screen-t-2
ESP32-54-movile-screen-t-2
ESP32-54-movile-screen-main
ESP32-54-movile-screen-main
855-ESP32 Tutorial 54/55- Arduino code Set WS2812 LED Strip Color over Wifi
语言: C++
/*
 * 通过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
}


资源与参考

尚无可用资源。

文件📁

没有可用的文件。