Shopping Cart

Posts

PTP 2.0 library function turns on Bulb mode on Nikon DSLR camera via USB

Bulb mode activation code screenshot

Bulb mode activation code screenshot


Last week my friend Hans and I spent some time in my lab exploring which features of his Nikon D300 are available via PTP protocol. Hans is working on extended range HDR-capable intervalometer and he needed to find out a way to switch his camera into bulb mode using Arduino board and USB Host shield. After we finished I realized that while bulb mode is not tricky to activate, it is not obvious either and no hints exist in the code and examples showing how to do this. This short article is intended to fill the void.

In PTP, shooting parameters, such as shutter speed, aperture, ISO, etc. are changed by setting certain device property. For each parameter there exists a list of allowed values of this property, each property value corresponding to a parameter value. For some parameters, property and parameter value lists are dynamic. For example, starting and ending aperture values are different for different lenses; additionally, the aperture step can be changed in camera settings. Stepping can also be changed for shutter speed and exposure compensation and this can also happen during PTP session if a photographer decides to switch modes – in this case a property may become unavailable, like shutter speed in aperture priority mode. Therefore, before changing a property value for one of these parameters it is necessary to somehow retrieve a list of available property values.

The property value list retrieval mechanism is slightly different for different cameras. On Canon DSLRs, a special event is generated by the camera and sent back to PTP host at the beginning of the session and also each time camera mode was changed, lens were swapped and so on. The application needs to track those events and constantly maintain current value list for each property. On Nikon DSLR, it is possible to simply get value list for a property any time it is needed. To save memory, the list is not stored but simply requested from the camera each time a property needs changing. It is combined with actual property change in two templates – StepUp and StepDown. If you need to increase, for example, shutter speed – call StepUp. If you need to decrease it, call StepDown.

If you “step up” shutter speed on Nikon DSLR manually, the last 2 values will be 30 seconds and bulb. If you step up shutter speed using StepUp method using Nkremote sketch it will stop at 30 seconds. This happens because bulb mode is not included in the list of available property values for shutter speed but simply defined as 0xffffffff. As a result, StepUp doesn’t know that another value is available. It is still possible, however, to set the property directly and I will show you how to do it.

For the demonstration, I will be modifying Nkremote sketch itself. The psconsole.cpp file contains the menu tree. The “Change Settings” menu contains transitions to menus which change a particular parameter of the camera. The last one, i.e., number nine or “FocusPoint” is not very useful for remote control so I’m going to modify this menu to activate bulb mode instead. The code of ChangeFocusAreaMenu() is as follows:

QState PSConsole::ChangeFocusAreaMenu(PSConsole *me, QEvent const *e) 
{
    switch (e->sig) 
    {
        case Q_ENTRY_SIG:
            PrintMenuTitles(UPDWN_MENU_COUNT, menuUpDown);
            PrintFocusArea();
            return Q_HANDLED();
        case MENU_SELECT_SIG: 
        {
            switch (((MenuSelectEvt*)e)->item_index)
            {
            case 0:
                return Q_TRAN(&PSConsole::ChangeSettingsMenu);
            case 2:
                StepUp<VT_FOCUSAREA>((PTP*)&Nk, NK_DPC_AutofocusArea);
                PrintFocusArea();
                return Q_HANDLED();
            case 1:
                StepDown<VT_FOCUSAREA>((PTP*)&Nk, NK_DPC_AutofocusArea);
                PrintFocusArea();
                return Q_HANDLED();
            } // switch (((MenuSelectEvt*)e)->item_index)
        } // case MENU_SELECT_SIG:
    }
    return Q_SUPER(&PSConsole::Active);
}

Cases 1 and 2 originally change the focus area. I’m commenting down StepUp() and StepDown() and inserting property change operation (lines 3 and 8). The new code will activate bulb mode if you press ’1′ or ’2′ in the terminal.

