LED Camera Lights

by tinyboatproductions in Circuits > Cameras

2119 Views, 20 Favorites, 0 Comments

LED Camera Lights

IMG_3473.jpg
Panels with Covers_1.35.1.png
IMG_3472.jpg
LED Camera Lights - Controlled over WiFi

I needed some better lighting for my videos. So I figured I would take the opportunity to make my own. The goal is to have two panels one on either side of the camera so that the lighting is more even and I have more options for filming and cool lighting effects.

I think this is to just be the first part of this project, but as Zack Freedman once said "if it works its finished," or something like that, so I figured I would share it with all of you. Right now, the panels are controlled over WiFi. I have 4 preset colors, feel free to add, modify, or expand on this project.

Let me know if you have questions or any suggestions moving forward.

Supplies

Supplies:

Tools:

  1. Soldering Iron
  2. 3D printer
  3. USB Cable
  4. Wire Strippers
  5. Wire Cutters
  6. Pliers

The Case

Case_1.5.2.png

As with many of my projects I am starting with the case here. I designed and printed a case for these light panels. It mounts to the top of my camera. Here are all of the printed parts that I used: https://www.thingiverse.com/thing:4949634

So start printing the case so when you are ready you can slap the whole thing together.

I printed all the parts in black except for the covers which are printed in transparent. You could also use white, but I think that would give a bluer tone to the lights. You could also use a different light colored filament but it will tint the light that the panels produce.

You'll need the following parts

  • (2) Case
  • (2) Cover - Printed in clear or white
  • (2) Panel Dowel Attachment
  • (1) Camera Dowel Attachment
  • (2) Standoff

Wiring

ESP Front View_1.23.1.png
Led panel diagram.png

To put this together I removed the wires that came with the panels as well as all of the pins on the ESP32. Then attached new wires that can run from the control board to the light panels.

Running from the ESP32 to the first panel on the DIN/GND/5V side. Then from the DOUT/GND/5V to the DIN/GND/5V on the second panel.

I've attached a wiring diagram to help with this.

Code

Oh boy, everyone's favorite part, the code. I've attached the full code to this step and on the next step I'll go into more detail about what it does and how it works.

A huge note here is that to use the ESP32 you will need to add it to the Arduino IDE. Here is a link to the to the tutorial I think I used when I added it.

The basis for the web page came from this tutorial.

I'll go a bit more into detail is some parts in the next step.

