To use Raspberry PI to control Nikon DSLRs (or in general any PTP camera) I turned to my own child library libptp2 and its companion tool ptpcam.
ptpcam is much, much smaller and simpler tool than gphoto2 that is also build around libptp2 source code hence in my humble opinion better suited for small device like RPI.

D3300

To compile libptp2 on Raspberry PI one has to install following dependencies:

apt-get -y install build-essential &&
apt-get -y install libtool &&
apt-get -y install automake &&
apt-get -y install pkg-config &&
apt-get -y install subversion &&
apt-get -y install libusb-dev

Then checkout the current source code:

svn checkout svn://svn.code.sf.net/p/libptp/code/trunk libptp-code

Compile the libptp2 and its companion tool:

cd libptp-code

./autogen.sh
./configure
make

And finally install:

sudo make install 
sudo ldconfig

Make sure that ld.so.conf contains the destination path of libptp2 (/ur/local/lib in this case):

# grep /usr/local/ /etc/ld.so.conf.d/*
/etc/ld.so.conf.d/libc.conf:/usr/local/lib

Now the fun begins. When ptpcam is properly build and installed you should be able to access the camera. If you see something like this:

# ptpcam -l

Found no PTP devices

Make sure that you properly connected the camera and the user you run ptpcam has proper permissions to access USB devices. If you stumble upon something like:

# ptpcam -l

Listing devices...
bus/dev vendorID/prodID device model
ERROR: Could not open session!
Try to reset the camera.

# dmesg | tail
[829332.584482] usb 1-1.5.1: new full-speed USB device number 46 using dwc_otg
[829332.689240] usb 1-1.5.1: New USB device found, idVendor=04b0, idProduct=040e
[829332.689259] usb 1-1.5.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[829332.689271] usb 1-1.5.1: Product: NIKON DSC D70s
[829332.689282] usb 1-1.5.1: Manufacturer: NIKON
[829336.094289] usb 1-1.5.1: usbfs: interface 0 claimed by usbfs while 'ptpcam' sets config #1
[829336.094598] usb 1-1.5.1: usbfs: process 8416 (ptpcam) did not claim interface 0 before use

Try to wait 30-60s after connectign the camera and before accessing it with ptpcam or try to use the -r switch to reset the camera.

If everything goes well you should be able to see your camera:

# ptpcam -l 

Listing devices...
bus/dev vendorID/prodID device model
001/031 0x04B0/0x0433 D3300

Listing and downloading pictures is very simple. Just use the -L and -g switches or -G to get all files. The most interesting functions are triggering the capture and reading and setting the camera properties.

Initiating capture

Please note that generic PTP capture is not supported by all PTP cameras. To verify if your camera supports generic capture operation use ptpcam to list supported operations:

# ptpcam -o

Listing supported operations...
Camera: D3300
 0x1001: GetDeviceInfo
(...)
 0x100e: InitiateCapture

If it does NOT list operation 0x100e then you’re out of luck.

To trigger a time lapse capture I prefer to use the –loop-capture switch together with –interval. This way ptpcam’s internal timer makes sure to trigger capture with as accurate intervals as possible. Also it downloads and removes the image from the camera.

# ptpcam --loop-capture=5 --interval=3
Camera: D3300

Initiating captue...
Object added 0x2919c431
Saving file: "DSC_1073.JPG" is done...
Deleting from camera.
Object 0x2919c431 (DSC_1073.JPG) deleted.
Sleeping for remaining 2 seconds.

Initiating captue...
Object added 0x2919c432
Saving file: "DSC_1074.JPG" is done...
Deleting from camera.
Object 0x2919c432 (DSC_1074.JPG) deleted.
Sleeping for remaining 2 seconds.

Initiating captue...
Object added 0x2919c433
Saving file: "DSC_1075.JPG" is done...
Deleting from camera.
Object 0x2919c433 (DSC_1075.JPG) deleted.
Sleeping for remaining 2 seconds.

Initiating captue...
Object added 0x2919c434
Saving file: "DSC_1076.JPG" is done...
Deleting from camera.
Object 0x2919c434 (DSC_1076.JPG) deleted.
Sleeping for remaining 2 seconds.

Initiating captue...
Object added 0x2919c435
Saving file: "DSC_1077.JPG" is done...
Deleting from camera.
Object 0x2919c435 (DSC_1077.JPG) deleted.

To make a good capture camera needs to be properly configures. That’s what properties are for.

Manipulating properties

