В советские времена нас учили, что кадры решают все. Может быть. Довелось мне поработать и там и тут и могу с уверенностью сказать, что кадры это только ступеньки к успеху. Все решает управление. В этой статье постараюсь рассказать как шаг за шагом сделать универсальный пульт дистанционного управления для камеры, позволяющий менять настройки камеры.
Шаг первый - ИК пульт.
Вы случайно под новый год не решили поменять телевизор или выбросить старый 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(); } }
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
IR_Shutter.pde
#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, запустите пару скриптов из командной строки. Camera_Properties.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 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>
получим список всех Properties (свойства) камеры.
Display_Detailed_Property.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 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>
получим список всех Properties и все возможные value (значение). Обратите внимание на два свойства "F Number" - диафрагма и "Exposure Time" — выдержка, значения этих свойств отличаются от привычных фотографу. Чтобы установить выдержку в 1 секунду нужно отправить в камеру значение 10000, для диафрагмы F8 нужно отправить значение 800. Диафрагму нужно умножить на 100. С выдержкой искомое значение получается несколько сложнее. Чтобы установить выдержку 1/160 нужно 10000/160 и отбросить дробную часть. Получим 62.
(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>
("White Balance").value
("F Number").value
("Exposure Time").value
("Exposure Mode").value
("Exposure Index").value
("Exposure Compensation").value
IR_WIAComander.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 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(); } }
Чтобы не работать постоянно, из командной строки написал программу IR_WIAComander.7z . По логике работы программа ничем не отличается от скрипта , добавлено несколько проверок на подключение камеры и Arduino.
Но, чтобы программа работала, в системе нужно зарегистрировать библиотеку работы с COM Port.
1. загрузить MSCOMM32.ocx
2. copy MSCOMM32.ocx в C:\Windows\System32\
3. открыть cmd как администратор
4. > regsvr32 C:\Windows\System32\MSCOMM32.ocx
5. загрузить vbctrls.zip
6. добавить лицензию в регистер.
Надеюсь, что описал не очень запутано.
Удачи в эксперементах.
© Andrew Buckin.
Shutterstock Dreamstime
Fotostream http://www.flickr.com
TODO:
Multiple FTDI Chip.
Detect Arduino Bootloader
Send Properties to Arduino.
Keine Kommentare:
Kommentar veröffentlichen