![]() |
|||
|
Вход на сайт
Популярные блоги Обсуждаемые блоги Последние комментарии |
Главная / Блоги - все записи / Блог ka_ru / Arduino, PC, Camera.
Arduino, PC, Camera. Вступление.
Статья для тех кто держит паяльник и чуть, чуть программируют. Попробуйте результат того стоит. В советские времена нас учили, что кадры решают все. Может быть.
Довелось мне поработать и там и тут и могу с уверенностью сказать, что кадры это только ступеньки к успеху. Все решает управление. В этой статье постараюсь рассказать как шаг за шагом сделать универсальный пульт дистанционного управления для камеры, позволяющий менять настройки камеры. Шаг первый - ИК пульт.
Вы случайно под новый год не решили поменять телевизор или выбросить старый DVD проигрыватель. Если нет, то жаль, так бы вам очень пригодился дистанционный пульт. У меня таких накопилось штук восемь. Но это не все, чем полезна старая электроника. Вооружившись отверткой можно вытащить ИК приемник. Приемник обычно размещаются под передней крышкой прибора.
Подойдет любой IR приемник TSOP17, TSOP13, SM3374, TK19 и им подобные. После того, как приемник найден, собираем маленькую схему на Arduino и приступаем к изучению пульта управления.
Пульт желательно использовать не самый новый, но и не самый старый, чтоб было максимум рабочих кодов. Для сканирования нужно загрузить библиотеку IRremote. Создать Sketch для Arduino IR_code_to_232.pde
#include <IRremote.h> int RECV_PIN = 2; int STATUS_PIN = 13; IRrecv irrecv(RECV_PIN); decode_results results; void setup() { Serial.begin(115200); irrecv.enableIRIn(); // Start the receiver } int codeType = -1; // The type of code void loop() { if (irrecv.decode(&results)) { codeType = results.decode_type; if (codeType != UNKNOWN) { if (results.value != REPEAT) { Serial.println(results.value, HEX); } } irrecv.resume(); } } и загрузить код в Arduino. Открыть терминал и, нажимая кнопки на пульте управления, записать код для каждой кнопки. Для ленивых как я. :) открываем командное окно
Start > «cmd», перейти в рабочую директорию, туда же скопировать программу RS232read.7z
> RS232read.exe 7 115200 > rs232.txt.
Где 7 - номер COM порта, 115200 - скорость, rs232.txt файл куда сохраняются принимаемые данные. После этого открыть rs232.txt и скопировать коды в Sketch должно получиться вот так.
#define button1 0xFF906F #define button2 0xFFB847 #define button3 0xFFF807 #define button4 0xFFB04F #define button5 0xFF9867 #define button6 0xFFD827 #define button7 0xFF8877 #define button8 0xFFA857 #define button9 0xFFE817 #include <IRremote.h> #define button1 0xFF906F #define button2 0xFFB847 #define button3 0xFFF807 #define button4 0xFFB04F #define button5 0xFF9867 #define button6 0xFFD827 #define button7 0xFF8877 #define button8 0xFFA857 #define button9 0xFFE817 const int Shot = 11; const int Focus = 12; int RECV_PIN = 2; int STATUS_PIN = 13; IRrecv irrecv(RECV_PIN); decode_results results; void setup() { Serial.begin(115200); irrecv.enableIRIn(); // Start the receiver pinMode(STATUS_PIN, OUTPUT); pinMode(Shot, OUTPUT); pinMode(Focus, OUTPUT); } int codeType = -1; // The type of code void loop() { digitalWrite(STATUS_PIN, LOW ); if (irrecv.decode(&results)) { codeType = results.decode_type; if (codeType != UNKNOWN) { if (results.value != REPEAT) { if (results.value == button1) { digitalWrite(Focus, HIGH); digitalWrite(Shot, HIGH); delay(1000); // waits for a second digitalWrite(Focus, LOW); digitalWrite(Shot, LOW); } if (results.value == button2) { Serial.println("Button 2"); } if (results.value == button3) { Serial.println("Button 3"); } if (results.value == button4) { Serial.println("Button 4"); } if (results.value == button5) { Serial.println("Button 5"); } if (results.value == button6) { Serial.println("Button 6"); } if (results.value == button7) { Serial.println("Button 7"); } if (results.value == button8) { Serial.println("Button 8"); } if (results.value == button9) { Serial.println("Shutter"); } //Serial.println(results.value, HEX); //irrecv.resume(); // Receive the next value } } digitalWrite(STATUS_PIN, HIGH); irrecv.resume(); } } Шаг второй - Windows Image Acquisition (WIA).
Почему WIA? Потому что позволяет управлять камерой, не углубляясь в Nikon SKD или Canon SDK. Свободно распространяется Microsoft, управлять можно из VBScript. Чтобы лучше понять, что может WIA, запустите пару скриптов из командной строки.
' before!!!! run cmd as Administrator and "cscript.exe //H:cscript" <job> <reference object="wia.DeviceManager" /> <object id="DevMan" progid="Wia.DeviceManager" /> <object id="dlg" progid="WIA.CommonDialog" /> <script language="VBScript"> ' Copyright 2011 All Rights Reserved ' Use and distribution for non-commercial purposes permitted ' http://karu2003.blogspot.com/ Option Explicit Dim WiaDev 'As wia.Device Dim WiaItm 'As wia.Item Dim dev 'As Device Dim i 'As Integer Dim s 'As String Dim p 'As Property Set dev = dlg.ShowSelectDevice For Each p In dev.Properties s = p.Name '& "(" & p.PropertyID & ")" 'MsgBox s WScript.echo s Next </script> </job> ' before!!!! run cmd as Administrator and "cscript.exe //H:cscript" <job> <reference object="wia.DeviceManager" /> <object id="DevMan" progid="Wia.DeviceManager" /> <object id="dlg" progid="WIA.CommonDialog" /> <script language="VBScript"> ' Copyright 2011 All Rights Reserved ' Use and distribution for non-commercial purposes permitted ' http://karu2003.blogspot.com/ Option Explicit Dim WiaDev 'As wia.Device Dim WiaItm 'As wia.Item Dim dev 'As Device Dim p 'As Property Dim s 'As String Dim i 'As Integer Set dev = dlg.ShowSelectDevice For Each p In dev.Properties s = p.Name & "(" & p.PropertyID & ") = " If p.IsVector Then s = s & "[vector of data]" Else s = s & p.Value If p.SubType <> UnspecifiedSubType Then If p.Value <> p.SubTypeDefault Then s = s & "(Default = " & p.SubTypeDefault & ")" End If End If End If If p.IsReadOnly then s= s & " [READ ONLY]" else Select Case p.SubType Case FlagSubType s = s & " [ valid flags include:" For i = 1 To p.SubTypeValues.Count s = s & p.SubTypeValues(i) If i <> p.SubTypeValues.Count Then s = s & ", " End If Next s = s & " ]" Case ListSubType s = s & " [ valid values include:" For i = 1 To p.SubTypeValues.Count s = s & p.SubTypeValues(i) If i <> p.SubTypeValues.Count Then s = s & ", " End If Next s = s & " ]" Case RangeSubType s = s & " [ valid values in the range from " & _ p.SubTypeMin & " to " & p.SubTypeMax & _ " in increments of " & p.SubTypeStep & " ]" Case Else 'UnspecifiedSubType End Select End If 'MsgBox s WScript.echo s Next </script> </job> (1,"6400"); (2,"4000"); (3,"3200"); (4,"2500"); (5,"2000"); (6,"1600"); (8,"1250"); (10,"1000"); (12,"800"); (13,"750"); (15,"640"); (20,"500"); (25,"400"); (28,"350"); (31,"320"); (40,"250"); (50,"200"); (55,"180"); (62,"160"); (80,"125"); (100,"100"); (111,"90"); (125,"80"); (166,"60"); (200,"50"); (222,"45"); (250,"40"); (333,"30"); (400,"25"); (500,"20"); (666,"15"); (769,"13"); (1000,"10"); (1250,"8"); (1666,"6"); (2000,"5"); (2500,"4"); (3333,"3"); (4000,"2.5"); (5000,"2"); (6250,"1.6"); (6666,"1.5"); (7692,"1.3"); (10000,"1\""); (13000,"1.3\""); (15000,"1.5\""); (16000,"1.6\""); (20000,"2\""); (25000,"2.5\""); (30000,"3\""); (40000,"4\""); (50000,"5\""); (60000,"6\""); (80000,"8\""); (100000,"10\""); (130000,"13\""); (150000,"15\""); (200000,"20\""); (250000,"25\""); (300000,"30\""); ' before!!!! run cmd as Administrator and "cscript.exe //H:cscript" <job> <reference object="wia.DeviceManager" /> <object id="DevMan" progid="Wia.DeviceManager" /> <object id="dlg" progid="WIA.CommonDialog" /> <script language="VBScript"> ' Copyright 2011 All Rights Reserved ' Use and distribution for non-commercial purposes permitted ' http://karu2003.blogspot.com/ Option Explicit Dim WiaDev 'As wia.Device Set WiaDev = dlg.ShowSelectDevice WiaDev.properties("Exposure Time").value = 62 WiaDev.properties("F Number").value = 800 </script> </job> и камера поменяет экспозицию на 1/160 F8. Очень важный момент: количество свойств и их значения могут меняться от камеры к камере и они могут быть только для чтения. Так что, перед тем, как изменять какие-либо свойства, убедитесь, что они доступны для записи.
Шаг три — Arduino > WIA > Camera.
Первым делом организуем срабатывание затвора по пути Arduino > PC > Camera. Для этого загрузим Sketch IR_Shutter.pde где на код кнопки «1» камера срабатывать на прямую от Arduino, а на код кнопки «9» Arduino будет отсылать в компьютер «Shutter». Со стороны компьютера из командной строки запустим скрипт Shutter.wsf
' before!!!! run cmd as Administrator and "cscript.exe //H:cscript" <job> <reference object="wia.DeviceManager" /> <object id="DevMan" progid="Wia.DeviceManager" /> <object id="dlg" progid="WIA.CommonDialog" /> <script language="VBScript"> ' Copyright 2011 All Rights Reserved ' Use and distribution for non-commercial purposes permitted ' http://karu2003.blogspot.com/ Option Explicit Dim WiaDev 'As wia.Device Const ForReading = 1 dim fso dim com dim s Dim strPortName' As String strPortName = GetComPort Set fso = CreateObject("Scripting.FileSystemObject") Set com = fso.OpenTextFile(strPortName & ":115200,N,8,1", ForReading) Set WiaDev = dlg.ShowSelectDevice WScript.echo "Shutter Camera Control with Arduino Script 1.0 " WScript.echo "Copyright 2011 All Rights Reserved" WScript.echo "Use and distribution for non-commercial purposes permitted" WScript.echo "http://karu2003.blogspot.com/" Wscript.echo "Controlling " & WiaDev.Properties("Description").Value ' set raw WiaDev.Properties("Format").Value = "{B96B3CA9-0728-11D3-9D7B-0000F81EF32E}" Wscript.echo "Shooting in RAW Format" ' set jpg 'WiaDev.Properties("Format").Value = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}" 'Wscript.echo "Shooting in JPG Format" WScript.echo "Start to read data from " & strPortName WScript.echo "Press Ctrl-Break to exit" Do While 1 Do While com.AtEndOfStream <> True WScript.Sleep(100) s = com.ReadLine 'WScript.echo (s) If s = "Shutter" Then WiaDev.ExecuteCommand (wiaCommandTakePicture) WScript.echo (s) End If Loop Loop com.Close() '************************************************************************ Function GetComPort() Dim strComputer Dim objWMIService Dim colItems Dim objItem Dim objRgx 'As RegExp Dim objRegMatches 'As MatchCollection Dim strDevName GetComPort = "" strComputer = "." Set objWMIService = GetObject( _ "winmgmts:\\" & strComputer & "\root\cimv2") Set colItems = objWMIService.ExecQuery _ ("Select * from Win32_PnPEntity") For Each objItem In colItems If ("FTSER2K" = objItem.Service) And ("FTDI" = objItem.Manufacturer) Then set objRgx = CreateObject("vbScript.RegExp") strDevName = objItem.Name objRgx.Pattern = "COM[0-9]+" Set objRegMatches = objRgx.Execute(strDevName) If objRegMatches.Count = 1 Then GetComPort = objRegMatches.Item(0).Value Else End If End If Next End Function ' ******************************************************************** </script> </job> Теперь у нас есть две возможности электорального спуска затвора и все с одного пульта управления. Немного изменив код, можно добавить сохранение снятого кадра прямо на компьютер. Но об этом в другой раз. Информацию, как это сделать, можно найти на DIYPhotoBits.com. Теперь осталось изменить пару строчек исходного кода в скрипте и Arduino и получится универсальный командный пульт. Но перед этим стоит разобраться, какие свойства камеры можно изменять. Для своих фото экспериментов - макро, HDRi, предметки мне хватает шести основных:
("White Balance").value
("F Number").value
("Exposure Time").value
("Exposure Mode").value
("Exposure Index").value
("Exposure Compensation").value
' before!!!! run cmd as Administrator and "cscript.exe //H:cscript" <job> <reference object="wia.DeviceManager" /> <object id="DevMan" progid="Wia.DeviceManager" /> <object id="dlg" progid="WIA.CommonDialog" /> <script language="VBScript"> ' Copyright 2011 All Rights Reserved ' Use and distribution for non-commercial purposes permitted ' http://karu2003.blogspot.com/ Option Explicit Dim WiaDev 'As wia.Device Const ForReading = 1 dim fso dim com dim s Dim strPortName' As String Dim k strPortName = GetComPort Set fso = CreateObject("Scripting.FileSystemObject") Set com = fso.OpenTextFile(strPortName & ":115200,N,8,1", ForReading) Set WiaDev = dlg.ShowSelectDevice WScript.echo "Shutter Camera Control with Arduino Script 1.0 " WScript.echo "Copyright 2011 All Rights Reserved" WScript.echo "Use and distribution for non-commercial purposes permitted" WScript.echo "http://karu2003.blogspot.com/" Wscript.echo "Controlling " & WiaDev.Properties("Description").Value ' set raw WiaDev.Properties("Format").Value = "{B96B3CA9-0728-11D3-9D7B-0000F81EF32E}" Wscript.echo "Shooting in RAW Format" ' set jpg 'WiaDev.Properties("Format").Value = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}" 'Wscript.echo "Shooting in JPG Format" WScript.echo "Start to read data from " & strPortName WScript.echo "Press Ctrl-Break to exit" Do While 1 Do While com.AtEndOfStream <> True s = com.ReadLine k = Len(s) 'WScript.echo (s) If s = "Shutter" Then WiaDev.ExecuteCommand (wiaCommandTakePicture) WScript.echo (s) End If If Left(s,2) = "WB" Then WiaDev.properties("White Balance").value = CDbl(Mid(s,3,k-2)) End If If Left(s,2) = "FN" Then WiaDev.properties("F Number").value = CDbl(Mid(s,3,k-2)) End If If Left(s,2) = "ET" Then WiaDev.properties("Exposure Time").value = CDbl(Mid(s,3,k-2)) End If If Left(s,2) = "EM" Then WiaDev.properties("Exposure Mode").value = CDbl(Mid(s,3,k-2)) End If If Left(s,2) = "EI" Then WiaDev.properties("Exposure Index").value = CDbl(Mid(s,3,k-2)) End If If Left(s,2) = "EC" Then WiaDev.properties("Exposure Compensation").value = CDbl(Mid(s,3,k-2)) End If WScript.Sleep(100) Loop Loop com.Close() '************************************************************************ Function GetComPort() Dim strComputer Dim objWMIService Dim colItems Dim objItem Dim objRgx 'As RegExp Dim objRegMatches 'As MatchCollection Dim strDevName GetComPort = "" strComputer = "." Set objWMIService = GetObject( _ "winmgmts:\\" & strComputer & "\root\cimv2") Set colItems = objWMIService.ExecQuery _ ("Select * from Win32_PnPEntity") For Each objItem In colItems If ("FTSER2K" = objItem.Service) And ("FTDI" = objItem.Manufacturer) Then set objRgx = CreateObject("vbScript.RegExp") strDevName = objItem.Name objRgx.Pattern = "COM[0-9]+" Set objRegMatches = objRgx.Execute(strDevName) If objRegMatches.Count = 1 Then GetComPort = objRegMatches.Item(0).Value Else End If End If Next End Function ' ******************************************************************** </script> </job> #include <IRremote.h> //WIA Format //("White Balance").value = //("F Number").value = //("Exposure Time").value = //("Exposure Mode").value = //("Exposure Index").value = //("Exposure Compensation").value = const char* WB = "WB"; //"White Balance"; const char* FN = "FN"; //"F Number"; const char* ET = "ET"; //"Exposure Time"; const char* EM = "EM"; //"Exposure Mode"; const char* EI = "EI"; //"Exposure Index"; const char* EC = "EC"; //"Exposure Compensation"; #define button1 0xFF906F #define button2 0xFFB847 #define button3 0xFFF807 #define button4 0xFFB04F #define button5 0xFF9867 #define button6 0xFFD827 #define button7 0xFF8877 #define button8 0xFFA857 #define button9 0xFFE817 const int Shot = 11; const int Focus = 12; int RECV_PIN = 2; int STATUS_PIN = 13; String sProperties; IRrecv irrecv(RECV_PIN); decode_results results; void setup() { Serial.begin(115200); irrecv.enableIRIn(); // Start the receiver pinMode(STATUS_PIN, OUTPUT); pinMode(Shot, OUTPUT); pinMode(Focus, OUTPUT); } int codeType = -1; // The type of code void loop() { digitalWrite(STATUS_PIN, LOW ); if (irrecv.decode(&results)) { codeType = results.decode_type; if (codeType != UNKNOWN) { if (results.value != REPEAT) { if (results.value == button1) { digitalWrite(Focus, HIGH); digitalWrite(Shot, HIGH); delay(1000); // waits for a second digitalWrite(Focus, LOW); digitalWrite(Shot, LOW); } if (results.value == button2) { sProperties = FN; sProperties = sProperties + "800"; Serial.println(sProperties); delay(100); sProperties = ET; sProperties = sProperties + "62"; Serial.println(sProperties); } if (results.value == button3) { sProperties = FN; sProperties = sProperties + "400"; Serial.println(sProperties); delay(100); sProperties = ET; sProperties = sProperties + "166"; Serial.println(sProperties); } if (results.value == button4) { Serial.println("Button 4"); } if (results.value == button5) { Serial.println("Button 5"); } if (results.value == button6) { Serial.println("Button 6"); } if (results.value == button7) { Serial.println("Button 7"); } if (results.value == button8) { Serial.println("Button 8"); } if (results.value == button9) { Serial.println("Shutter"); } //Serial.println(results.value, HEX); //irrecv.resume(); // Receive the next value } } digitalWrite(STATUS_PIN, HIGH); irrecv.resume(); } } Вот и все, что нужно. Дальше каждый расширяет код под Arduino под свои потребности. Чтобы не работать постоянно, из командной строки написал программу IR_WIAComander.7z . По логике работы программа ничем не отличается от скрипта , добавлено несколько проверок на подключение камеры и Arduino.
Но, чтобы программа работала, в системе нужно зарегистрировать библиотеку работы с COM Port.
2. copy MSCOMM32.ocx в C:\Windows\System32\
3. открыть cmd как администратор
4. > regsvr32 C:\Windows\System32\MSCOMM32.ocx
5. загрузить vbctrls.zip
6. добавить лицензию в регистер.
Надеюсь, что описал не очень запутано.
Удачи в эксперементах.
© Andrew Buckin.
TODO:
Multiple FTDI Chip.
Detect Arduino Bootloader
Send Properties to Arduino.
Комментарии03.01.2012 2:56 Спасибо, интересная статья. Полагаю, многим читателям помогут сориентироваться в материале вот эти две ссылки (вторая совершенно не уникальна и дана просто для ознакомления): http://ru.wikipedia.org/wiki/Arduino http://www.amazon.com/Arduino-Nano-v3-0/dp/B003YVL34O 03.01.2012 4:24 Спасибо, познавательно. Паяльник в руках держу, с программированием проблемы)))) А возможно вместо ИК управления, сделать управление по Wi-Fi?(родное решение стоит вовсе не гуманно) мне просто нужно достаточно удалённое управление фотокамерой для будущего проекта. 03.01.2012 7:46 Можно и радио подключит. Пара радио-модулей есть в тумбочке. Сейчас модули стоят не дорого 5-10€. Если на выходных время будет расскажу как. Только надо подумать как сделать все мобильное и не много паять. 03.01.2012 9:30 DwMan, почти угадали, аппарат будет летательный(в проекте, но уже не вертолёт) А возможно найти радиомодуль с дальностью метров 300? чтобы была возможность менять экспозицию на камере с ноутбука. Я видел у одного кажется австралийца в блоге управление камерой по Wi-Fi, но дальность смешная. 03.01.2012 9:53, изменен 03.01.2012 10:09 Все зависит от частоты и антенны. 300 метров прямой видимости может любой. Я бы посоветовал 433Мгц. WiFi будет много потреблять. Я пробовал по WiFi на воде, лодка, два километра с метровой антенной на берегу и 7 дБ антенна на лодке. Если для самолета или вертолета. Я бы посмотрел систему на ангстреме, плата потребляют до 2Вт есть библиотеки gPhoto2 и радио модем на 433МГц до 100мВт. Но можно WiFi но модули потребляют до 1Вт. 03.01.2012 10:09, изменен 03.01.2012 10:10 Летательный аппарат будет управляться по радио(2,4) Макс высота метров 500( скорее от 100 до 250) С учётом полётного времени минут 10, то потребление не особо смущает Li-Po батареи можно заряжать большими токами, да и стоимость батарей на сегодня-доступная, главное вес девайса. Если Вы можете подсказать гоовое решение или около того будет замечательно, но в принципе готов в разумных пределах платить за рабочее решение-управление камерой с земли(всмысле какие устройства нужны и программа под ардуино. 03.01.2012 21:25 О цене лучше в личку. Реальных вариантом может быть два. Очень маленький контроллер и embedded Linux. Вариант с Linux у меня работает. Управлять можно через радио(433М) и WiFi(2.4Г). Если использовать для летательного аппарата нужно оптимизировать вес и потребление. У Linux очень большое достоинство не надо разбираться с PTP протоколом, минус - цена и время загрузки системы. У маленького контроллер вес маленький, габариты маленькие, но может понадобиться адаптация программ под производителя камеры. Последний вариант у меня в разработке и пока не готов для публикации.
|
||
|
|||
|
2012 © Photokaravan.com Все права защищены |
Главная | Галерея | Конкурсы | Блоги | Форум | ||