14浏览
查看: 14|回复: 2

[项目] 【Arduino 动手做】使用 ESP32 实现互联网控制的 LED 灯带

[复制链接]
本帖最后由 驴友花雕 于 2025-6-22 20:25 编辑

使用 ESP32 控制 RGB LED 灯带,该灯带托管一个用 Arduino 框架编写的 HTTP 服务器。可在本地网络和互联网上工作。

介绍
在本教程中,我将向您展示如何使用 ESP32 和 Arduino IDE 创建由 Web 浏览器控制的 WS2812 LED 灯带。

ESP32 正在运行一个 HTTP 服务器,每次点击按钮时主题都会更改。该 HTTP 服务器可通过本地网络和互联网访问。

默认情况下有 5 个 LED 主题可用:
彩虹
白色光泽
红色光芒
只有白色
离开
但是您可以轻松添加您能想象到的任何主题(和代码:)。

在源代码中,我们使用单独的 FreeRTOS 任务来处理 HTTP 服务器和 LED 灯带主题 - 由于该代码清晰、易于理解和修改。

准备硬件
接线非常简单:

1. 将 5V 直流电源连接到 LED 灯带。本教程中使用的 LED 灯带包含 60 个像素,长度为 1 米,每米电流消耗为 3.5 A。请根据您使用的像素数量购买合适的 5V 直流电源转换器。

2. 将 ESP32 连接到 LED 灯带:

LED 灯带仅包含 3 个输入引脚:+5V、GND和Din。ESP32 由 3.3V 供电,这得益于板载 LDO 线性稳压器。将电源连接到 LDO 输入引脚 - 在我的开发板上,它被称为V5,但在您的开发板上,它的名称可能不同。将 LED 灯带数据输入引脚连接Din到G12开发板上的引脚。

准备 ESP32 固件
借助Husarnet ,LED 灯带不仅可以通过局域网控制,还可以通过互联网控制。Husarnet 提供了经过修改的 ESP32-IDF,因此您可以使用与 ESP32 标准 Arduino 软件包几乎相同的 API。Husarnet 还可以轻松与 Arduino IDE 集成。

现在打开 Arduino IDE,并按照以下说明步骤操作:

1.在Arduino IDE中安装NeoPixelBus库:

打开Tools -> Manage Libraries
搜索NeoPixelBus by Makuna
点击Install按钮
2. 安装 Husarnet IDF for ESP32:

打开File -> Preferences
在附加董事会管理器 URL 字段中添加此链接:
https://github.com/husarnet/ardu ... ge_esp32_index.json
3. 安装 ESP32 开发板

打开Tools -> Board: "..." -> Boards Manager ...
搜索esp32-husarnet
点击Install按钮
我们在此添加了一个针对 ESP32 的官方 Arduino 核心的修改版(主要涉及 IPv6 支持相关更改)- https://github.com/husarnet/arduino-esp32 。如果您之前安装过原版 Arduino 核心,建议您删除系统中所有其他适用于 ESP32 的 Arduino 核心。

4.选择ESP32开发板:

打开Tools -> Board "..."
选择ESP32 Dev Module部分ESP32 Arduino​
4. 运行演示:

克隆项目代码:
git clone https://github.com/DominikN/ESP32_ledstrip_webserver.git
修改第 9 行,设置 LED 灯带的像素数量。此代码旨在根据此处定义的像素数量自动缩放 LED 主题。
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      60
修改第 22 至 33 行以添加您的 Wi-Fi 网络凭据。在这里添加多个网络凭据非常方便——如果您将项目移动到不同的物理目的地,则无需每次都重新编程 ESP32。
  1. // Add your networks credentials here
  2. const char* ssidTab[NUM_NETWORKS] = {
  3. "wifi-network-1",
  4. "wifi-network-2",
  5. "wifi-network-3",
  6. "wifi-network-4"
  7. };
  8. const char* passwordTab[NUM_NETWORKS] = {
  9. "wifi-pass-1",
  10. "wifi-pass-2",
  11. "wifi-pass-3",
  12. "wifi-pass-4"
  13. };