1
2
3
4
5
6
7
8
9
10
          case 2:
                //StepUp<VT_FOCUSAREA>((PTP*)&Nk, NK_DPC_AutofocusArea);
                Nk.SetDevicePropValue(0xd100, (uint32_t)0xffffffff);
                PrintFocusArea();
                return Q_HANDLED();
            case 1:
                //StepDown<VT_FOCUSAREA>((PTP*)&Nk, NK_DPC_AutofocusArea);
                Nk.SetDevicePropValue(0xd100, (uint32_t)0xffffffff);
                PrintFocusArea();
                return Q_HANDLED();

After you change Nkremote, compile it and load into Arduino board. In a terminal window, choose “Change Settings”, then “FocusPoint”. On the next screen press ’1′ or ’2′, then ’0′ to return to the previous level. Now go to “View Settings”, you should see T:Bulb near the end of the output. To change it back to normal shutter mode go to “Change Settings”, then to the “Shutter Speed”.

Now let’s talk briefly about limitations. First, the bulb mode is only available in “Manual” and “Shutter Priority” modes. In all other modes an attempt to set shutter speed to bulb will be rejected. Another rather annoying limitation is capture command, which doesn’t function in bulb mode ( most Canon DSLRs continue to execute capture when switched to bulb, manually or otherwise). Cable release will work as usual so it is still possible to make a HDR intervalometer which can switch between ‘normal’ and bulb modes – all that is necessary is a digital pin on Arduino, a transistor and a couple of resistors.

This is it for the PTP, bulb mode and Nikons. I hope the information in this article was helpful for you. Enjoy!

Oleg.

Related posts:

  1. Controlling Canon Powershot cameras with Arduino
  2. Using Logitech Extreme 3D Pro joystick with Arduino HID library
  3. Arduino 1.0-compatible USB Host Library released
  4. Google Open Accessory Interface for USB Host Shield Library 2.0 released
  5. USB Host Shield library Version 2.0 released.
  6. Sony PS3 Controller support added to USB Host library
  7. USGlobalsat ND-100S GPS receiver works with USB Host library
  8. Andriod ADK-compatible USB Host Library release.
  9. Bluetooth RFCOMM/SPP service support for USB Host 2.0 Library released!
  10. Developing Arduino code for HID Joystick