#include "FastLED.h"<br>#include "WiFi.h"<br><br>//Define Pins<br>#define LED_PIN 13<br>#define NUM_LEDS 128<br>#define BRIGHTNESS 64     //used later but not implimented in the code for adjustment<br>#define LED_TYPE WS2811<br>#define COLOR_ORDER GRB<br>CRGB leds[NUM_LEDS];<br>#define UPDATES_PER_SECOND 100;<br><br>//Define Web Page<br>const char* ssid = "Network Name";<br>const char* password = "Network Password";<br>String header;<br>WiFiServer server(80);<br><br><br>//Define Arrays<br>float theaturePB[6] = {1,.5,.5,.5,.5,1};<br>float BRed[6] = {1,.25,.3,.3,.25,1};<br>float white[6] = {1,1,1,1,1,1};<br>float amber[6] = {0.5,1,1,0.5,1,1};<br><br>String THPBstate = "off";<br>String BRedstate = "off";<br>String whitestate = "off";<br>String amberstate = "off";<br>String blackoutstate = "on";<br><br>void setup(){<br>  Serial.begin(115200);<br>  delay(3000);<br>  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);<br>  FastLED.setBrightness(BRIGHTNESS);<br><br>  WiFi.begin(ssid, password);<br>  Serial.print("Connecting to ");<br>  Serial.println(ssid);<br>  while(WiFi.status() != WL_CONNECTED){<br>    delay(500);<br>    Serial.print(".");<br>  }<br>  Serial.println("");<br>  Serial.println("WiFi connected.");<br>  Serial.print("IP address: ");<br>  Serial.println(WiFi.localIP());<br>  <br>  server.begin();<br>}<br><br>void loop(){<br>  WiFiClient client = server.available();<br>  if(client){<br>    String currentLine = "";<br>    while (client.available()){<br>      if(client.available()){<br>        char c = client.read();<br>        header += c;<br>        if(c=='\n'){<br>          if(currentLine.length() == 0){<br>            client.println("HTTP/1.1 200 OK");<br>            client.println("Content-type:text/html");<br>            client.println("Connection: close");<br>            client.println();<br>            if(header.indexOf("GET /THPB/on") >= 0) {<br>              THPBstate = "on";<br>              BRedstate = "off";<br>              whitestate = "off";<br>              amberstate = "off";<br>              blackoutstate = "off";<br>              update(theaturePB,1);<br>            }else if(header.indexOf("GET /BRed/on") >= 0) {<br>              THPBstate = "off";<br>              BRedstate = "on";<br>              whitestate = "off";<br>              amberstate = "off";<br>              blackoutstate = "off";<br>              update(BRed,1);<br>            } else if(header.indexOf("GET /white/on") >= 0) {<br>              THPBstate = "off";<br>              BRedstate = "off";<br>              whitestate = "on";<br>              amberstate = "off";<br>              blackoutstate = "off";<br>              update(white,1);<br>            } else if(header.indexOf("GET /amber/on") >= 0) {<br>              THPBstate = "off";<br>              BRedstate = "off";<br>              whitestate = "off";<br>              amberstate = "on";<br>              blackoutstate = "off";<br>              update(amber,1);<br>            } else{<br>              THPBstate = "off";<br>              BRedstate = "off";<br>              whitestate = "off";<br>              amberstate = "off";<br>              blackoutstate = "on";<br>              blackout();<br>            }<br><br>            //Set up the web page using HTML<br>            client.println("<!DOCTYPE html><html>");<br>            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");<br>            client.println("<link rel=\"icon\" href=\"data:,\">");<br>            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");<br>            client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");<br>            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");<br>            client.println(".button2 {background-color: #195B6A;}</style></head>");<br>            <br>            // Web Page Heading<br>            client.println("<body><h1>LED Panel Control</h1>");<br>            <br>            // Display current state for THPB<br>            client.println("<p>THPB - State " + THPBstate + "</p>");<br>            // If the green LED is off, it displays the ON button       <br>            if (THPBstate == "on") {<br>              client.println("<p><a href=\"/THPB/on\"><button class=\"button\">OFF</button></a></p>");<br>            } else {<br>              client.println("<p><a href=\"/THPB/on\"><button class=\"button\">ON</button></a></p>");<br>            }<br>               <br>            // Display current state for BRed<br>            client.println("<p>BRed - State " + BRedstate + "</p>");<br>            // If the red LED is off, it displays the ON button       <br>            if (BRedstate == "on") {<br>              client.println("<p><a href=\"/BRed/on\"><button class=\"button button2\">OFF</button></a></p>");<br>            } else {<br>              client.println("<p><a href=\"/BRed/on\"><button class=\"button button2\">ON</button></a></p>");<br>            }<br>            client.println("</body></html>");<br><br>            // Display current state for white<br>            client.println("<p>White - State " + whitestate + "</p>");<br>            // If the green LED is off, it displays the ON button       <br>            if (whitestate == "on") {<br>              client.println("<p><a href=\"/white/on\"><button class=\"button button3\">OFF</button></a></p>");<br>            } else {<br>              client.println("<p><a href=\"/white/on\"><button class=\"button button3\">ON</button></a></p>");<br>            } <br><br>            // Display current state for amber <br>            client.println("<p>Amber - State " + amberstate + "</p>");<br>            // If the green LED is off, it displays the ON button       <br>            if (amberstate == "on") {<br>              client.println("<p><a href=\"/amber/on\"><button class=\"button button4\">OFF</button></a></p>");<br>            } else {<br>              client.println("<p><a href=\"/amber/on\"><button class=\"button button4\">ON</button></a></p>");<br>            } <br><br>            // Display current state for blackout <br>            client.println("<p>Blackout - State " + blackoutstate + "</p>");<br>            // If the green LED is off, it displays the ON button       <br>            if (blackoutstate == "on") {<br>              client.println("<p><a href=\"/blackout/on\"><button class=\"button button5\">OFF</button></a></p>");<br>            } else {<br>              client.println("<p><a href=\"/blackout/on\"><button class=\"button button5\">ON</button></a></p>");<br>            } <br><br>            // The HTTP response ends with another blank line<br>            client.println();<br>            // Break out of the while loop<br>            break;<br>          } else { // if you got a newline, then clear currentLine<br>            currentLine = "";<br>          }<br>        } else if (c != '\r') {  // if you got anything else but a carriage return character,<br>          currentLine += c;      // add it to the end of the currentLine<br>        }<br>      }<br>    }<br>    // Clear the header variable<br>    header = "";<br>    // Close the connection<br>    client.stop();<br>    Serial.println("Client disconnected.");<br>    Serial.println("");<br>  }<br>}<br>          <br>//Update the panel colors<br>void update(float arr[], float brightness){<br>    for(int i = 0; i < 64; i++){<br>      leds[i].r = arr[0]*brightness*255;<br>      leds[i].g = arr[1]*brightness*255;<br>      leds[i].b = arr[2]*brightness*255;<br>    }<br>    for(int i = 64; i < 128; i++){<br>      leds[i].r = arr[3]*brightness*255;<br>      leds[i].g = arr[4]*brightness*255;<br>      leds[i].b = arr[5]*brightness*255;<br>    }<br>    FastLED.show();<br>}<br><br><br>void blackout(){<br>  for(int i = 0; i <128; i++){<br>    leds[i] = CRGB::Black;<br>  }<br>  FastLED.show();<br>}<br>

Code Walk Through