复制代码

将 LED 灯带的输入数据引脚连接到G12ESP32 开发板的引脚
将项目上传到您的 ESP32 开发板(根据您的开发板,您需要按“BOOT”按钮,或在闪烁时将 Pin0 或 IO0 短接至 GND)
在 Arduino IDE 中打开Tools -> Serial Monitor并等待 ESP32 连接到 Wi-Fi 网络。几秒钟后,您应该会看到类似这样的链接(代码中串行端口的默认波特率为 115200):
[10009675] Visit
https://app.husarnet.com/husarne ... f3ee4a9xxxxyyyyzzzz
to configure the device .
复制该链接并在网络浏览器中打开它
为您的设备命名(例如 ledstrip),单击Add to network并选择Create new network- 并为其命名(例如 ledstripnet)
打开ledstripnet并左键单击ledstrip元素
选择Make the Web UI public并单击update按钮
在网络Info栏中,ledstripnet您应该会看到Web UI一个按钮,上面有一个指向控制面板的公共链接。每次通过该链接为 ESP32 开发板供电时,您都可以访问 Web UI 来控制 LED 灯带。
5.(可选)改进 - 如果您不想让任何公共链接指向您的 ESP32,您需要将您的笔记本电脑添加到“ledstripnet”网络:

在你的 Linux 设备上安装 Husarnet(https://docs.husarnet.com/getting-started/ )并将其添加到你的网络
在您的 Linux 设备上打开 Web 浏览器并将地址写入具有 8000 端口的 ESP32,例如。http://ledstrip:8000
概括
为您的 ESP32 创建可访问互联网的 Web 用户界面非常简单。该 Wi-Fi 模块集成了大量的 RAM 和闪存,结合 FreeRTOS,您可以轻松托管 HTTP 服务器来控制任何您想要控制的东西。LED 灯带就是一个​​很好的例子 :)。

我希望你会喜欢这个项目!:)

【Arduino 动手做】使用 ESP32 实现互联网控制的 LED 灯带图1

【Arduino 动手做】使用 ESP32 实现互联网控制的 LED 灯带图2

【Arduino 动手做】使用 ESP32 实现互联网控制的 LED 灯带图4

【Arduino 动手做】使用 ESP32 实现互联网控制的 LED 灯带图3

驴友花雕  中级技神
 楼主|

发表于 昨天 20:22

【Arduino 动手做】使用 ESP32 实现互联网控制的 LED 灯带

