亲,“电路城”已合并升级到更全、更大、更强的「新与非网」。点击查看「新与非网」

本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页

基于ESP32的LED相机灯

发布时间:2021-09-17
分享到:

基于ESP32的LED相机灯

发布时间:2021-09-17
分享到:

我的视频需要更好的照明。所以我想我会抓住机会自己做。目标是在相机的两侧各有两个面板,以便照明更加均匀。

我认为这只是这个项目的第一部分,但正如 Zack Freedman 曾经说过的“如果它成功了,它就完成了”或类似的东西,所以我想我会与大家分享。现在,面板是通过 WiFi 控制的。我有 4 种预设颜色,可以随意添加、修改或扩展此项目。

如果您有任何问题或任何建议,请告诉我。

零件清单:

  • ESP32
  • 8x8 可寻址 LED 面板
  • 3/8" 销钉
  • 案件
  • 金属丝
  • 焊接
  • 硬件
  • (4)M3x18
  • (3)M3x8
  • (8)M3x6
  • 热胶
  • 强力胶

工具:

  • 烙铁
  • 3D打印机
  • USB电缆
  • 剥线钳
  • 线切割机

第 1 步:打印外壳

我为这些灯板设计并打印了一个外壳。它安装在我的相机顶部。以下是我使用的所有打印部件:https://www.thingiverse.com/thing:4949634

所以开始打印外壳,这样当你准备好时,你可以把整个部件连接在在一起。

除了用透明打印的封面外,我用黑色打印了所有部分。你也可以使用白色,但我认为这会给灯光带来更蓝的色调。您也可以使用不同的浅色灯丝,但它会使面板产生的光着色。

第 2 步:接线

为了将它们放在一起,我移除了面板随附的电线以及 ESP32 上的所有引脚。然后连接可以从控制板连接到灯板的新电线。

从 ESP32 运行到 DIN/GND/5V 侧的第一个面板。然后从 DOUT/GND/5V 到第二个面板上的 DIN/GND/5V。

我附上了一个接线图来帮助解决这个问题。

第 3 步:代码

我已将完整代码附加到此步骤,在下一步中,我将更详细地介绍它的作用和工作方式。

这里需要注意的是,要使用 ESP32,您需要将其添加到 Arduino IDE。这是我添加时使用的教程的链接

网页的基础来自本教程

我将更详细地介绍下一步中的某些部分。

#include "FastLED.h"
#include "WiFi.h"

//Define Pins
#define LED_PIN 13
#define NUM_LEDS 128
#define BRIGHTNESS 64     //used later but not implimented in the code for adjustment
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
#define UPDATES_PER_SECOND 100;

//Define Web Page
const char* ssid = "Network Name";
const char* password = "Network Password";
String header;
WiFiServer server(80);


//Define Arrays
float theaturePB[6] = {1,.5,.5,.5,.5,1};
float BRed[6] = {1,.25,.3,.3,.25,1};
float white[6] = {1,1,1,1,1,1};
float amber[6] = {0.5,1,1,0.5,1,1};

String THPBstate = "off";
String BRedstate = "off";
String whitestate = "off";
String amberstate = "off";
String blackoutstate = "on";

void setup(){
  Serial.begin(115200);
  delay(3000);
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);

  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  while(WiFi.status() != WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  server.begin();
}

