Фотографу

Собираем студийный свет с адресными 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 и в следующий раз.

Все готово.

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

Источник

b8c49f23d6acc40de2a736280fa0fb80 (3)

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

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Кнопка «Наверх»


Яндекс.Метрика
Закрыть
Закрыть