项目代码

  1. #include <WiFi.h>
  2. #include <NeoPixelBus.h>
  3. #include <Husarnet.h>
  4. // Which pin on the Arduino is connected to the NeoPixels?
  5. #define PIN            12
  6. // How many NeoPixels are attached to the Arduino?
  7. #define NUMPIXELS      60
  8. NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(NUMPIXELS, PIN);
  9. uint8_t red = 0;
  10. uint8_t green = 0;
  11. uint8_t blue = 0;
  12. int j = 0;
  13. #define NUM_NETWORKS 4
  14. // Add your networks credentials here
  15. const char* ssidTab[NUM_NETWORKS] = {
  16.   "wifi-network-1",
  17.   "wifi-network-2",
  18.   "wifi-network-3",
  19.   "wifi-network-4"
  20. };
  21. const char* passwordTab[NUM_NETWORKS] = {
  22.   "wifi-pass-1",
  23.   "wifi-pass-2",
  24.   "wifi-pass-3",
  25.   "wifi-pass-4"
  26. };
  27. HusarnetServer server(8000);
  28. String header;
  29. void setup() {
  30.   Serial.begin(115200);
  31.   strip.Begin();
  32.   strip.Show();
  33.   bool connectedSuccess = 0;
  34.   for (int i = 0; i < NUM_NETWORKS; i++) {
  35.     Serial.print("Connecting to ");
  36.     Serial.println(ssidTab[i]);
  37.     WiFi.begin(ssidTab[i], passwordTab[i]);
  38.     for (int j = 0; j < 10; j++) {
  39.       if (WiFi.status() != WL_CONNECTED) {
  40.         delay(500);
  41.         Serial.print(".");
  42.       } else {
  43.         connectedSuccess = true;
  44.       }
  45.     }
  46.     Serial.println("");
  47.     if (connectedSuccess == true) {
  48.       break;
  49.     }
  50.   }
  51.   if (connectedSuccess == false) {
  52.     Serial.println("WiFi network unreachable");
  53.     while (1) {
  54.       ;
  55.     }
  56.   }
  57.   Serial.println("");
  58.   Serial.println("WiFi connected.");
  59.   Serial.println("IP address: ");
  60.   Serial.println(WiFi.localIP());
  61.   Husarnet.selfHostedSetup("default");
  62.   // Husarnet.join(husarnetJoinCode, hostName); // alternative way, to clicking a link from a terminal. Visit app.husarnet.com -> network -> add element -> join code tab.
  63.   Husarnet.start();
  64.   server.begin();
  65.   xTaskCreate(
  66.     taskLED,          /* Task function. */
  67.     "taskLED",        /* String with name of task. */
  68.     10000,            /* Stack size in bytes. */
  69.     NULL,             /* Parameter passed as input of the task */
  70.     2,                /* Priority of the task. */
  71.     NULL);            /* Task handle. */
  72.   xTaskCreate(
  73.     taskWifi,          /* Task function. */
  74.     "taskWifi",        /* String with name of task. */
  75.     10000,            /* Stack size in bytes. */
  76.     NULL,             /* Parameter passed as input of the task */
  77.     1,                /* Priority of the task. */
  78.     NULL);            /* Task handle. */
  79. }
  80. void rainbow(int j) {
  81.   int k = 0;
  82.   int l = 0;
  83.   int m = 0;
  84.   for (int i = 0; i < NUMPIXELS; i++) {
  85.     if ( ( i >= 0 ) && ( i < NUMPIXELS * 1 / 3 ) ) {
  86.       red = 255 * k / (NUMPIXELS / 3);
  87.       green = 0;
  88.       blue = 255 - (255 * k / (NUMPIXELS / 3) );
  89.       k++;
  90.     }
  91.     if ( ( i >= NUMPIXELS * 1 / 3 ) && ( i < NUMPIXELS * 2 / 3 ) ) {
  92.       red = 255 - (255 * l / (NUMPIXELS / 3) );
  93.       green = 255 * l / (NUMPIXELS / 3);
  94.       blue = 0;
  95.       l++;
  96.     }
  97.     if ( ( i >= NUMPIXELS * 2 / 3 ) && ( i < NUMPIXELS * 3 / 3 ) ) {
  98.       red = 0;
  99.       green = 255 - (255 * m / (NUMPIXELS / 3) );
  100.       blue = 255 * m / (NUMPIXELS / 3);
  101.       m++;
  102.     }
  103.     strip.SetPixelColor((i + j) % NUMPIXELS, RgbColor(red, green, blue));
  104.   }
  105.   strip.Show();
  106.   delay(50);
  107. }
  108. void white_shine(int j) {
  109.   int k = 0;
  110.   int l = 0;
  111.   int m = 0;
  112.   for (int i = 0; i < NUMPIXELS; i++) {
  113.     if ( ( i >= 0 ) && ( i < NUMPIXELS * 1 / 3 ) ) {
  114.       red = 255 * k / (NUMPIXELS / 3);
  115.       green = 255 * k / (NUMPIXELS / 3);
  116.       blue = 255 * k / (NUMPIXELS / 3);
  117.       k++;
  118.     }
  119.     if ( ( i >= NUMPIXELS * 1 / 3 ) && ( i < NUMPIXELS * 2 / 3 ) ) {
  120.       red = 255 - (255 * l / (NUMPIXELS / 3) );
  121.       green = 255 - (255 * l / (NUMPIXELS / 3) );
  122.       blue = 255 - (255 * l / (NUMPIXELS / 3) );
  123.       l++;
  124.     }
  125.     if ( ( i >= NUMPIXELS * 2 / 3 ) && ( i < NUMPIXELS * 3 / 3 ) ) {
  126.       red = 0;
  127.       green = 0;
  128.       blue = 0;
  129.       m++;
  130.     }
  131.     Serial.printf("\r\n[R,G,B] = [%d,%d,%d]", red, green, blue);
  132.     strip.SetPixelColor((i + j) % NUMPIXELS, RgbColor(red, green, blue));
  133.   }
  134.   strip.Show();
  135.   delay(40);
  136. }
  137. void red_shine(int j) {
  138.   int k = 0;
  139.   int l = 0;
  140.   int m = 0;
  141.   
  142.   for (int i = 0; i < NUMPIXELS; i++) {
  143.     if ( ( i >= 0 ) && ( i < NUMPIXELS * 1 / 3 ) ) {
  144.       red = 255;
  145.       green = 255 - 255 * k / (NUMPIXELS / 3);
  146.       blue = 255 - 255 * k / (NUMPIXELS / 3);
  147.       k++;
  148.     }
  149.     if ( ( i >= NUMPIXELS * 1 / 3 ) && ( i < NUMPIXELS * 2 / 3 ) ) {
  150.       red = 255;
  151.       green = (255 * l / (NUMPIXELS / 3) );
  152.       blue = (255 * l / (NUMPIXELS / 3) );
  153.       l++;
  154.     }
  155.     if ( ( i >= NUMPIXELS * 2 / 3 ) && ( i < NUMPIXELS * 3 / 3 ) ) {
  156.       red = 255;
  157.       green = 255;
  158.       blue = 255;
  159.       m++;
  160.     }
  161.     strip.SetPixelColor((i + j) % NUMPIXELS, RgbColor(red, green, blue));
  162.   }
  163.   strip.Show();
  164.   delay(40);
  165. }
  166. void led_white()
  167. {
  168.   for (int i = 0; i < NUMPIXELS; i++) {
  169.     red = 255;
  170.     green = 255;
  171.     blue = 255;
  172.     strip.SetPixelColor((i + j) % NUMPIXELS, RgbColor(red, green, blue));
  173.   }
  174.   delay(5);
  175.   strip.Show();
  176. }
  177. void led_off() {
  178.   for (int i = 0; i < NUMPIXELS; i++) {
  179.     red = 0;
  180.     green = 0;
  181.     blue = 0;
  182.     strip.SetPixelColor((i + j) % NUMPIXELS, RgbColor(red, green, blue));
  183.   }
  184.   delay(100);
  185.   strip.Show();
  186. }
  187. char* getModeName(uint8_t modeNo) {
  188.   switch (modeNo) {
  189.     case 0:
  190.       return "rainbow";
  191.     case 1:
  192.       return "white shine";
  193.     case 2:
  194.       return "red shine";
  195.     case 3:
  196.       return "only white";
  197.     case 4:
  198.       return "off";
  199.   }
  200.   return "error";
  201. }
  202. uint8_t modeRGB = 0;
  203. void taskLED( void * parameter )
  204. {
  205.   while (1) {
  206.     switch (modeRGB) {
  207.       case 0:
  208.         rainbow(j++);
  209.         break;
  210.       case 1:
  211.         white_shine(j++);
  212.         break;
  213.       case 2:
  214.         red_shine(j++);
  215.         break;
  216.       case 3:
  217.         led_white();
  218.         break;
  219.       case 4:
  220.         led_off();
  221.         break;
  222.       default:
  223.         rainbow(j++);
  224.         break;
  225.     }
  226.     if (j >= NUMPIXELS) {
  227.       j = 0;
  228.     }
  229.   }
  230.   Serial.println("Ending task LED");
  231.   vTaskDelete( NULL );
  232. }
  233. void loop() {
  234.   while (1) {
  235.     delay(1000);
  236.   }
  237. }
  238. static const char* htmlHead = R"rawText(
  239. <head>
  240. <meta name="viewport" content="width=device-width, initial-scale=1">
  241. <link rel="icon" href="data:,">
  242. <style>
  243. html {
  244. font-family: Helvetica;
  245. display: inline-block;
  246. margin: 0px auto;
  247. text-align: center;
  248. }
  249. .button {
  250. background:
  251. linear-gradient(to right, #FB6060 0%, #EC305D 100%);
  252. border: none;
  253. text-decoration: none;
  254. margin: 2px;   
  255. padding: 25px 25px;
  256. width: 300px;
  257. border-radius: 12px;
  258. color: white;
  259. font-size: 30px;
  260. cursor: pointer;
  261. }
  262. </style>
  263. </head>   
  264. )rawText";
  265.   
  266. void taskWifi( void * parameter ) {
  267.   
  268.   while (1) {
  269.     HusarnetClient client = server.available();
  270.     if (client) {
  271.       Serial.println("New Client.");
  272.       String currentLine = "";
  273.       Serial.printf("connected: %d\n", (int)client.connected());
  274.       while (client.connected()) {
  275.         if (client.available()) {
  276.           char c = client.read();
  277.           //          Serial.write(c);
  278.           header += c;
  279.           if (c == '\n') {
  280.             if (currentLine.length() == 0) {
  281.               client.println("HTTP/1.1 200 OK");
  282.               client.println("Content-type:text/html");
  283.               client.println("Connection: close");
  284.               client.println();
  285.               if (header.indexOf("GET /0") >= 0) {
  286.                 modeRGB = 1;
  287.               }
  288.               if (header.indexOf("GET /1") >= 0) {
  289.                 modeRGB = 2;
  290.               }
  291.               if (header.indexOf("GET /2") >= 0) {
  292.                 modeRGB = 3;
  293.               }
  294.               if (header.indexOf("GET /3") >= 0) {
  295.                 modeRGB = 4;
  296.               }
  297.               if (header.indexOf("GET /4") >= 0) {
  298.                 modeRGB = 0;
  299.               }
  300.               // Head
  301.               client.println("<!DOCTYPE html><html>");
  302.               client.println(htmlHead);
  303.               // Body
  304.               client.println("<body><h1>ESP32 Web RGB strip control</h1>");
  305.               client.print("<p><a href="/");
  306.               client.print(modeRGB);
  307.               client.print(""><button class="button">");
  308.               client.print(getModeName(modeRGB));
  309.               client.println("</button></a></p>");
  310.               client.println("</body></html>");
  311.               client.println();
  312.               break;
  313.             } else {
  314.               currentLine = "";
  315.             }
  316.           } else if (c != '\r') {
  317.             currentLine += c;
  318.           }
  319.         }
  320.       }
  321.       header = "";
  322.       client.stop();
  323.       Serial.println("Client disconnected.");
  324.       Serial.println("");
  325.     }
  326.   }
  327. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 昨天 20:24

【Arduino 动手做】使用 ESP32 实现互联网控制的 LED 灯带

【Arduino 动手做】使用 ESP32 实现互联网控制的 LED 灯带
项目链接:https://www.hackster.io/donowak/ ... sp32-arduino-2ca8a9
项目作者:多米尼克

项目视频 :https://www.youtube.com/watch?v=qtcwGlR5Vmc
项目代码:https://www.hackster.io/code_files/228004/download
https://github.com/DominikN/ESP32_ledstrip_webserver

【Arduino 动手做】使用 ESP32 实现互联网控制的 LED 灯带图1

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail