Компания SONY, решив показать себя на рынке экшен камер, выпускает линейку устройств HDR. Поманив клиентов привлекательной начинкой — хорошая матрица, быстрый процессор, цейсовская оптика и электронный стабилизатор изображения при маленьком весе, компания показывает свое «истинное лицо капитализма».
Для управления камерой выпускается пульт с просмотром видео по WiFi. Пульт довольно дорогой и дефицитный — сейчас его можно купить только на различных электронных барахолках.
Но ведь есть WiFi, значит можно управлять с телефона? А вы пробовали кататься на горных лыжах или на вейкборде со смартфоном в руках? Но этого неудобства еще мало.
Компания SONY, совершенно не заботясь о своих клиентах, убирает из Google Play приложение PlayMemories Mobile для управления своими экшен камерами по WiFi с любого мобильного телефона, заменив его на приложение для умных часов. Вместо него выпускает Imaging Edge Mobile — жутко неудобное и постоянно отваливающее от камеры. Та же песня и для приложений по iPhone.
Как обманутый вкладчик пользователь камеры HDR AS100 я решил поискать альтернативное решение и наткнулся на довольно интересный архив — Sony Camera Remote API beta SDK
SDK написан для разработки приложений управления камерами SONY по WiFi с устройств под управлением Android и iOS.
Внутри архива два каталога с примерами для разработки приложения на Java под Android и под iOS. Самое интересное, это PDF документ API references for Camera Remote API beta. Решено — буду делать ДУ пульт своими руками
Что в API твоем?
Во первых, там есть таблица поддерживаемых устройств на февраль 2017.
Исходя из таблицы, API с разной степенью функциональности совместим с практически всеми экшен камерами HDR от AS15 до AS300, камерами FDR, фотоаппаратами серий DSC, ILCE и NEX имеющих WiFi интерфейс.
Далее я буду описывать работу с камерой HDR AS100 с последней прошивкой 2.0.0, подразумевая, что с другими устройствами должна быть совместимость.
Во вторых, протокол управления камерами. Каждое устройство SONY из данного списка представляет собой HTTP сервер, который выполняет запросы, а также выдает отдельные кадры в формате JPEG и потоковое видео.
Моя же цель разработать компактный и максимально дешевый пульт дистанционного управления для камер SONY
Для начала, нужно убедиться, что в меню камеры включен WiFi:
[SETUP] -> [CONFG] -> [Wi-Fi] -> [ON]
Идентификатор и пароль должны быть на отдельной наклейке в инструкции по эксплуатации к камере. Если данная наклейка утеряна, то можно подключить камеру по MicoUSB к компьютеру под управлением Microsoft Windows и включить ее. На экране появится [USB], а на компьютере два сетевых диска — с карточкой памяти, вставленной в камеру и внутренней памятью камеры PMHOME. Нас интересует второй диск
В файле: \\INFO\WIFI_INF.TXT содержится идентификатор и пароль доступа к камере по WiFi, а в файле \\INFO\WPS_PIN.TXT ключевой пин для подключения по WPS. Доступ к информации возможен только на чтение, так что изменить идентификатор, пароль или пин не представляется возможным.
Теперь можно с этими данными подключиться к камере. IP-адрес камеры после подключения — 192.168.122.1. Для управления камерой необходимо послать HTTP POST запросы по адресу http://192.168.122.1:10000/sony/camera.
Для разных моделей камер могут быть использованы следующие адреса:
- http://10.0.0.1:10000/camera
- http://10.0.0.1:10000/sony/camera
- http://192.168.122.1:8080/sony/camera
- http://192.168.122.1:10000/sony/camera
В третьих, структуру запроса и ответа. Каждый запрос содержит команду в формате JSON и возвращает ответ также в формате JSON. Полный список команд, а также примеры использования содержатся все в том же PDF файле.
Так же по HTTP протоколу возвращаются готовые файлы со снимками и видеопоток для просмотра с камеры.
Наиболее сложным в протоколе является запрос на выдачу информации. В зависимости от версии запроса (1.0 — 1.3) выдает массив от 34 до 62 параметров в формате JSON, которые тоже в свою очередь могут быть массивами, и имеет два режима работы — с немедленным ответом полной информации по состоянию камеры и с ответом по любому событию на камере (например переключению режима или включению записи)
Первый блин … ЛУТом
Сердце — пламенный мотор самый дешевый МК с WiFi — китайский ESP8266. Правда глядя на унылую перерисовку картинки на графическом экране 240×320 по SPI я решил отложить изготовлении копии родного соньковского пульта с предпросмотром видео в реальном времени, а остановился на функционале обычной включалки/выключалки с выбором режима. В качестве дисплея взял 0.91″ одноцветный OLED с разрешением 32×128, какой обычно применяется в недорогих фитнес браслетах.
Накидываю схему для прототипа
и дизайн платы с односторонним монтажом под ЛУТ технологию
Ну и сама жертва ЛУТ
Прошивка
Прошивку я разрабатывал в Arduino IDE с установленным ESP8266 Core. Для удобства я воспользовался дополнительными библиотеками:
- Графическая библиотека Adafruit GFX
- Библиотека работа с OLED экранами Adafruit SSD1306
- Библиотека для быстрой и удобной конфигурации WiFiManager
- Библиотека ArduinoJson — удобный парсер JSON сообщений
С графическими библиотеками все понятно. Они нужны для работы с OLED дисплеем. WiFiManager — очень удобная библиотечка для настройки подключения WiFi контроллера. В случае входа в режим настроек поднимает на ESP точку доступа и свой минималистичный WEB-сервер, на который переадресует при подключении. Можно запускать в автоматическом режиме, но тогда режим настроек будет запускаться каждый раз, когда нету соединения камерой. Я выбрал вход в режим настроек по длинному нажатию кнопки «BOOT/MODE» и выход по таймауту в 120 сек.
Библиотека WiFiManager удобна еще и тем, что можно добавлять свои поля для настройки (в этом проекте мне не пригодилось), а также обрабатывать события — вход в режим настройки и сохранение параметров настройки.
После того как параметры подключения к камере настроены, программа выполняет соединение, о чем пишет а экранчике. В случае установки соединения программа каждую секунду шлет камере запрос на текущее состояние и отображает на экране изменения. Это сделано для того чтобы можно было отслеживать управления камерой непосредственно с кнопочек на ней.
По кнопке «BOOT/MODE» циклически переключаем три основных режима камеры — «VIDEO«, «PHOTO» и «LOOPS» . Кнопкой «PLAY/STOP» включаем/отключаем запись в режиме «VIDEO» или «LOOPS» и делает запись одиночного фото в режиме «PHOTO«. При режиме включения записи горит красный светодиод. При записи фото однократно моргает.
Также существует дополнительный вход на GPIO14, который по сути дублирует кнопку «PLAY/STOP«. Этот вход нужен для подключения внешнего триггера, которым можно синхронизировать съемку фото для таймлапс снимков с внешним событием. Этот вход я планирую для подключения к 3D принтеру и съемке таймлапс видео печати деталей.
Из дополнительных функций, программа периодически мерит значения входа ADC, куда подключен делитель напрямую от батареи питания, и выдает значком состояние батареи. Программа откалибрована на делители R12=1.6К и R11=10К и литиевую батарею.
К сожалению AS100 не поддерживает выдачу в JSON времени записи и количество снимков в режиме таймлапс. В скетчи эти параметры записываются в переменные, если кто то будет повторять, то на других камерах их также можно выводить на дисплей.
Первое включение или перенастройка камеры производится длинным (более 5 сек) удержанием кнопки BOOT/OPER. По этому действию запускается WiFiManager в режиме настройки WiFi. Он поднимает точку доступа (без пароля!) и, после соединения, позволяет выбрать или прописать имя и пароль соединения к камере SONY. После этого подключение будет всегда происходить в автоматическом режиме после включения камеры.
«Промышленный» образец
Не удержался. Заказывал платки на JLCPCB и на свободное место вставил и для ДУ. Немного доработал схему на основании «опытной эксплуатации». Уменьшил размеры, а на обратной стороне добавил зарядку для лития на TP4056
Дизайн платы получился таким
Вид без дисплей OLED
Спецификация компонентов
- Конденсаторы C1, C2, C3, C4 1206 10 мкФ
- Светодиод D1 1206 зеленый
- Светодиод D2 1206 желтый
- Светодиод D3 1206 красный
- Диод шоттки D3 1N5819 SOD-123
- Разъем J1 MicroUSB
- Резистор R1, R3 1206 1 ом
- Резистор R2 1206 4.7 кОм — 1.2 кОм (определят тог зарядки аккумулятора)
- Резисторы R4, R5, R5, R9, R11, R13 1206 10 кОм
- Резисторы R7, R8, R14 1206 1 кОм
- Резистор R10 1206 100 кОм
- Резистор R12 1206 1.6 кОм
- Кнопка тактовая S1, S2, S3 3x6x2.5
- Переключатель боковой с шагом 2мм
- U1 Контроллер заряда батареи TP4056
- U2 Контроллер ESP8266-12E
- U3 LowDrop стабилизатор 3.3В AP2112
- Разъемы XP1,XP2 PLS с шагом 2.54
- Дисплей OLED 0.91″ SSD1306
- Литиевый аккумулятор любой 300-1500 мАн
Что получилось
Теперь немного применении
Для чего затевался вход внешнего триггера. Захотелось мне попробовать снимать TimeLaps печати на 3D-принтере при помощи моей камеры SONY HDR AS100. Для этого я в контроллере и сделал вход для внешнего триггера. Подавать сигнал на этот вход можно несколькими способами
Подключить к свободному пину контроллера и зашить в прошивку принтера управление этим входом при помощи дополнительной команды G-кода.
Установить OctoPrint с плагином OptoLapse и подключить вход контроллера ДУ к свободному порту Orange PI/Raspberry PI.
Установить дополнительный концевой выключатель, подключенный к контроллеру и отводить для фотографирования каждого кадра головку принтера, чтобы она нажимала на этот выключатель.
Я попробовал 3-й способ:
Быстро на коленке написал скрипт на PHP, который после печати каждого слоя вставляет код отвода головки в позицию концевого выключателя.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<?php $file1 = $argv[1]; $file2 = $argv[2]; if (!file_exists($file1)) { printf("Can't open %s\n",$file1); exit(1); } $flag = 0; $f1 = fopen($file1,"r"); $f2 = fopen($file2,"w"); while( !feof($f1) ){ $s = fgets($f1, 1024); $n = strpos($s,";LAYER:"); if( $n !== false )$flag = 1; if( $flag == 1 ){ $n1 = strpos($s,"G0 "); if( $n1 !== false ){ fprintf($f2, ";TIMELAPSE BEGIN\n"); fprintf($f2,"G10\n"); fprintf($f2, "G91\n"); fprintf($f2, "G0 F1000 Z10\n"); fprintf($f2, "G90\n"); fprintf($f2, "G0 F5000 Y230\n"); fprintf($f2, "G0 F5000 X178 Y230\n"); fprintf($f2, "G4 P1000\n"); fprintf($f2,"%s",$s); fprintf($f2,"G11\n"); fprintf($f2, ";TIMELAPSE END\n"); $flag = 0; } else { fprintf($f2,"%s",$s); } } else { fprintf($f2,"%s",$s); } } fclose($f1); fclose($f2); ?> |
G-код выглядит так:
1 2 3 4 5 6 7 8 9 |
;TIMELAPSE BEGIN G91 G0 F1000 Z10 G90 G0 F5000 Y230 G0 F5000 X178 Y230 G4 P1000 G0 F6000 X93.168 Y92.836 Z0.3 ;TIMELAPSE END |
К сожалению, с ходу разобраться с ретраком принтера не получилось, поэтому первое видео получилось с названием «Печатаем сопли» )))
Но «это уже другая история» …
Исходные тексты, схемотехнику и дизайн плат можно взять на GITHUB
Хм..Извиняюсь-а где статья?
Сорри. Статья была в стадии разработки
Привет Алексей! А ещё можешь такой мультик сделать за денюшку?
Да.
Ответил на почту
Пультик
Прикольно!
В симплифае есть сценарий смены слоя… то есть можно без php обойтись.
А чем собирал отдельные картинки в видео?
Adobe Premiere
Ищу способ управлять видеоплеером в винде через вайфай. Половина уже есть, осталось написать сервер под винду, хотя можно слушать порты через повершелл по идее?
Чтобы не писать свой TCP/IP сервер, на винде поднимаем маленький WEB-сервер (или не маленький) и HTTP пакетами с ESP8266 производим управление
Спасибо, очень помогла твоя статья. Искал способ записи бесконечного таймлапса на видеокамере Sony HDR-CX625 (в камере есть встроенный режим на 300 снимков). (К камере нет TimeRemoteSwitch, хотя у камеры есть Sony Multiport и есть TimeRemoteSwitch JJC TM-F2, но он как и обещал производитель с ней не заработал, хотя я думал что мог бы и работать). Все работает и должно работать на других камерах серии в которых есть WiFi.
В моей версии все проще мне нужно делать снимок раз в минуту.
#include
#include
#include
WiFiMulti WiFiMulti;
void setup() {
Serial.begin(115200);
while (!Serial) continue;
// We start by connecting to a WiFi AP
WiFiMulti.addAP(«DIRECT-KEH3:HDR-CX625», «pass»);
Serial.println(«Waiting for WiFi… «);
while(WiFiMulti.run() != WL_CONNECTED) {
Serial.print(«.»);
delay(500);
}
Serial.println(«WiFi connected»);
Serial.println(«IP address: «);
Serial.println(WiFi.localIP());
delay(500);
HTTPClient http;
http.begin(«http://192.168.122.1:10000/sony/camera»);
http.addHeader(«Content-Type», «application/json»);
http.POST(«{ \»method\»: \»setShootMode\», \»params\»: [\»still\»], \»id\»: 1, \»version\»: \»1.0\» }»);
}
void loop() {
HTTPClient http;
http.begin(«http://192.168.122.1:10000/sony/camera»);
http.addHeader(«Content-Type», «application/json»);
http.POST(«{ \»method\»: \»actTakePicture\», \»params\»: [], \»id\»: 1, \»version\»: \»1.0\» }»);
delay(60000);
}