«Китайцы» делают очень крутые штуки, в том числе в сфере девайсов для фотографов. За последние 10 лет очень подтянули качество, стали разрабатывать свои уникальные продукты, которые бывает выше на голову чем от «именитых производителей». Но, почему то практически в каждом продукте находится хотя бы один, но огромный жирный минус. Такое ощущение, что разработчикам электроники прямо таки ставят в тз пунктик: «ложка дегтя — минимум 200 грамм».

Не так давно я решил побаловать себя постоянным светом и купил себе несколько «световых палок» yongnuo yn-360. Палки оказались просто волшебными, но без жирного минуса конечно же не обошлось — android приложение для дистанционного управления, оказалось практически не рабочим. Кроме мелких минусов приложения — главный, это невозможность управления несколькими устройствами сразу. Этот минус сделал бесполезным функцию управления, так как все равно приходилось бегать от палки до палки и регулировать свет вручную.

У меня был опыт в программировании, поэтому за несколько вечеров ситуация была исправлена.

image

Выбор инструмента разработки


Я не профессиональный разработчик — программирование это мое хобби и поэтому я не готов тратить на изучение технологий много времени. Так получилось, что мой любимый язык python, но для мобильной разработки он подходит не очень хорошо. Есть конечно такие замечательные проекты как kivy, но очень не хватает «батареек», к которым так привык в python (а потом уже в JavaScript). В итоге выбор пал на JS с apache cordova, на котором я уже делал один проект (он кстати немного связан с моей работой — этим приложением я «прокачивал» свой квадрокоптер dji spark, который был урезан маркетологами почитать тут). Из плюсов разработки на cordova, это скорость и легкость разработки и наличие «батареек».

Как оно работает


Догадаться как эти палки работают со смартфоном совсем не сложно — это bluetooth LE. Мне повезло что этим вопросом кто то уже озадачился до меня и за несколько минут я нашел проект на python, в котором я смог подсмотреть протокол работы палок. Он оказался совсем не сложным. Для работы с ble в cordova нашелся плагин ble и на написание рабочего прототипа, ушел ровно один вечер.

Все начинается со сканирования bluetooth LE устройств. Но чтобы исключить из поиска не нужное (а его вокруг оказалось очень много), можно сканировать, задав UUID нужного сервиса. Далее соединяемся с ним и получаем сервис и характеристику. UUID нужного сервиса и характеристики можно узнать, например, используя приложение BLE Scanner.

Все это приводится к простому куску кода:

var devices_dev={};
var devices=[];
var dev_main={};
function start_scan(){
         evothings.ble.startScan(
            function(device)
            {
                // если девайс еще не в списке
                if (! (device.address in devices_dev)){
                    // добавляем его адрес в список
                    devices_dev[device.address]=1;
                    // соединяемся
                    evothings.ble.connectToDevice(
                            device,
                    function(dev)
                 {
                        // получаем "сервис"
                         var service = evothings.ble.getService(dev, 'f000aa60-0451-4000-b000-000000000000');
                        // и характеристику сервиса
                         var characteristic = evothings.ble.getCharacteristic(service, 'f000aa61-0451-4000-b000-000000000000');
                         // добавляем характеристику к списку устройств. Оно нам нужно будет для отправки.
                         dev_main[dev.name]=[dev,characteristic];
                         devices.push(dev.name);
                  }
            },
            function(error)
            {
                                console.log(error);
            },
            // фильтр по UUID сервисов, которые предоставляет устройства.
            { serviceUUIDs: ['f000aa60-0451-4000-b000-000000000000'] }
            )
}

По тому же принципу, кстати, можно присоединяться к другим BLE устройствам. Я побаловался с умными весами xiaomi, которых смогу получить вес. Так же смог включить умный чайник от redmond (а так же узнать текущую температуру).

После этого, остается только лишь отправлять информацию о цвете или яркости света. В этих палках есть несколько типов светодиодов: холодные 5500к, теплые 3200к и RGB диоды. Сделано так, что ты можешь либо задать яркость холодным и теплым (0-99%), либо включить RGB диоды.
Если нужно установить яркость холодных или теплых диодов, отправляем такую последовательность:

var white=0; // яркость 5500к диодов 0-99
var yellow= 50; //яркость 3200к диодов 0-99
var data= new Uint8Array([0xAE,0xAA,0x01,white,yellow,0x56]);

Если цветных:

var RR=255; //яркость красного канала 0-255
var GG=0; //яркость зеленого  канала 0-255
var BB=; //яркость синего канала 0-255
var data=new Uint8Array([0xAE,0xA1,RR,GG,BB,0x56]);

Сама же функция отправки выглядит так:

evothings.ble.writeCharacteristic(
    dev,
    characteristic,
    data, // Buffer view with data to write
    function()
    {
     console.log('done!');
    },
    function(errorCode)
    {
        console.log('writeCharacteristic error: ' + errorCode);
    });

В процессе дальнейшей работы над приложением, у палки нашелся досаднейший баг, на обнаружении которого ушло достаточно много времени: например, если отправить «белый 50%», затем «включи красный», а потом опять «белый 50%», то на последнюю команду палка уже не реагирует. Пришлось вставлять костыль на такие случаи и для последней команды такой последовательности отправлять случайно плюс/минус 1%.

UI и «фишки»


Так как приходится работать со стандартным стеком html+js+css, тебе доступны очень много готовых наработок. Для UI был выбран materialize css, а в роли главного компонента UI — выбора цвета iro.js.

В процессе тестирования приложения, вылезла особенность раздельных RGB диодов — ужасное смешение цветов. Если к красному добавить хоть 1% другого цвета, то получается странная цветовая каша. Выбор цвета обычно (в том числе официальном приложении) реализуется стандартным для таких вещей «цветовым кругом», в котором очень трудно попасть на «чистый красный» и т.д. Пришлось реализовывать поканальное управление группами цветных диодов.

Ну и так же были сделаны некоторые фишки, которые в реальной работе помогают. Например, переименовании палок. В голове не нужно держать их порядковые номера и соображать, какая из них стоит на фоне — можно просто задать имена «контровой», «слева» и т.д. Ну и не обошлось без пресетов, когда тебе нужно быстро сменить свет на заранее определенный.

image

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

«Анимация»


Для видеосъемки, иногда нужно всякие разные световые эффекты, например, «свет» полицейской машины на заднем фоне и т.д. Если приложение умеет управлять светом «вручную», то почему бы не реализовать «анимацию». Первоначально возникла идея «зашить» штук 10-20 различных анимаций, но как то лень было над ними сидеть, поэтому, потратив еще два вечера, я сделал простенький веб редактор анимаций. Причем, редактировать можно до 10 каналов, распределяя потом их в приложении между палками.

image

Единственным минусом этих палок, по сравнению с более дорогими аналогами, оказалось достаточно медленная работы. От отправки команды, до переключения цвета, доходит до 300-400 миллисекунд, поэтому нельзя добиться более стабильной работы на более высоких скоростях.

Итого


В результате, за несколько вечером было написано и опубликовано готовое приложение, которое по моему мнению, на голову выше «официального» от известного производителя. Как оно работает, показал в этом ролике:


P.S. Это не первая моя статья, как программирование помогает в работе, которая совершенно не связана с самим программированием. Почитать по этой теме:

Transcend WiFi. Пишем клиент Shoot&View для Windows, Mac и Linux.
Linux в кармане — на службе у фотографа
Делаем автономную фотобудку на raspberry pi