void loop(){
  WiFiClient client = server.available();
  if(client){
    String currentLine = "";
    while (client.available()){
      if(client.available()){
        char c = client.read();
        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();
            if(header.indexOf("GET /THPB/on") >= 0) {
              THPBstate = "on";
              BRedstate = "off";
              whitestate = "off";
              amberstate = "off";
              blackoutstate = "off";
              update(theaturePB,1);
            }else if(header.indexOf("GET /BRed/on") >= 0) {
              THPBstate = "off";
              BRedstate = "on";
              whitestate = "off";
              amberstate = "off";
              blackoutstate = "off";
              update(BRed,1);
            } else if(header.indexOf("GET /white/on") >= 0) {
              THPBstate = "off";
              BRedstate = "off";
              whitestate = "on";
              amberstate = "off";
              blackoutstate = "off";
              update(white,1);
            } else if(header.indexOf("GET /amber/on") >= 0) {
              THPBstate = "off";
              BRedstate = "off";
              whitestate = "off";
              amberstate = "on";
              blackoutstate = "off";
              update(amber,1);
            } else{
              THPBstate = "off";
              BRedstate = "off";
              whitestate = "off";
              amberstate = "off";
              blackoutstate = "on";
              blackout();
            }

            //Set up the web page using HTML
            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("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #195B6A;}</style></head>");

            // Web Page Heading
            client.println("<body><h1>LED Panel Control</h1>");

            // Display current state for THPB
            client.println("<p>THPB - State " + THPBstate + "</p>");
            // If the green LED is off, it displays the ON button       
            if (THPBstate == "on") {
              client.println("<p><a href=\"/THPB/on\"><button class=\"button\">OFF</button></a></p>");
            } else {
              client.println("<p><a href=\"/THPB/on\"><button class=\"button\">ON</button></a></p>");
            }

            // Display current state for BRed
            client.println("<p>BRed - State " + BRedstate + "</p>");
            // If the red LED is off, it displays the ON button       
            if (BRedstate == "on") {
              client.println("<p><a href=\"/BRed/on\"><button class=\"button button2\">OFF</button></a></p>");
            } else {
              client.println("<p><a href=\"/BRed/on\"><button class=\"button button2\">ON</button></a></p>");
            }
            client.println("</body></html>

第 4 步:代码模拟

我所知道的很多关于如何使用这些 Web 功能的知识都是基于其他更好的教程。这里的主要思想是在数组中设置我们的颜色,以便我们在设置面板颜色时可以参考该数组。然后我们设置网页将按钮打开每个阵列。从那里我们只需将数组和状态传递给我们的其余代码,以便它可以更改面板的颜色。

关于我选择放入代码的颜色的一些解释。首先是剧院粉红色和蓝色或我在代码中所说的 THPB。这是一种大部分是白光,一个面板上只有一点粉红色,另一个面板上只有一点蓝色。这只是有助于为场景添加一些深度和温暖。下一个是 BRed,蓝色和红色的缩写,我想要的是你在视频文章中看到的照明风格,一个面板上的粉红色几乎是紫色/红色,另一个面板上是非常饱和的蓝色。我认为这是一个有趣的组合,所以我把它扔在这里。接下来是白色,只是白色,一种明亮的白色,可为场景添加大量光线。其次是琥珀色,有点偏暖的白色。最后,停电——关掉所有的灯。

请随时将这些颜色修改为适合您的颜色。我仍在努力对它们进行微调,因为其中大部分只是我猜测的起始值。

这段代码的第一部分非常标准,定义了我们将要使用的库,定义了一些贯穿始终的常量,最后设置了一些变量,以便 ESP 可以连接到您的 WiFi 网络

#include "FastLED.h"
#include "WiFi.h"

//Define Pins
#define LED_PIN 13
#define NUM_LEDS 128
#define BRIGHTNESS 64     //used later but not implimented in the code for adjustment
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
#define UPDATES_PER_SECOND 100;

//Define Web Page
const char* ssid = "Network Name";
const char* password = "Network Password";
String header;
WiFiServer server(80);

这是我之前提到的数组。这些数组中的每一个都以 [红色面板 1、绿色面板 1、蓝色面板 1、红色面板 2、绿色面板 2、蓝色面板 2] 形式的数组保存颜色。这些值中的每一个都在 0 和 1 之间,0 表示该颜色关闭,1 表示该颜色最亮。这样做是因为我计划稍后添加一种更改亮度的方法。随意修改这些数组以满足您的需要。

//Define Arrays
float theaturePB[6] = {1,.5,.5,.5,.5,1};
float BRed[6] = {1,.25,.3,.3,.25,1};
float white[6] = {1,1,1,1,1,1};
float amber[6] = {0.5,1,1,0.5,1,1};

我们需要跟踪我们打开和关闭的内容。所以首先我们从关灯开始 - 停电状态。在这里,我们只是将它们全部设置为关闭,将停电状态设置为开启

String THPBstate = "off";
String BRedstate = "off";
String whitestate = "off";
String amberstate = "off";
String blackoutstate = "on";

在 setup() 中,我们需要完成很多事情。首先我们定义串行连接,然后定义 LED 面板。

接下来,我们设置 WiFi 连接并在连接后打印出 IP 地址。这是如何找出连接到网页的位置。然后我们开始向任何连接的人提供网页。

void setup(){
  Serial.begin(115200);
  delay(3000);
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);

  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  while(WiFi.status() != WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  server.begin();
}

在 loop() 中,我们需要检查是否有人连接到 ESP 托管的网页。然后我们查看我们托管的网页的 URL。从那里我们可以确定我们想要灯光的颜色。请注意,这是代码中最令人困惑的部分。所以请随时在评论中提出任何问题,我会看看我能做些什么。

在第一部分中,我们查看 URL 的末尾并阅读那里的文本。从该文本中,它告诉我们要打开什么状态。然后我们修改状态变量以符合我们想要打开的内容并打开其他所有内容。

void loop(){
  WiFiClient client = server.available();
  if(client){
    String currentLine = "";
    while (client.available()){
      if(client.available()){
        char c = client.read();
        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();
            if(header.indexOf("GET /THPB/on") >= 0) {
              THPBstate = "on";
              BRedstate = "off";
              whitestate = "off";
              amberstate = "off";
              blackoutstate = "off";
              update(theaturePB,1);
            }else if(header.indexOf("GET /BRed/on") >= 0) {
              THPBstate = "off";
              BRedstate = "on";
              whitestate = "off";
              amberstate = "off";
              blackoutstate = "off";
              update(BRed,1);
            } else if(header.indexOf("GET /white/on") >= 0) {
              THPBstate = "off";
              BRedstate = "off";
              whitestate = "on";
              amberstate = "off";
              blackoutstate = "off";
              update(white,1);
            } else if(header.indexOf("GET /amber/on") >= 0) {
              THPBstate = "off";
              BRedstate = "off";
              whitestate = "off";
              amberstate = "on";
              blackoutstate = "off";
              update(amber,1);
            } else{
              THPBstate = "off";
              BRedstate = "off";
              whitestate = "off";
              amberstate = "off";
              blackoutstate = "on";
              blackout();
            }

接下来我们需要告诉ESP如何设置网页。我们在这里使用 HTML 来设置页面。我没有触及的顶部,我找到了另一个带有按钮的教程,我复制了他们的代码以将按钮添加到我的。然后我们设置网页标题 - 或屏幕顶部选项卡中显示的内容。接下来我们需要设置每个按钮。为此,我们查看按钮的状态,对于第一个,我们查看 THPB 的状态(如果打开),我们打印出表示关闭的按钮,以便将其关闭。但是如果状态是关闭的,我们会打印一个按钮,上面写着打开,这样我们就可以打开它。我们还更新了我们在上一节中使用的 URL 末尾的文本。

然后我们为每个按钮状态执行此操作。它是一个很长的部分,但每个块都做同样的事情。

    //Set up the web page using HTML
            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("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #195B6A;}</style></head>");

            // Web Page Heading
            client.println("<body><h1>LED Panel Control</h1>");

            // Display current state for THPB
            client.println("<p>THPB - State " + THPBstate + "</p>");
            // If the green LED is off, it displays the ON button       
            if (THPBstate == "on") {
              client.println("<p><a href=\"/THPB/on\"><button class=\"button\">OFF</button></a></p>");
            } else {
              client.println("<p><a href=\"/THPB/on\"><button class=\"button\">ON</button></a></p>");
            }

            // Display current state for BRed
            client.println("<p>BRed - State " + BRedstate + "</p>");
            // If the red LED is off, it displays the ON button       
            if (BRedstate == "on") {
              client.println("<p><a href=\"/BRed/on\"><button class=\"button button2\">OFF</button></a></p>");
            } else {
              client.println("<p><a href=\"/BRed/on\"><button class=\"button button2\">ON</button></a></p>");
            }
            client.println("</body></html>

你已经做到了这一步,你几乎完成了。下一节实际上是链接 LED 面板的颜色。我们将每个 LED 分成两部分循环,前 64 个是第一个面板,第二个 64 个是第二个面板。然后我们为每个 LED 设置每种颜色的值。一旦我们为每个 LED 设置了所有颜色,我们就使用 .show() 来更新面板。

请注意,这是一个单独的函数。这是从循环中调用的,它提供给定颜色和亮度的数组。

//Update the panel colors
void update(float arr[], float brightness){
    for(int i = 0; i < 64; i++){
      leds[i].r = arr[0]*brightness*255;
      leds[i].g = arr[1]*brightness*255;
      leds[i].b = arr[2]*brightness*255;
    }
    for(int i = 64; i < 128; i++){
      leds[i].r = arr[3]*brightness*255;
      leds[i].g = arr[4]*brightness*255;
      leds[i].b = arr[5]*brightness*255;
    }
    FastLED.show();
}

最后一部分是关闭所有 LED。我们只是通过所有 LED 循环并将它们的颜色设置为黑色。他们关闭。

void blackout(){ 
  for(int i = 0; i <128; i++){ 
    leds[i] = CRGB::Black; 
  } 
  FastLED.show(); 
}

第 5 步:组装零部件

打印外壳,完成接线并上传代码后,我们可以将它们放在一起。

LED 面板热粘在外壳的背面,电线从顶部伸出一个孔。ESP32 使用两个支架固定在外壳背面。另外两个螺丝钉通过外壳顶部的孔。一切就绪后,可以用一些短螺钉拧上盖子。

接下来将所有销钉附件滑到销钉上,并用穿过孔的螺钉将它们固定到位。

最后将面板上的螺钉穿过定位销附件的凸耳上的孔,然后将螺母拧入以将其固定到位。

将所有东西放在一起并准备就绪后,我用一些扭结将电线固定在销钉上以稍微清理一下。

第 6 步:使用面板

要使用面板,请将 ESP32 连接到计算机并打开串行监视器。测试输出应该告诉您 ESP32 托管的网页的 IP 地址。在浏览器中转到该 IP 地址,您应该会看到一些按钮。每个按钮都会打开代码中的一种预设颜色。以后您只需要将 ESP 连接到电源并转到网页,您的路由器可能会在下次为 ESP 分配相同的 IP。如果您遇到问题,请连接到计算机并使用串行监视器再次检查 IP。

项目到这里就完成了,希望大家能喜欢这个项目。

加入微信技术交流群

技术交流,职业进阶

关注与非网服务号

获取电子工程师福利

加入电路城 QQ 交流群

与技术大牛交朋友

讨论