I am going to warn you on this one, I have no idea how most of this works. A lot of what I know about how to use these web functions is based on other, better tutorials out there. The main idea here is to set up our colors in arrays so that we can refer to the array later when setting the color of the panel. Then we set up the web page will buttons to turn on each array. From there we just pass the array and state to the rest of our code so that it can change the color of the panels.

A bit of explanation on the colors that I chose to put in the code. First up is theater pink and blue or THPB as I call it in the code. This is a mostly white light with just a touch of pink in one panel and blue in the other. This just helps to add a bit of depth and warmth to a scene. The next is BRed, short for blue and red, I was going for the style of lighting you see in a video essay with extreme pink almost purple/red on one panel and a very saturated blue on the other. I think its a fun combo so I threw it in here. Next up White, just white, a bright white to add a lot of light to a scene. Followed by Amber, a bit of a warmer white. Finally, black out - just turn all the lights off.

Please feel free to modify these colors to what ever works for you. I am still working on getting them fine tuned a bit as most of these are just what I guessed as a starting value.

The first chunk of this code is pretty standard, defining libararies we are going to use, defining some constants to use throughout and finally set up some variables so that the ESP can connect to your WiFi network


#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);

Here are the arrays I mentioned earlier. Each of these arrays holds the colors in an array of the form [Red Panel 1, Green Panel 1, Blue Panel 1, Red Panel 2, Green Panel 2, Blue Panel 2]. Each of these values is between 0 and 1 with 0 being having that color off and 1 being that color at the brightest. It is done this way as I plan to add a way to change the brightness later on. Feel free to modify these arrays to your need.

//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};

We need to keep track of what we have turned on and off. So to start with we start with the lights off - the blackout state. Here we just set all of them as off and the blackout state as on

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

In the setup() we need to get a bunch of things done. First we define the serial connection and then the LED panels.

Next we set up the WiFi connection and print out the IP address once we are connected. This is how to figure out where to connect to the web page. Then we begin providing the webpage to any one who connects.

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();
}

In the loop() we need to check and see if someone is connected to the webpage the ESP is hosting. We then look at the URL of the web page we are hosting. From there we can determine what color we want the lights to be. Just a heads up this is the most confusing part of the code. So feel free to ask any questions in the comments, and I'll see what I can do.

In this first section we are looking the end of the URL and reading the text thats there. From that text it tells us what state to turn on. We then modify the state variables to line up with what we want to turn on and turn everything else on.

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();
}

Next we need to tell the ESP how to set up the webpage. We are using HTML here to setup the page. The top I didn't touch, I found another tutorail that had buttons and I copped their code to add the buttons to mine. We then set up the webpage header - or what shows up in the tab at the top of the screen. Next we need to set up each button. To do this we look at what the state of the button is, for the first one we look at the state of THPB if its on, we print out the button that says off, so we can turn it off. But if the state is off we print a button that says on so we can turn it on. We also update the text at the end of the URL that we used in the previous section.

We then do that for each button state. Its a long section but each chunk does the same thing.


//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>");

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

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

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

// The HTTP response ends with another blank line
client.println();
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}

You've made it this far you are almost done. This next section is acutally chaing the color of the LED panels. We cycle through each LED in two sections, the first 64 are the first panel and the second 64 are the second panel. We then set the value of each color for each LED. Once we set all the colors for every LED we use .show() to update the panels.

Note here that this is a speperate function. This is called from the loop, it is provided the array for the given color and the brightness.

//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();
}

Last section is to turn all the LEDs off. We just cycle thorugh all the LEDs and set their color to black. And they turn off.

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

Putting It All Together

Panels with Covers_1.35.1.png

With the case printed, the wiring done, and the code uploaded we can put it all together.

The LED panels are hot glued into the backs of the case and the wires run out a hole at the top. The ESP32 is screwed on to the back of the case using the two standoffs. Two more screws are glued through the holes in the top of the case. With everything in place the cover can be screwed on with some short screws.

Next slide all the dowel attachments on to the dowel and secure them in place with a screw through the hole.

Finally feed the screws on the panels through the hole on the tab of the dowel attachment and thread a nut down to secure it in place.

With everything put together and ready to go I secured the wire to the dowels with some twist ties to clean them up a bit.

Using the Panels

IMG_3474.jpg
Benchy Shot Multi.png

To use the panels connect your ESP32 to a computer and open the serial monitor. The test output should tell you the IP address of the web page the ESP32 is hosting. Go to that IP address in your browser and you should be greeted with some buttons. Each button will turn on one of the preset colors in the code. In the future you just need to connect the ESP to power and go to the web page, your router likely will assign the ESP the same IP next time. If you are having issues connect to a computer and check the IP again using the serial monitor.

I have found if you click the buttons too fast the web page needs to be reloaded.

I've also included an image with a few of the colors that are in the code.

Thanks for reading. If you make this make sure to share a picture. If you have a question or comment let me know in the comments.