To list the properties that your camera support use the -p switch:

# ptpcam -p 

Listing properties...
Camera: D3300
 0x5001: Battery Level
 0x5003: Image Size
 0x5004: Compression Setting
 0x5005: White Balance
 0x5007: F-Number
 0x5008: Focal Length
 0x500a: Focus Mode
 0x500b: Exposure Metering Mode
 0x500c: Flash Mode
 0x500d: Exposure Time
 0x500e: Exposure Program Mode
 0x500f: Exposure Index (film speed ISO)
 0x5010: Exposure Bias Compensation
 0x5011: Date Time
 0x5013: Still Capture Mode
 0x5018: Burst Number
 0x501c: Focus Metering Mode
 0xd303: UNKNOWN
 0xd406: UNKNOWN
 0xd407: UNKNOWN

Unfortunately not all proprietary extension properties are documented or reversed and hence listed as UNKNOWN (though you might still be able to identify and manipulate them).

Properties can be of various types like UINT8, UINT32, INT16, STRING, etc. and its values can be either random (rarely), range (for numeric properties) or enumerated (any  type). To show property along its value and description use switch -s together with -v:

# ptpcam -s 0x5001 -v

Camera: D3300
Battery Level: [0x5001, readonly, UINT8] 
 Current value: 100
 Factory value: 100
Range [0 - 100; step 1]

Alternatively you can also use the textual property names with abbreviations, like this (–set without –val is equivalent of -s):

# ptpcam --set Battery -v

Camera: D3300
Battery Level: [0x5001, readonly, UINT8] 
 Current value: 100
 Factory value: 100
Range [0 - 100; step 1]

From the output we can find that property Battery Level is a readonly property (of UINT8 type), its current value is 100 and possible values are in range between 0 and 100 with step of 1.

Other properties are settable, for example:

# ptpcam -s 0x5003 -v

Camera: D3300
Image Size: [0x5003, readwrite, String] 
 Current value: "4496x3000"
 Factory value: "6000x4000"
Enumerated:
"6000x4000"
"4496x3000"
"2992x2000"

The Image Size property is a string and is readwrite. Please note that some properties (in example F-Stop) can be set only in certain camera modes (Manual, Aperture Priority)  so make sure you turn the dial to proper mode before complain that given property is readonly.

To obtain the overview of camera properties use –show-all-properties switch along -v:

# ptpcam --show-all-properties -v

Camera: D200
 0x5001: (Battery Level) 50
 0x5003: (Image Size) "3872x2592"
 0x5004: (Compression Setting: JPEG Normal) 1
 0x5005: (White Balance: Automatic) 2
 0x5007: (F-Number: 16.0) 1600
 0x5008: (Focal Length: 18mm) 1800
 0x500a: (Focus Mode: Manual) 1
 0x500b: (Exposure Metering Mode: Multi-spot) 3
 0x500c: (Flash Mode: Front-courtain) -32752
 0x500d: (Exposure Time: 0.1000s) 1000
 0x500e: (Exposure Program Mode: Manual) 1
 0x500f: (Exposure Index (film speed ISO)) 400
 0x5010: (Exposure Bias Compensation: 0.0) 0
 0x5011: (Date Time) "20150610T220559"
 0x5013: (Still Capture Mode: Single Frame) 1
 0x5018: (Burst Number) 1
 0x501c: (Focus Metering Mode: Single Area) -32752

Some cameras support less properties while others support more:

# ptpcam --show-all-properties -v

