Фотографу

Собираем студийный свет с адресными RGB светодиодами

Если вы увлекаетесь студийной фото/видеосъемкой, то эта статья будет вам полезна.
Как известно, освещение играет большую роль в качестве снимков. Правильно подобранный свет делает фотографию намного эффектней. Если раньше, фотографы имели возможность изменять освещение только определенного спектра, то сейчас, с развитием светодиодов, возможности в выборе цветовой гаммы практически безграничны.

В этой статье мастер расскажет нам, как сделать и запрограммировать студийное освещение, использовав уже готовую светодиодную матрицу. Управляется освещение с помощью смартфона через Wi-Fi.

Инструменты и материалы:
-Микроконтроллер ESP32;
-Адресная светодиодная панель 8×8;
-Рейка круглая деревянная;
-Проволока;
-Паяльные принадлежности;
-Крепеж;
-Клеевой пистолет;
-Супер клей;
-3D-принтер;
-USB-кабель;
-Инструмент для зачистки проводов;
-Кусачки;
-Плоскогубцы;

Шаг первый: корпус
Светодиодная панель имеет размер 8Х8 см. В соответствии с размерами был разработан и напечатан на 3D-принтере корпус и крепление для двух светильников. Светильники будут крепиться на деревянную рейку, а он крепиться непосредственно к фотокамере.
Основной корпус напечатан черной нитью. Передняя панель напечатана прозрачной нитью.

Файлы для печати деталей можно скачать здесь.

Шаг второй: подключение
Схема подключения панелей к ESP32 следующая:
ESP32 —- первая панель
D13 DIN
GND GND
VIN 5V
первая панель —- вторая панель

DOUT DIN
GND GND
5V 5V

Шаг третий: код
Весь код можно скачать ниже.

 Показать / Скрыть текст#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>");

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

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

void blackout(){
for(int i = 0; i <128; i++){
leds[i] = CRGB::Black;
}
FastLED.show();
}
Основная задача здесь состоит в том, чтобы настроить цвета в массивах, чтобы можно было ссылаться на массив позже при установке цвета панели. Затем настраивается веб-страница с кнопками для включения каждого массива.
Первый фрагмент этого кода довольно стандартный, он определяет библиотеки, которые будут использоваться.

 Показать / Скрыть текст#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 () определяется последовательное соединение, а затем светодиодные панели.
Затем нужно настроить соединение Wi-Fi и распечатать 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 () проверяет, есть ли подключение к веб-странице, и какой цвет задается пользователем.

 Показать / Скрыть текст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, как настроить веб-страницу, каждую кнопку, в каком состоянии кнопка (вкл/выкл) и т.д.

 Показать / Скрыть текст //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("");
}
}
Следующий раздел посвящен изменению цвета светодиодных панелей. Здесь циклически перебирается каждый светодиод в двух секциях, первые 64 — это первая панель, а вторые 64 — это вторая панель. Затем устанавливается значение каждого цвета для каждого светодиода. После установки данных используется функция .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();
}
Последний раздел — выключить все светодиоды.
void blackout(){
for(int i = 0; i &lt;128; i++){
leds[i] = CRGB::Black;
}
FastLED.show();
}
Шаг четвертый: сборка
Теперь можно собрать все вместе.
Светодиодные панели крепятся к задней части корпуса термоклеем, а провода выходят через отверстие наверху. ESP32 прикручивается к задней части корпуса с помощью двух резьбовых вставок. Еще два винта вклеиваются через отверстия в верхней части корпуса. Лицевая панель прикручивается короткими винтами.
Затем светильник, с помощью крепления, фиксируются на деревянной рейке.

Шаг пятый: работа светильников
Чтобы использовать панели, подключаем ESP32 к компьютеру и открываем монитор последовательного порта. В результатах теста должен быть указан IP-адрес веб-страницы, на которой размещается ESP32. Переходим на этот IP-адрес в своем браузере. В приложении есть несколько кнопок. Каждая кнопка включает один из предустановленных цветов в коде.
В дальнейшем просто нужно подключить ESP к источнику питания и перейти на веб-страницу, маршрутизатор, скорее всего, назначит ESP тот же IP и в следующий раз.

Все готово.

Весь процесс по сборке и тестированию панелей можно посмотреть на видео.


Источник

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть
Закрыть