44 comments to PTP 2.0 library function turns on Bulb mode on Nikon DSLR camera via USB

  • ysw925

    Hi,
    Can use USB Focus Controler control NIKON camera,such as change ISO,Aperture,etc?
    If of course,Why are there not such product in the market?
    Thank you!

  • John

    Hi,

    I’m trying to keep up with you guys, some time ago (ehh… almost 2 years now) I was trying to control my EOS 20D camera via USB.
    Now I bought myself a other more up to date EOS camera and tried to pick up on things again to control this new one but so far no luck.
    I am running Arduino IDE 1.02 with libraries ‘PTP_2.0′ and ‘USB_Host_Shield_2.0′ installed on my iMac Mountain Lion.
    I’ve also installed QP for Arduino v4.5.02.
    Should the examples compile without any other library or settings?
    I feel somehow silly that after a day of trying, going backwards and forwards, I can’t get most of the examples to compile, what am I missing?

    cheers,
    John

  • John

    Hi Oleg,

    I am able to compile PTPDevInfo and this works beautifully with my USB shield and my EOS/Powershot camera’s.
    (your original shield ‘v1′ that I modified it and after I ordered a new one yesterday in your shop).
    I also tried a fresh installation of the Arduino IDE on a clean/virgin OSX computer with only the libraries installed that where necessary like PTP_2.0, USB_Host_v2.0, QP for Arduino (this one installed in the Arduino.app library) and some other basic libraries.
    But the more advanced programs like EOS camera remote it struggles and doesn’t want to compile.
    Can there be things left that I’m missing?

    Cheers,
    John

    BTW; Am I correct that the biggest change from V1 to v2 hardware is cutting GPX connection and tying MRST to the USB controller from the reset of the Arduino. By doing this the hardware seems to be working and also the one that I have from Sparkfun works with this mod.

    • John

      This is the first error message during compilation;

      EOSCamController.pde: In member function ‘virtual void CamStateHandlers::OnDeviceInitializedState(PTP*)’:
      EOSCamController:536: error: cannot declare variable ‘hnd’ to be of abstract type ‘EosEventHandlers’
      eoseventhandler.h:13: note: because the following virtual functions are pure within ‘EosEventHandlers’:
      /Users/John/Documents/Arduino/libraries/ptp/eoseventparser.h:37: note: virtual void EOSEventHandlers::OnObjectCreated(const EOSEvent*)

      -John

      • I believe it has something to do with IDE version. I’m using 1.0 – try with this version ans see if it makes any difference.

        • John

          Similar error in the same area;

          EOSCamController.cpp: In member function ‘virtual void CamStateHandlers::OnDeviceInitializedState(PTP*)’:
          EOSCamController.pde:-1: error: cannot declare variable ‘hnd’ to be of abstract type ‘EosEventHandlers’
          eoseventhandler.h:13: note: because the following virtual functions are pure within ‘EosEventHandlers’:
          /Users/John/Documents/Arduino/libraries/ptp/eoseventparser.h:37: note: virtual void EOSEventHandlers::OnObjectCreated(const EOSEvent*)

          • This is strange; I need to take a look into this, give me couple of days.

          • Alex

            The problem is that there is one more event handler was added to EOSEventHandler class in the PTP library, but the EOSCamController sample sketch has not been changed since. It is going to be fixed in the next release of the library. Add line:
            virtual void OnObjectCreated(const EOSEvent *evt) {};
            to eoseventhandler.h file found in EOSCamController folder to make it running.

          • J0HN

            Hi Oleg en Alex,

            Getting there…
            I’ve edited the extra line in and now it compiles a lot further then before but it ends with this error;

            core.a(new.cpp.o): In function `operator delete(void*)’:
            X:\arduino-1.0.2\hardware\arduino\cores\arduino/new.cpp:10: multiple definition of `operator delete(void*)’
            QP\qp_port.cpp.o:\\Neelix2\Users\john\My Documents\Arduino\libraries\QP/qp_port.cpp:49: first defined here

            I’ve tried Arduino v1.0 / v1.0.2 and QP v4.3.00 / v4.5.02 and combinations of both.
            Which version of QP should I stick with anyway?
            QP v4.3.00 gave me the result above in both Arduino versions.

            Cheers!

  • ysw925

    Hello,Oleg
    If I want to do some experiments of USB control NIKON camera D90,I should use what library?
    In my opinion should use “felis-USB_Host_Shield_2.0-2be3f61″and”PTP_2.0-master”.Is right
    or wrong?Is there any other library I must want to have?
    Thanks!

  • ysw925

    Can you help me,Thanks!

  • John

    Bingo!

    I’ve added the extra line as Alex suggested and I had commented out some extra lines in the qp_port.cpp
    Now it compiles and runs with Arduino v1.0.2 and QP for Arduino v4.3.00
    ——
    // void operator delete(void *) {
    // Q_ERROR(); // this operator should never be actually called
    // }
    ——
    Thanks both for your help!

    • John, I would really appreciate you help here since at the moment I recieve no reply from Oleg.
      I’ve followed your progress and have made these changes:
      1. Replaced qp_ccp
      2. Commented out these lines in the qp_port.cpp:
      // void operator delete(void *) {
      // Q_ERROR(); // this operator should never be actually called
      // }
      3. Added the following line to eoseventhandler.h file found in EOSCamController folder:
      virtual void OnObjectCreated(const EOSEvent *evt) {};

      Now I’m able to compile all examples except EOSRemote which spits out this error log:

      EOSRemote.cpp: In member function ‘virtual void CamStateHandlers::OnDeviceInitializedState(PTP*)’:
      EOSRemote.pde:-1: error: cannot declare variable ‘hnd’ to be of abstract type ‘EosEventHandlers’
      /eoseventhandlers.h:12: note: because the following virtual functions are pure within ‘EosEventHandlers’:
      C:\Program Files (x86)\arduino-1.0.1\libraries\ptp/eoseventparser.h:37: note: virtual void EOSEventHandlers::OnObjectCreated(const EOSEvent*)

      Can you help me out with this?

  • ysw925

    Hi,
    I want to do some experiments of USB control NIKON camera D90.
    I added librarys “felis-USB_Host_Shield_2.0-2be3f61″and”PTP_2.0-master”base in Arduino v1.0.1.
    When I compile NKEventLab.pde and NKEventMonitor.pde and NKLiveView.pde are successful.
    But when I compile NKRemote.pde is unsuccessful.Because lose files such as qp_port.h,
    Is any librarys I donot add?
    Thanks!

  • ysw925

    Why nobody answer?
    waiting…

  • ysw925

    hello,all
    Let nikon camera into LiveView, What command can do it?
    Thanks!

  • Hannes

    Hi!

    I’m also struggling with this library for 2 days now.
    I’m trying to compile eosHdrCapture and tried as suggested several different verions of the arduino-ide and of the qp-library in all kinds of variants:
    Arduino-ide 1.0.1/1.0.2/1.0.3
    qp-lib: qp_arduino_4.3.00/ 4.5.02/ 4.5.03

    The best solution yet is ArduinoIDE 1.0.1 and qp 4.3.00 with qp_ports.cpp you provided at your site.

    But when I try to compile, I’m still getting errors:
    core.a(new.cpp.o): In function `operator delete(void*)’:
    [...]arduino\cores\arduino/new.cpp:10: multiple definition of `operator delete(void*)’
    [...]arduino-1.0.1\libraries\qp/qp_port.cpp:49: first defined here

    I googled around but couldn’t find a solution…

    Has anybody suggestions for what I could do?
    thanks in advance!

  • ysw925

    Oleg,
    On the basis of you librarys I succeed in making the D90 camera into the liveview mode and also MoveFocus.
    Now I have a question want to your help.When let D90 into liveview mode ,D90 display screen into a blank screen
    and D90 control panel display on “PC”. My question is D90 into liveview mode Can make display screen not into a blank screen?
    Waiting for your help,You only need to answer” Can or NO”.Thank you very much!

    • I don’t think it’s possible. I experimented with several Nikon cameras, they all turn off LCD as well as video out when switched to LiveView from a PC. So basically on Nikons you can move focus but you can’t see it.

  • ysw925

    I see ,thank you!

  • Hi Oleg,

    thank you for documenting all of the PTP commands for the Canon and Nikon cameras.

    Have you had any success switching the Canon 5D MkII or 7D into BULB mode while leaving the Mode dial in MANUAL mode. Typically this is for extended HDR work to avoid touching the camera to switch from Manual to Bulb mode when exposures over 30 seconds are required as part of the exposure range.

    I know it can be done as I use a programme called GBTimelapse which controls my 5D MkII via a usb tether and I can pretty much ignore what the mode dial is physically set to and use the software to switch modes.

    best regards and happy new year
    Kev Lewis

  • Thank you Oleg, your background knowledge would be appreciated

    Kev

  • Ralf Nolte

    hi oleg,

    some time ago i baught the usb-host shield from solarbotics, it says rev 1.21.

    i’m trying to get it to run on a freeduino, mega328, externally powered, with the usbhostlib 2 (from github)
    when running the test-script, i get:

    Press RESET to restart test
    Circuits At Home 2011
    USB Host Shield Quality Control Routine
    Reading REVISION register… Die revision 03
    SPI long test. Transfers 1MB of data. Each dot is 64K
    Test failed. Value written: 01 read: 00
    Unrecoverable error – test halted!!
    0×55 pattern is transmitted via SPI
    Press RESET to restart test

    can i get the shield running?

    best regards,
    ralf.

  • Ralf Nolte

    Rehi,
    Works like a charm now, thanks for your great work!

    Best,
    Ralf

  • frank b

    I having some trouble getting the EosCamcontroller to compile.
    Arduino version 1.0.3 and using arduino qp 4.3.

    I added the line virtual void OnObjectCreated(const EOSEvent *evt) {};
    to eoseventhandler.h file found in EOSCamController as described above.

    I commented out// void operator delete(void *) {
    // Q_ERROR(); // this operator should never be actually called
    // } in qp_port.cpp as noted above.

    than commented out void operator delete(void *) {
    Q_ERROR();

    now I am left with the following error messages:

    qp/qp.cpp.o: In function `QHsm::dispatch(QEvent const*)’:
    /Users/fsb/Documents/Arduino/libraries/qp/qp.cpp:235: undefined reference to `Q_onAssert’
    /Users/fsb/Documents/Arduino/libraries/qp/qp.cpp:246: undefined reference to `Q_onAssert’
    /Users/fsb/Documents/Arduino/libraries/qp/qp.cpp:330: undefined reference to `Q_onAssert’
    qp/qp.cpp.o: In function `QHsm::init(QEvent const*)’:
    /Users/fsb/Documents/Arduino/libraries/qp/qp.cpp:111: undefined reference to `Q_onAssert’
    /Users/fsb/Documents/Arduino/libraries/qp/qp.cpp:134: undefined reference to `Q_onAssert’

    Obviously I am doing something stupid, any suggestions for help?

    fsb

  • frank b

    cleaned up libraries
    Everything now compiles with IDE 1.01 and 1.03
    Only cannot load Eoscamcontroller (get avrdude stk500 error)
    so still working on my canon. However, NKremote works great with my
    Nikon D300.

    This is great Oleg, Nice work.
    fsb

  • Hi,
    To all of you that have problem compiling the library. Here is a short guide I wrote on how to do so:

    These are the steps you need to do in order to compile the library:

    Download the PTP library: https://github.com/felis/PTP_2.0
    Extract and rename the folder to: PTP_20

    Download the QP library version 4.3.00: http://sourceforge.net/projects/qpc/files/QP_Arduino/4.3.00/
    Extract the QP library and navigate to the libraries/qp folder.
    Now replace the qp_port.cpp with the file found here: http://www.circuitsathome.com/chome_downloads/qp_port.cpp

    Now comment out the following function:

    void operator delete(void *) {
    Q_ERROR(); // this operator should never be actually called
    }

    Now put these files inside the PTP_20 directory.

    Now open PTP_20/ptpdebug.h and notice these lines:

    #include "../USBHost/printhex.h"
    #include "../USBHost/hexdump.h"
    #include "../USBHost/message.h"

    You will have to change the USBHost directory to the name of your USB Host Shield library directory. For instance I had to change mine to:

    #include "../USB_Host_Shield_20/printhex.h"
    #include "../USB_Host_Shield_20/hexdump.h"
    #include "../USB_Host_Shield_20/message.h"

    Open eoseventhandler.h in PTP_20/examples/Canon_EOS/EOSCamController and eoseventhandlers.h in PTP_20/examples/Canon_EOS/EOSRemote and then add the following function:

    virtual void OnObjectCreated(const EOSEvent *evt) {};

    So the class end up looking like this:

    class EosEventHandlers : public EOSEventHandlers
    {
    public:
    virtual void OnPropertyChanged(const EOSEvent *evt);
    virtual void OnAcceptedListSize(const EOSEvent *evt, const uint16_t size);
    virtual void OnPropertyValuesAccepted(const EOSEvent *evt, const uint16_t index, const uint32_t &val);
    virtual void OnObjectCreated(const EOSEvent *evt) {};
    };

    Now finally put the PTP_20 directory inside the Arduino libraries folder.
    Now you should be able to compile the library.

  • Congratulations Oleg for your works !!

    I have a question :

    It is possible to get speed, aperture, White balance settings, and set it,
    from the DSLR Nikon camera ?

    Have you an PDE sketch exemple ?

    I work on a project “Photographer Tools”, that is a color meter, exposure meter,
    flash meter, and I search a solution (Actually I create a computer Program with the SDK Nikon)
    to get and set directly the parameters mesured by my “Photographer Tools” on the DSLR.

    This is the link of my project :

    The good way for me,
    is to use a remote module (with arduino Nano for example and bluetooth or wifi connection)
    to get and set DSLR exposure values from my “Photographer Tools”.

    If you have any arduino solution ?

    Thanks for your reading.
    Regards.

  • Hi all,
    I have two little questions.
    The usb host shield V20 is compatible with the “USB Host Shield for Arduino Pro Mini” ?
    The arduino sketch “NKRemote” work with this shield and arduino pro mini ?
    It is for create a very smaller transceiver with NRF24L01 Wifi module.

  • Norbert

    Hi,

    I’m having a bunch of trouble with PTPCapture with the new Nikon J3 (And probably other V*/J* series). Have had no problems with the software in the past and have gotten it working on other nikons ranging from Coolpix to DSLR’s.

    When hooked up, it gets to the “Camera Connected” mark, then gets stuck- no image is taken. Identical un-altered sketch runs fine on others. PTP DevInfo works fine too (attached below) and it looks to me that it should support capture image.

    Moreover, the “Image Capture” application on Mac OS is able to remotely trigger the camera without issues!

    Any ideas? Thanks!

    PTPDevInfo:

    Start
    Camera connected

    Std.Ver.: 0×100
    Vendor Ext. ID: 0×6(Microsoft)

    Vend.Ext.Ver.: 0×64
    microsoft.com: 1.0
    Func.Mode: 0x21E0

    Operations supported:
    1001 GetDeviceInfo
    1002 OpenSession
    1003 CloseSession
    1004 GetStorageIDs
    1005 GetStorageInfo
    1006 GetNumObjects
    1007 GetObjectHandles
    1008 GetObjectInfo
    1009 GetObject
    100A GetThumb
    100B DeleteObject
    100C SendObjectInfo
    100D SendObject
    100E InitiateCapture
    100F FormatStore
    1014 GetDevicePropDesc
    1015 GetDevicePropValue
    1016 SetDevicePropValue
    101B GetPartialObject
    90C0 Vendor defined
    90C1 Vendor defined
    90C2 Vendor defined
    90C3 Vendor defined
    90C4 Vendor defined
    90C7 Vendor defined
    90C8 Vendor defined
    9201 Vendor defined
    9202 Vendor defined
    9203 Vendor defined
    9207 Vendor defined
    9801 GetObjectPropsSupported
    9802 GetObjectPropDesc
    9803 GetObjectPropValue
    9805 GetObjectPropList

    Events supported:
    4001 CancelTransaction
    4002 ObjectAdded
    4004 StoreAdded
    4005 StoreRemoved
    4006 DevicePropChanged
    4008 DeviceInfoChanged
    4009 RequestObjectTransfer
    400A StoreFull
    400C StorageInfoChanged
    400D CaptureComplete

    Device properties supported:
    5001 BatteryLevel
    5004 CompressionSetting
    5007 FNumber
    500E ExposureProgramMode
    5011 DateTime
    D303 Vendor defined
    D406 Session_Initiator_Version_Info
    D407 Perceived_Device_Type

    Capture formats:
    3801 EXIF_JPEG
    3000 Undefined

    Image Formats:
    3000 Undefined
    3001 Association
    3002 Script
    3006 DPOF
    300D QT
    3801 EXIF_JPEG
    380D TIFF

    Manufacturer: Nikon Corporation
    Model: J3
    Device ver.: Ver.1.0001

Leave a Reply

  

  

  

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">