Camera: D70s
 0x5001: (Battery Level) 100
 0x5003: (Image Size) "3008x2000"
 0x5004: (Compression Setting: JPEG Fine) 2
 0x5005: (White Balance: Automatic) 2
 0x5007: (F-Number: 0.0) 0
 0x5008: (Focal Length: 0mm) 0
 0x500a: (Focus Mode: Manual) 1
 0x500b: (Exposure Metering Mode: Multi-spot) 3
 0x500c: (Flash Mode: Front-courtain) -32752
 0x500d: (Exposure Time: 0.1666s) 1666
 0x500e: (Exposure Program Mode: Manual) 1
 0x500f: (Exposure Index (film speed ISO)) 200
 0x5010: (Exposure Bias Compensation: 0.0) 0
 0x5011: (Date Time) "20150611T001523"
 0x5013: (Still Capture Mode: Single Frame) 1
 0x5018: (Burst Number) 1
 0x501c: (Focus Metering Mode: Single Area) -32752
 0xd017: (NIKON White Balance Auto Bias) 0
 0xd018: (NIKON White Balance Tungsten Bias) 0
 0xd019: (NIKON White Balance Flourescent Bias) 1
 0xd01a: (NIKON White Balance Daylight Bias) 3
 0xd01b: (NIKON White Balance Flash Bias) 2
 0xd01c: (NIKON White Balance Cloudy Bias) 0
 0xd01d: (NIKON White Balance Shade Bias) 1
 0xd01f: (UNKNOWN) 0
 0xd025: (UNKNOWN) 28115589
 0xd026: (UNKNOWN) 36372868
 0xd02a: (NIKON Image Sharpening: -2 Low) 2
 0xd02b: (NIKON Tone Compensation: Normal) 1
 0xd02c: (NIKON Color Mode: IIIa (sRGB)) 2
 0xd02d: (NIKON Hue Adjustment) 0
 0xd045: (UNKNOWN) 0
 0xd04f: (NIKON Focus Area Wrap: No Wrap) 0
 0xd054: (NIKON ISO Auto: Off) 0
 0xd056: (NIKON EV Step: 1/3) 0
 0xd058: (NIKON Exposure Compensation by Command Dial only: Off) 0
 0xd059: (NIKON Center Weighted Area: 8mm) 1
 0xd05e: (NIKON AE Lock Mode: AE-L Button) 0
 0xd05f: (NIKON AE-L/AF-L Mode: Exposure and Focus Lock) 0
 0xd062: (NIKON Meter-Off: 6s) 1
 0xd063: (NIKON Self Timer: 10s) 2
 0xd064: (NIKON Monitor Off: 20s) 1
 0xd06b: (NIKON Long Exposure Noise Reduction: On) 1
 0xd06c: (NIKON File Number Sequence: On) 1
 0xd075: (NIKON Slowest Flash Shutter Speed: 1/60) 0
 0xd078: (NIKON Bracket Set: AE & Flash) 0
 0xd07a: (NIKON Bracket Order: MTR->Under->Over) 0
 0xd086: (NIKON Reverse Command Dials: Yes) 1
 0xd08a: (NIKON No CF Card: Enabled Release) 0
 0xd090: (NIKON Image Comment String) " "
 0xd091: (NIKON Image Comment Attach: Off) 0
 0xd092: (NIKON Image Rotation: Automatic) 0
 0xd0c0: (NIKON Bracketing: Off) 0
 0xd0c2: (NIKON Bracketing Program: +2F) 1
 0xd0c3: (UNKNOWN) 1
 0xd0c4: (NIKON White Balance Bracket Step) 0
 0xd0c5: (UNKNOWN) 0
 0xd0e0: (NIKON Lens ID) 0
 0xd0e1: (UNKNOWN) 0
 0xd0e2: (UNKNOWN) 0
 0xd0e3: (NIKON Min. Focal Length: 0) 0
 0xd0e4: (NIKON Max. Focal Length: 0) 0
 0xd0e5: (NIKON Max. Aperture at Min. Focal Length: 0.0) 0
 0xd0e6: (NIKON Max. Aperture at Max. Focal Length: 0.0) 0
 0xd100: (NIKON Exposure Time: 1/6) 65542
 0xd101: (NIKON AC Power) 0
 0xd102: (UNKNOWN) 0
 0xd103: (NIKON Maximum Shots) 2
 0xd104: (NIKON AF-L Locked) 0
 0xd105: (NIKON AE Lock: Not Locked) 0
 0xd106: (NIKON AF Lock) 0
 0xd108: (NIKON Autofocus Area selector: <CENTER>) 0
 0xd109: (UNKNOWN) 0
 0xd10a: (NIKON Light Meter) 0
 0xd10d: (UNKNOWN) "NO= 1006b1f2 "
 0xd10e: (NIKON Camera orientation: Landscape) 0
 0xd10b: (UNKNOWN) 0
 0xd120: (UNKNOWN) 0
 0xd121: (UNKNOWN) 0
 0xd122: (UNKNOWN) 0
 0xd124: (UNKNOWN) 0
 0xd125: (UNKNOWN) 1
 0xd126: (NIKON Flash Exposure Compensation: 0.0) 0
 0xd140: (NIKON Optimize Image: Vivid) 1
 0xd142: (NIKON Saturation: Moderate) 1
 0xd160: (NIKON Beep: On) 0
 0xd161: (NIKON Autofocus Mode: AF-S (single-servo)) 0
 0xd163: (NIKON AF Assist Lamp: On) 0
 0xd164: (NIKON Auto ISO shutter limit for P A and DVP Mode: 1/30) 2
 0xd165: (NIKON Image Review: On) 0
 0xd166: (NIKON AF Area Illumination: Auto) 0
 0xd167: (NIKON Flash Mode: TTL) 0
 0xd168: (NIKON Flash Commander Mode: TTL) 0
 0xd169: (NIKON Flash Signal Indicator: On) 0
 0xd16b: (NIKON Remote Timeout: 1min) 0
 0xd16c: (NIKON Viewfinder Grid Display: Off) 0
 0xd16d: (NIKON Flash Manual Mode Power: Full power) 0
 0xd16e: (NIKON Flash Commander Mode Power: FULL) 0
 0xd180: (NIKON CSM Menu: Detailed) 1
 0xd190: (NIKON Bracketing Increment: 2.0) 12
 0xd1b0: (NIKON Low Light Indicator: No) 0
 0xd1c0: (NIKON Flash Open: No) 0
 0xd1c1: (NIKON Flash Charged: No) 0
# ptpcam --show-all-properties -v

Camera: D3300
 0x5001: (Battery Level) 100
 0x5003: (Image Size) "4496x3000"
 0x5004: (Compression Setting) 1
 0x5005: (White Balance: Automatic) 2
 0x5007: (F-Number: 1.8) 180
 0x5008: (Focal Length: 30mm) 3000
 0x500a: (Focus Mode) -32750
 0x500b: (Exposure Metering Mode: Multi-spot) 3
 0x500c: (Flash Mode) -32752
 0x500d: (Exposure Time: 0.0012s) 12
 0x500e: (Exposure Program Mode: Manual) 1
 0x500f: (Exposure Index (film speed ISO)) 6400
 0x5010: (Exposure Bias Compensation: 0.0) 0
 0x5011: (Date Time) "20150610T225551"
 0x5013: (Still Capture Mode: Normal) 1
 0x5018: (Burst Number) 1
 0x501c: (Focus Metering Mode) -32751
 0xd303: (UNKNOWN) 1
 0xd406: (UNKNOWN) "Windows/6.0.5330.0 MTPClassDriver/6.0.5330.0"
 0xd407: (UNKNOWN) 1

As you can see in the output some vendor extension modes are not recognized and are displayed as numeric values rather than descriptive text. However we can inspect such properties anyway:

# ptpcam -s 0x501c -v

Camera: D3300
Focus Metering Mode: [0x501c, readwrite, UINT16] 
 Current value: 0x8011 (-32751)
 Factory value: 0x8011 (-32751)
Enumerated:
0x0002 (2) [Multi-spot]
0x8010 (-32752)
0x8011 (-32751)
0x8012 (-32750)

Mind that you can use textual property names with abbreviations:

# ptpcam --set "Focus M" -v

Camera: D3300
Focus Mode: [0x500a, readonly, UINT16] 
 Current value: 0x8012 (-32750)
 Factory value: 0x8012 (-32750)
Enumerated:
0x0001 (1) [Manual]
0x8010 (-32752)
0x8011 (-32751)
0x8012 (-32750)
0x8013 (-32749)

# ptpcam --set "Focus Me" -v

Camera: D3300
Focus Metering Mode: [0x501c, readwrite, UINT16] 
 Current value: 0x8011 (-32751)
 Factory value: 0x8011 (-32751)
Enumerated:
0x0002 (2) [Multi-spot]
0x8010 (-32752)
0x8011 (-32751)
0x8012 (-32750)

Setting properties is as simple as it can be:

# ptpcam --set "Focus Me" -v --val 2

Camera: D3300
'Focus Metering Mode' is set to: 0x8011 (-32751)
Changing property value to 2 [Multi-spot] succeeded.

# ptpcam --set Image --val 6000x4000

Camera: D3300
'Image Size' is set to: "4496x3000"
Changing property value to 6000x4000 [(null)] succeeded.

# ptpcam -s 0x5005 --val 4

Camera: D3300
'White Balance' is set to: [Automatic]
Changing property value to 4 [Daylight] succeeded.

Conclusion

With libptp2 and its companion app ptpcam I was finally able to use all my PTP cameras for astrony from my balcony without the need to use lengthy cables through my whole apartment :) I just set up a RPi with WiFi and was able to access it via ssh to control my cameras.

Advertisements