RICOH THETA API Over USB Cable - (S, V, SC models)



Before You Get Started

The RICOH THETA S, the third generation version of RICOH’s 360 degree camera, provides open API access so you can connect to the camera and build applications and devices that take advantage of camera’s low-cost, versatile 360 degree image and video capabilities. Individuals and companies in a wide range of fields are already doing this.

There are two ways to access the camera API: Over wifi and over USB.

The RICOH THETA S 360 camera can be controlled with an API that is accessible using WiFi. Version 2 of the API is compliant with Google Open Spherical Camera API specification.

An alternative to using the RICOH THETA S API over WiFi exists that works over a USB cable. This is a different API and requires firmware version 01.42 or later. v2 USB API uses extended PTP, or Picture Transfer Protocol, as the communications protocol.

There are pros and cons for using each method, depending on your specific requirements. Some of the differences are quickly highlighted here:

Getting Started with the RICOH THETA USB API

To use v2 USB API, go to:

Official RICOH THETA USB Reference v2

On the RICOH developer forum, MattWymore posted this:

I figured out how to make this work. This feature does work correctly, you just have to issue “raw”
MTP/PTP commands to get it to work. So if anybody else is using the Windows Portable Devices API
to control the Theta S, keep this in mind:

  1. It looks like you can’t use the WPD command
    WPD_COMMAND_STILL_IMAGE_CAPTURE_INITIATE to initiate capture. If you use this
    command the driver returns an error to you.
  1. The correct way to do this is to use
    the parameters and Op Code for image capture and then send that command. Take a look at this
    example from Microsoft for setting things up. Basically you just need to change the Op Code to
    0x100E (for initiate capture) and change the StorageID to 0x0 (as documented in the Theta v2
    USB API) and you are ready to go.

Hopefully this helps out anybody that is trying to do tethered capture.


These are untested.

C, C++


  • PyMTP (Python bindings to LibMTP)
  • python-mtp (another libmtp Python wrapper)

MTP Specification



On my system, Xenial Xerus, Ubuntu 16.04, I already had libmtp installed. I think it may be installed with Calibre ebook reader.

ricoh@xerus:~/Documents/community-document$ dpkg -l *libmtp*
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
ii libmtp-common 1.1.10-2ubun all Media Transfer Protocol (MTP) com
ii libmtp-runtime 1.1.10-2ubun amd64 Media Transfer Protocol (MTP) run
un libmtp8 <none> <none> (no description available)
ii libmtp9:amd64 1.1.10-2ubun amd64 Media Transfer Protocol (MTP) lib

API over USB with the Raspberry Pi using Open Source libptp

From XiaomingYang

Finally got it to work. I am working on Raspberry Pi with libptp
I have problem with gphoto2. The problem comes from the rational number used for shutter speed in USB API. None of these package support it directly. gphoto 2.5.10 may support m15 but does not work Theta S from my test.

With ptpcam -R, it can send a raw generic PTP request with parameters. The returned result could be reformated to shutter speed settings of Theta S. First read properties available, 0x1014 for reading device property description and 0xd00f for shutter speed. In the returned values, all the possible shutter speed is listed. For example, 01 00 00 00 a0 0f 00 are two 4-bype integers, 01 00 00 00 is 1 and a0 0f 00 00 is actually 0f a0 which is 6400.

$ ptpcam -R 0x1014,0xd00f,0,0,0,r
Sending generic request: reqCode=0x1014, params=[0x0000d00f,0x00000000,0x00000000,0x00000000,0x00000000]
0f d0 08 00 01 00 00 00 00 00 00 00 00 01 00 00 - …
00 3c 00 00 00 02 37 00 01 00 00 00 00 19 00 00 - .<…7…
01 00 00 00 88 13 00 00 01 00 00 00 a0 0f 00 00 - …
01 00 00 00 80 0c 00 00 01 00 00 00 c4 09 00 00 - …
01 00 00 00 d0 07 00 00 01 00 00 00 40 06 00 00 - …@…

To get current setting of a property, 0x1015 for get property and 0xd00f for shutter speed:

$ptpcam -R 0x1015,0xd00f,0,0,0,r

Sending generic request: reqCode=0x1015, params=[0x0000d00f,0x00000000,0x00000000,0x00000000,0x00000000]
01 00 00 00 3c 00 00 00 00 00 00 00 - …<…
PTP: response OK

The result 01 00 00 00 3c 00 00 00 could be read as (01)/(3c) = 1/60
To set shutter speed, could send binary data with ptpcam -R. To send 1/8, use 0x1016 for set property:
echo -e -n ‘\x01\x00\x00\x00\x08\x00\x00\x00’ > shutter.bin
ptpcam -R 0x1016,0x00f,0,0,0,0,shuuter.bin

THETA S Firmware Upgrade Adds Wired Remote Support
Using THETA 360 Video from a Drone
Top 6 RICOH THETA Community Posts in 2016
Raspberry Pi 360 Challenge
THETA S Firmware Upgrade Adds Wired Remote Support
Start Here: MIT Reality Virtually Hackathon 2017
USB Remote Accessory Alternatives for Theta S

In order to test libptp, it looks like I need libusb. There is a Ubuntu package for libusb.

craig@linux-silver:~$ sudo apt-get install libusb-1.0-0-dev
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
The following NEW packages will be installed:
  libusb-1.0-0-dev libusb-1.0-doc
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 219 kB of archives.
After this operation, 1,683 kB of additional disk space will be used.
Do you want to continue? [Y/n] 

Install went fine.

I next downloaded libptp source code from Sourceforge.

craig@linux-silver:$ tar xvf libptp2-1.2.0.tar.gz

Extract went fine.

I got this error when I tried ./configure

./configure: line 13153: test: : integer expression expected
configure: error: 
*** You need the 0 line of libusb which is at least 0.1.8.
*** Higher versions might not be compatible! Download and istall
*** libusb version 0.X.X from or
*** use --disable-ptpcam option to build without ptpcam tool.

The easiest thing is to install libusb 0.1.8 and see if it compiles. I compiled and installed libusb 0.1.8.

I then compiled libptp2-1.2.0

It installed in /usr/local/bin

craig@linux-silver:/usr/local/bin$ ls -l ptpcam 
-rwxr-xr-x 1 root root 159904 Jun 29 16:32 ptpcam

When I first tried to run ptpcam, I got this error:

craig@linux-silver:~$ ptpcam
ptpcam: error while loading shared libraries: cannot open shared object file: No such file or directory

I added /usr/local/lib to my LD_LIBRARY_PATH

craig@linux-silver:$ export LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib
craig@linux-silver:$ ptpcam
USAGE: ptpcam [OPTION]

Seems to be working. I’m going to plug in the camera.

Not finding camera

root@linux-silver:~# ptpcam --list-devices
Found no PTP devices

There’s life:

craig@linux-silver:~$ gphoto2 --auto-detect
Model                          Port                                            
USB PTP Class Camera           usb:003,009     

root@linux-silver:~# gphoto2 -L -f /store_00010001/DCIM/100RICOH
There are 8 files in folder '/store_00010001/DCIM/100RICOH'.                   
#1     R0010622.JPG               rd  3908 KB 5376x2688 image/jpeg
#2     R0010623.JPG               rd  3862 KB 5376x2688 image/jpeg
#3     R0010624.JPG               rd  3832 KB 5376x2688 image/jpeg

I can also take a picture and download the pictures using the USB cable

craig@linux-silver:~/Documents/tmp$ gphoto2 --capture-image
New file is in location /store_00010001/DCIM/100RICOH/R0010631.JPG on the camera
craig@linux-silver:~/Documents/tmp/img$ gphoto2 -P
Saving file as R0010622.JPG                                                    
Saving file as R0010623.JPG                                                    
Saving file as R0010624.JPG                                                    
Saving file as R0010625.JPG                                                    
Saving file as R0010626.JPG                                                    
Saving file as R0010627.JPG                                                    
Saving file as R0010628.JPG                                                    
Saving file as R0010629.JPG                                                    
Saving file as R0010630.JPG                                                    
Saving file as R0010631.JPG                                                    
craig@linux-silver:~/Documents/tmp/img$ ls
R0010622.JPG  R0010624.JPG  R0010626.JPG  R0010628.JPG  R0010630.JPG
R0010623.JPG  R0010625.JPG  R0010627.JPG  R0010629.JPG  R0010631.JPG

Capture Image and Download also works

craig@linux-silver:~/Documents/tmp/img$ gphoto2 --capture-image-and-download
New file is in location /store_00010001/DCIM/100RICOH/R0010632.JPG on the camera
Saving file as R0010632.JPG                                                    
Deleting file /store_00010001/DCIM/100RICOH/R0010632.JPG on the camera

Python Bindings for libgphoto2

install libgphoto-dev

craig@linux-silver:$ sudo apt-get install libgphoto2-dev

Grabbed libgphoto2-python from github

need to install pyrex

craig@linux-silver:~/Documents/Accounts/ricoh/Development/usb/libgphoto2-python$ sudo apt install python-pyrex
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  libexpat1-dev libpython-all-dev libpython-dev libpython2.7-dev python-all
  python-all-dev python-dev python2.7-dev
The following NEW packages will be installed:
  libexpat1-dev libpython-all-dev libpython-dev libpython2.7-dev python-all
  python-all-dev python-dev python-pyrex python2.7-dev

running ./configure produced the necessary

libgphoto2-python$ ls
aclocal.m4      config.status  gphoto-m4        libtool      README
AUTHORS         configure      m4 
auto-aux   Makefile
autom4te.cache  COPYING
ChangeLog       ctypes-test    INSTALL  TODO
config.log      gphoto2.pyx  NEWS

build and install went smoothly.

$ python build
$ sudo python install

I used pydoc gphoto2 to access the docs.

I saved this code snippet into a file called,

from gphoto2 import *

theta = camera()
folderList = theta.list_folders_in_folder('/')
# print(folderList[0]) #core dump

The program works over USB, including the ability to take a picture

$ python 
Manufacturer: Ricoh Company, Ltd.
  Version: 01.42
  Serial Number: 00010093
Vendor Extension ID: 0x6 (1.10)
Functional Mode: 0x8001

Capture Formats: 
Display Formats: Association/Directory, JPEG, Firmware, MP4

Device Capabilities:
    File Download, File Deletion, No File Upload
    Generic Image Capture, Open Capture, No vendor specific capture

Storage Devices Summary:
    StorageDescription: None
    VolumeLabel: None
    Storage Type: Builtin RAM
    Filesystemtype: Digital Camera Layout (DCIM)
    Access Capability: Read-Write
    Maximum Capability: 8060403712 (7687 MB)
    Free Space (Bytes): 8002180096 (7631 MB)
    Free Space (Images): 1606

Device Property Summary:
Battery Level(0x5001):(read only) (type=0x2) Range [0 - 100, step 1] value: 100% (100)
Functional Mode(0x5002):(read only) (type=0x4) Enumeration [0,32769] value: 32769
Image Size(0x5003):(readwrite) (type=0xffff) Enumeration [
    ] value: '5376x2688'
Date & Time(0x5011):(readwrite) (type=0xffff) '20160629T203221-0700'
Pre-Capture Delay(0x5012):(readwrite) (type=0x6) Range [0 - 10000, step 1000] value: 0.0s (0)
Perceived Device Type(0xd407):(read only) (type=0x6) 1
White Balance(0x5005):(readwrite) (type=0x4) Enumeration [2,4,32769,32770,6,32800,32771,32772,32773,32774] value: Automatic (2)
Exposure Program Mode(0x500e):(readwrite) (type=0x4) Enumeration [1,2,4,32771] value: P (2)
Exposure Index (film speed ISO)(0x500f):(readwrite) (type=0x4) Enumeration [65535] value: ISO 65535 (65535)
Exposure Bias Compensation(0x5010):(readwrite) (type=0x3) Enumeration [2000,1700,1300,1000,700,300,0,-300,-700,-1000,-1300,-1700,-2000] value: 0.0 stops (0)
Still Capture Mode(0x5013):(readwrite) (type=0x4) Enumeration [1,3,32770] value: Single Shot (1)
Timelapse Number(0x501a):(readwrite) (type=0x4) Range [0 - 9999, step 1] value: 0
Timelapse Interval(0x501b):(readwrite) (type=0x6) Range [8000 - 3600000, step 1000] value: 8000
Audio Volume(0x502c):(readwrite) (type=0x6) Range [0 - 100, step 1] value: 100
Property 0xd006:(read only) (type=0x6) 0
Property 0xd00f:(readwrite) (type=0x8) Enumeration [0] value: 0
Property 0xd801:(readwrite) (type=0xffff) ''
Property 0xd802:(readwrite) (type=0x2) Range [0 - 30, step 1] value: 10
Property 0xd803:(readwrite) (type=0x4) Range [0 - 1800, step 1] value: 600
Property 0xd805:(readwrite) (type=0xffff) 'THETAXS00010093.OSC'
Property 0xd806:(readwrite) (type=0xffff) '00010093'
Property 0xd807:(readwrite) (type=0x2) Enumeration [0,1,6,11] value: 6
Property 0xd808:(read only) (type=0x2) Enumeration [0,1,2] value: 0
Property 0xd809:(read only) (type=0x4) Range [0 - 1499, step 1] value: 0
Property 0xd80a:(read only) (type=0x4) Range [0 - 1500, step 1] value: 0
Property 0xd80b:(readwrite) (type=0x2) Enumeration [0,1,2,3] value: 0
Property 0xd80c:(read only) (type=0x2) Enumeration [0,1,2] value: 2
Property 0xd80d:(read only) (type=0x4) 2718
Property 0xd80e:(readwrite) (type=0x2) Enumeration [0,1] value: 1

Model : USB PTP Class Camera
Status : 1
Port : 4
Operations : 25
File Operations : 10
Folder Operations : 14
USB (vendor/product) : 0x0/0x0
USB class : 0x6/0x1/0x1
Library : /usr/lib/x86_64-linux-gnu/libgphoto2/2.5.9/ptp2
Id : PTP

Unfortunately, I can’t grab the list of files as I get a core dump.


Controlling THETA Over USB with libptp

We’ll test libptp with the included ptpcam command line program.

Preparing the Camera

  • Camera is on, there is a blue light
  • Camera is connected with USB to Linux computer (camera is USB 2.0, but it’ll work on a USB 3.0 port)
  • Camera is not mounted

Verify Computer finds Camera as USB Devices

$ lsusb
Bus 003 Device 009: ID 05ca:0366 Ricoh Co., Ltd 

Verify ptpcam Can Connect to Camera

First verify that ptpcam can connect to the camera.

$ ptpcam -i

Camera information
  manufacturer: Ricoh Company, Ltd.
  serial number: '00010093'
  device version: 01.42
  extension ID: 0x00000006
  extension description: (null)
  extension version: 0x006e

Next, we’ll list all the operations that libptp can access on the camera over usb.

$ ptpcam -o

Listing supported operations...
  0x1001: GetDeviceInfo
  0x1002: OpenSession
  0x1003: CloseSession
  0x1004: GetStorageIDs
  0x1005: GetStorageInfo
  0x1006: GetNumObjects
  0x1007: GetObjectHandles
  0x1008: GetObjectInfo
  0x1009: GetObject
  0x100a: GetThumb
  0x100b: DeleteObject
  0x1014: GetDevicePropDesc
  0x1015: GetDevicePropValue
  0x101b: GetPartialObject
  0x9001: UNKNOWN
  0x9991: UNKNOWN
  0x9999: UNKNOWN
  0x999a: UNKNOWN
  0x999b: UNKNOWN
  0x999c: UNKNOWN
  0x999d: UNKNOWN
  0x100e: InitiateCapture
  0x1016: SetDevicePropValue
  0x101c: InitiateOpenCapture
  0x1018: TerminateOpenCapture
  0x99a2: UNKNOWN

It’s looking very promising. Next, we’ll list the properties that can accessed.

Accessing Camera Properties Over USB

$ ptpcam -p

Listing properties...
  0x5001: Battery Level
  0x5002: Functional Mode
  0x5003: Image Size
  0x5011: Date Time
  0x5012: Pre-Capture Delay
  0xd407: UNKNOWN
  0x5005: White Balance
  0x500e: Exposure Program Mode
  0x500f: Exposure Index (film speed ISO)
  0x5010: Exposure Bias Compensation
  0x5013: Still Capture Mode
  0x501a: Timelapse Number
  0x501b: Timelapse Interval
  0x502c: UNKNOWN

Let’s check if I have battery.

$ ptpcam --show-property=0x5001

'Battery Level' is set to: 100

It’s plugged into USB, so it makes sense that my battery is at 100%.

Next, I’ll check the image size:

$ ptpcam --show-property=0x5003

'Image Size' is set to: "5376x2688"

I’ll check the time:

$ ptpcam --show-property=0x5011

'Date Time' is set to: "20160701T142845-0700"

Check Capture Mode

$ ptpcam --show-property=0x5013

'Still Capture Mode' is set to: [Normal]

Set Capture Mode to Video

Using the RICOH v2 USB documentation, you can find that video shooting corresponds to 0x8002.

$ ptpcam --set-property=0x5013 --val=0x8002

'Still Capture Mode' is set to: [Normal]
Changing property value to 0x8002 [(null)] succeeded.

Verify that the change was saved:

craig@linux-silver:~$ ptpcam --show-property=0x5013

'Still Capture Mode' is set to: 0x8002 (-32766)

The blue light on the THETA now shows a video icon.

At this stage, I boiled a pot of tea and left the camera on. When I came back, it had turned off.

I verified that the battery was still at 100%.

$ ptpcam --show-property=0x5013

'Still Capture Mode' is set to: 0x8002 (-32766)
craig@linux-silver:~$ ptpcam --show-property=0x5001

'Battery Level' is set to: 100

I then looked at the sleepDelay

craig@linux-silver:~$ ptpcam --show-property=0xd803

'UNKNOWN' is set to: 600

The sleepDelay is set to 600 seconds, or 10 minutes. I’m going to turn it off.

$ ptpcam --set-property=0xd803 --val=0

'UNKNOWN' is set to: 600
Changing property value to 0 [(null)] succeeded.

Now, hopefully, the THETA will stay on indefinitely, powered by the USB and I’ll be able to use it in an industrial application such as security surveillance.

List the files on your THETA.

$ ptpcam -L

Listing files...
Handler:           Size:     Captured:          name:
0x0064026e:      4000851    2016-06-03 21:11    R0010622.JPG
0x0064026f:      3953884    2016-06-09 22:52    R0010623.JPG
0x00640270:      3923907    2016-06-10 00:22    R0010624.JPG

Download the first file from the camera to your local computer.

$ ptpcam --get-file=0x0064026e
Saving file: "R0010622.JPG" is done.

Boom! It’s super fast.

You can look at the image in your Linux file browser just to verify that the image was downloaded. In this picture, I have the THETA lying on it’s side on my desk.

It’s not a very nice picture, so I’ll delete it.

$ ptpcam --delete-object=0x0064026e

Object 0x0064026e (R0010622.JPG) deleted.

I’m going to attempt to take another shot with my camera in a tripod. First, I’ll set the mode to still image as I set it to video earlier.

$ ptpcam --set-property=0x5013 --val=0x0001

'Still Capture Mode' is set to: 0x8002 (-32766)
Changing property value to 0x0001 [(null)] succeeded.

Then, I take the image.

$ ptpcam -c

Initiating captue...

List the files on the camera:

$ ptpcam -L

Listing files...
Handler:           Size:     Captured:          name:
0x0064027e:      3930938    2016-07-01 23:22    R0010638.JPG

Download the file to my local computer

$ ptpcam --get-file=0x0064027e
Saving file: "R0010638.JPG" is done.

Verify that the download worked.

You can now see my boss Antec case for my overclocked system and the top of my overclocked and watercooled Linux test rig decorated with rainbow tape by my daughter.

I then checked the battery to verify that the THETA can last indefinitely connected with USB:

$ ptpcam --show-property=0x5001

'Battery Level' is set to: 100

The camera still turned off. I’m going to connect with the WiFi USB to set the offDelay.

As I have two network interfaces in my computer, I can access the THETA over WiFi while I am connected to the Internet. Once I connect to the THETA, I use DHC to easily set the options. DHC is simply a tool to send, save, and organize HTTP requests. As I test the THETA frequently. I find it convenient to save the HTTP POST commands in DHC.

If the image is difficult to see, the relevant POST body is

{"name": "camera.setOptions",
    "sessionId": "SID_0001",
    "options": {
		"offDelay": 65535

You can check the offDelay parameter with this:

{"name": "camera.getOptions",
    	"sessionId": "SID_0001",
    	"optionNames": [

Again, I have this template saved in DHC, so it’s easy for me to just change the optionNames.

I’m hopeful that the THETA will now stay on forever. At this point, it’s been on for an hour and I can send it API commands. So, it’s in a good state for surveillance or mapping. I can’t switch it to livestreaming mode. Also, the video is a bit problematic.

Using Raw PTP Commands

Grabbing Info

Pass the raw ptp command of GetDeviceInfo as a hex string, 0x1001

craig@linux-silver:$ ptpcam -R 0x1001
Sending generic request: reqCode=0x1001, params=[0x00000000,0x00000000,0x00000000,0x00000000,0x00000000]
64 00 06 00 00 00 6e 00 00 01 80 1a 00 00 00 01 - d.....n.........
10 02 10 03 10 04 10 05 10 06 10 07 10 08 10 09 - ................
10 0a 10 0b 10 14 10 15 10 1b 10 01 90 91 99 99 - ................
99 9a 99 9b 99 9c 99 9d 99 0e 10 16 10 1c 10 18 - ................
10 a2 99 06 00 00 00 02 40 06 40 08 40 0a 40 0c - ........@.@.@.@.
40 0d 40 1d 00 00 00 01 50 02 50 03 50 11 50 12 - @.@.....P.P.P.P.
50 07 d4 05 50 0e 50 0f 50 10 50 13 50 1a 50 1b - P...P.P.P.P.P.P.
50 2c 50 06 d0 0f d0 01 d8 02 d8 03 d8 05 d8 06 - P,P.............
d8 07 d8 08 d8 09 d8 0a d8 0b d8 0c d8 0d d8 0e - ................
d8 00 00 00 00 04 00 00 00 01 30 01 38 02 b8 82 - ..........0.8...
b9 14 52 00 69 00 63 00 6f 00 68 00 20 00 43 00 - ..R.i.c.o.h. .C.
6f 00 6d 00 70 00 61 00 6e 00 79 00 2c 00 20 00 - o.m.p.a.n.y.,. .
4c 00 74 00 64 00 2e 00 00 00 0e 52 00 49 00 43 - L.t.d......R.I.C
00 4f 00 48 00 20 00 54 00 48 00 45 00 54 00 41 - .O.H. .T.H.E.T.A
00 20 00 53 00 00 00 06 30 00 31 00 2e 00 34 00 - . .S....0.1...4.
32 00 00 00 09 30 00 30 00 30 00 31 00 30 00 30 - 2....
00 39 00 33 00 00 00 00                         - .9.3....        
PTP: response OK

Checking Battery Status

0x1015 is GetDevicePropValue. The property battery is 0x5001. The result is a number between 0 and 100. I get 64 in hex which corresponds to a decimal value of 100. My battery charge is 100%.

craig@linux-silver:$ ptpcam -R 0x1015,0x5001
Sending generic request: reqCode=0x1015, params=[0x00005001,0x00000000,0x00000000,0x00000000,0x00000000]
64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - d...............
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................
00 00 00 00 00 00 00 00                         - ........        
PTP: response OK

Getting Size of Still Image

In this example, I look for the property ImageSize which is 0x5003. Just to refresh from the previous example, 0x1015 is GetDevicePropValue. In the right column, you can see that the image size is 5376x2688

craig@linux-silver:$ ptpcam -R 0x1015,0x5003
Sending generic request: reqCode=0x1015, params=[0x00005003,0x00000000,0x00000000,0x00000000,0x00000000]
0a 35 00 33 00 37 00 36 00 78 00 32 00 36 00 38 - .
00 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - .8..............
00 00 00 00 00 00 00 00                         - ........        
PTP: response OK

Theta S now shuts down when plugged in. :/
Problems using ptpcam on RPi with Theta SC via USB

I am thinking of using a Raspberry Pi for USB control and am considering this case for the coolness factor. What do you think?

I ordered this case, so I may build the demo with a touchscreen in order to set things like timelapse delay and image display.


Seriously slick looking. Love that it integrates a stand with it. That display case is also pretty cool looking, appears to be very portable. Thumbs up for the coolness factor of both!


I had the THETA disconnect from Ubuntu after about 1,000 pictures taken over 2.5 hours. I suspect that something goes wrong with the USB connection. As a first step, I disabled Automount on Ubuntu 16.04.

Update August 9: I verified that the USB cable itself was bad. I threw it out. Now, the THETA stays connected.

Configuring Automounting

To enable or disable automount open a terminal and type: dconf-editor

Browse to The automount key controls whether to automatically mount media. If set to true, Nautilus will automatically mount media such as user-visible hard disks and removable media on start-up and media insertion. Another key,, controls whether to automatically open a folder for automounted media. If set to true, Nautilus will automatically open a folder when media is
automounted. This only applies to media where no known x-content type was detected; for media where a known x-content type is detected, the user configurable action will be taken instead. This can be configured
as shown below.


This is an extreme improvement over wifi picture taking. I have done
several interval shooting sessions set up through the iOS THETA S app, set
at a minute and 9 seconds intervals with a total limit of 120 and my THETA
camera tends to lose charge before the end of the two plus hours that would
be needed to get all 120 pictures.


I’m hoping to take 10,000 pictures or more. There is no loss in battery when the THETA S is connected with USB. Also, since I delete the pictures from the THETA after downloading, the limitation is simply the hard disk on my Linux computer. I just need to figure out how to stabilize the USB connection. In addition to turning off automount, I also upgraded my THETA to firmware 1.5. Maybe that will help.

In the iOS THETA S app, what is the minimum time interval you can set? Is it 9 seconds?

BTW, I noticed that the THETA firmware update for 1.42 indicated that:

・Photos can now also be taken while connected to PC via USB.
*While the THETA S is connected via USB and power is on, WiFi will switch off.

I notice it says Photos and not Photos and Videos. I wonder if the video is supported with the USB cable. I can start the video, just not stop it.


Yes, 9 seconds is the minimum allowed interval in the iOS THETA app.


I suspect that’s because the camera takes 8.5 seconds to store the equirectangular image and get ready for another shot. With the API over USB version, the minimum delay set to 9 seconds.

Have you figured out a way to get WiFi access to the THETA when it is being powered by the USB cable (and getting WiFi commands)? For example, have you tried timelapse with the mobile app and the theta plugged into a USB power source?

I currently have the THETA plugged into the USB 2.0 back-panel port on my Linux computer. I’m running a test at 15 second intervals and have taken 178 pictures so far. What’s the maximum number you’ve taken with the mobile app? Is it 120 pictures? Or, did you do another test with a higher number?

If you run a test with the WiFi, make sure the sleepDelay and offDelay are set to 65535

This guy seems like he’s got the timelapse working with WiFi using external power.


I need to do some more specific testing to be sure. But if I’m connected by
wifi and plug in the USB, wifi is instantly dropped. I can test and see
about setting up interval shooting and check if it continues after losing
the wifi connection. I have been able to take about 60-70 photos (I was not
focused on the exact number) at one time before my batteries died. I have
never gotten to 120. I have also never tried setting a higher number. I’ll
focus on these two specific tests (wifi and USB connectivity at the same
time, total number of pics able to be taken using interval shooting) and
try it out more.


When you say, plug in USB, are you plugging the camera into a wall adapter, NOT your computer? I know the THETA won’t work with WiFi when plugged into a computer, but I didn’t know that the WiFi stopped working when plugged into a wall adapter.

Current Timelapse Test:

  • 7 hours continuous
  • 1109 pictures in single session
  • 4.1 Gig of data

I’m planning on stopping it soon in order to modify the code.


Appears NOT to lose the wifi connection if you plug it into a power plug.
It DOES lose connection if you plug it into your computer. Potentially this
means that you have a powered THETA S run through the smartphone app,
setting interval shooting, continuing for very long periods of time.


It would be interesting to test the WiFi API connection over long periods of time and also how to reset the WiFi connection if the WiFi connection is cut. I think this would be needed for industrial applications.

Also, does the THETA need to be in range of the smartphone for interval shooting? I think that there’s an internal setting for interval shooting and that the THETA can take interval shooting without WiFi. You would still need to download and delete the pictures in the THETA every 1,600 pictures.

For the sample USB timelapse app, we have it set to delete the picture on the camera after every shot. It downloads it to a local computer.

I am thinking of writing a program to then upload it to the RICOH Cloud and delete it from the local disk. Do you know if the RICOH Cloud has a storage limitation during the Beta period. I’d like to store about 50GB of 360 image data to start with, but might need more.

The other feature I need is to reset the USB port in the event of failure. I found several fascinating articles on this subject.


As part of this test, I took a small sample of about 440 pictures outside using the USB cable. Each picture is 5376 x 2688. My son then ran a test using Adobe Premier Pro with their new VR features to combine the 440 pictures into a 15 second clip. The resulting video should be viewed at 4K for test viewing.

The test also shows the use of Mettle SkyBox, a plugin for After Effects, to manipulate text in 360 videos. He’s using the trial version for the test and the logos are visible. As we’re not big 360/VR hobbyists, I don’t think we’ll pay the $99, but it was cool to test the placement.


The case for the touchscreen and Raspberry Pi came.

This is what is looks like:

This is the back with the Raspberry Pi exposed. There’s a cover for it to hide it. The Raspberry Pi on the left is shown with a CP2102 USB 2.0 to UART TTL serial adapter. This is a $5.44 (free shipping) part that allows the Raspberry Pi to be connected to any computer through the USB port, enabling the RPi to be programmed from the computer. Although the touchscreen is nice, it is expensive. I hope to get a Raspberry Pi Zero rigged with a cheaper interface to control the camera. In the meantime, I’m using the touchscreen interface to test the Raspberry Pi with the THETA.


Here’s a link to the CP2102 board.

There’s a cheaper version available as well. I paid $2 more for the testing lights. There’s one that is about $2.50.

Another shot of the device.


Using gphoto2 on a Raspberry Pi to control the RICOH THETA Over a USB Cable

I have gphoto2 working on the Raspberry Pi. This is installable with apt and is easier to use than ptpcam.

In the example below, I set the shutter chirp to 30% of sound volume and then verify that the setting in correct.

pi@raspberrypi ~/Development/libptp2-1.2.0 $ gphoto2 --set-config=502c=30
pi@raspberrypi ~/Development/libptp2-1.2.0 $ gphoto2 --get-config=502c
Label: PTP Property 0x502c
Type: MENU
Current: 30
Choice: 0 0

In the next example, I download three files to my local disk

pi@raspberrypi ~/Development/gphoto2 $ gphoto2 --get-file 1-3
Downloading 'R0011757.JPG' from folder '/store_00010001/DCIM/100RICOH'...
Saving file as R0011757.JPG
Downloading 'R0011758.JPG' from folder '/store_00010001/DCIM/100RICOH'...
Saving file as R0011758.JPG
Downloading 'R0011759.JPG' from folder '/store_00010001/DCIM/100RICOH'...
Saving file as R0011759.JPG
pi@raspberrypi ~/Development/gphoto2 $

Download thumbnails

pi@raspberrypi ~/Development/gphoto2 $ gphoto2 --get-thumbnail 4-6
Downloading 'R0011761.JPG' from folder '/store_00010001/DCIM/100RICOH'...
Saving file as thumb_R0011761.jpg
Downloading 'R0011763.JPG' from folder '/store_00010001/DCIM/100RICOH'...
Saving file as thumb_R0011763.jpg
Downloading 'R0011764.JPG' from folder '/store_00010001/DCIM/100RICOH'...
Saving file as thumb_R0011764.jpg
pi@raspberrypi ~/Development/gphoto2 $

Components I Used

  • Raspian Jessie
  • gphoto2
  • Raspberry Pi 2
  • THETA plugged into Raspberry Pi with USB cable


Showing installed gphoto2 version with apt-cache

pi@raspberrypi ~ $ apt-cache show gphoto2
Package: gphoto2
Version: 2.5.4-1
Architecture: armhf
Maintainer: Debian PhotoTools Maintainers <pkg-phototools-devel@lists.alioth.deb>
Installed-Size: 802
Depends: libaa1 (>= 1.4p5), libc6 (>= 2.4), libcdk5, libexif12, libgphoto2-6 (>= 2.5.2), libgphoto2-port10 (>= 2.5.2), libjpeg8 (>= 8c), libncurses5 (>= 5.5-5~) , libpopt0 (>= 1.14), libreadline6 (>= 6.0)
Suggests: gtkam, gthumb
Priority: extra
Section: utils
Filename: pool/main/g/gphoto2/gphoto2_2.5.4-1_armhf.deb
Size: 169204
SHA256: 71baeac776e762229ad31c550a493a82a8fd5f2a435dd65a674d0030d14f8991
SHA1: 7018ffe0a8432ffcfbb08887f27b2ae22224b2fd
MD5sum: a522290cef04bf1cf7c6cdb4d0cf37d5
Description: digital camera command-line client
The gphoto2 library can be used by applications to access various
digital camera models, via standard protocols such as USB Mass Storage
and PTP, or vendor-specific protocols.
This package provide the gphoto2 command-line frontend.

Showing installed OS on Raspberry Pi

pi@raspberrypi ~ $ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"
NAME="Raspbian GNU/Linux"
VERSION="8 (jessie)"


Right now, I get this error when I first step the Raspberry Pi. I haven’t bothered to disable gvfs-gphoto2-volume-monitor at boot yet. I’ll figure this out in the future.

pi@raspberrypi ~ $ gphoto2 --about

*** Error ***
An error occurred in the io-library ('Could not claim the USB device'): Could not claim interface 0 (Device or resource busy). Make sure no other program (gvfs-gphoto2-volume-monitor) or kernel module (such as sdc2xx, stv680, spca50x) is using the device and you have read/write access to the device.
*** Error (-53: 'Could not claim the USB device') ***

It looks like I can prevent the daemon in /usr/lib/gvfs/gvfsd to run. In the meantime, I’m going to kill the processes before I start the tests.

You can find the process to kill with ps aux |grep gvfs

I also killed the spawner. In my test this morning, I needed to kill this in addition to gvfs-gphoto2-volume-monitor

Test it

pi@raspberrypi ~ $ gphoto2 --about
About the camera driver:
PTP2 driver
(c) 2001-2005 by Mariusz Woloszyn <>.
(c) 2003-2014 by Marcus Meissner <>.
This driver supports cameras that support PTP or PictBridge(tm), and
Media Players that support the Media Transfer Protocol (MTP).


Remove gvfs-gphoto2-volume-monitor

As I do not plan to mount the THETA as a storage device from the Raspberry Pi, I removed gvfs virtual filesystem.

Remove gvfs-backends

pi@raspberrypi ~ $ sudo apt remove gvfs-backends
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be REMOVED:

Test to make sure it still works.

pi@raspberrypi ~ $ gphoto2 -l
There is 1 folder in folder '/'.                                               
 - store_00010001
There is 1 folder in folder '/store_00010001'.


gphoto2 now works after reboot without having to kill the processes.

pi@raspberrypi ~ $ gphoto2 -l
There is 1 folder in folder '/'.                                               
 - store_00010001
There is 1 folder in folder '/store_00010001'.
There is 1 folder in folder '/store_00010001/DCIM'.
 - 100RICOH
There are 0 folders in folder '/store_00010001/DCIM/100RICOH'.

Ricoh theta usb cable

@orikoon verified that video control for start and stop works with the USB API on Ubuntu 14.10 using libptp2 1.2.0.


Great example of using the USB API by @khufkens


The photosphere project combines a Rico Theta S and a raspberry pi with a custom outdoor housing into a rugged 360 (outdoor) time-lapse camera. In my application I track changes in leaf development in a North-Eastern US forest. You can visit the project website at However, other applications are possible (hints on how to do nighttime images through the USB API are welcome).

The housing is made of standard PVC fittings, sitting on top of a garden fence post. The optics are covered by a glass lamp shade to provide optimal transmission and limited deformation (acrylic globes can be used as well). The only custom part is the plate on which the camera is mount using 1/4" steel thread. This plate is cut out of 3mm acrylic plastic. A vertical support also holds the raspberry pi to keep things tidy (see cad files). I use two 3mm plates extra rigidity (glued together). You can also use a 6mm top plate and a 3mm vertical plate. The inside of the “lens cover” is spray painted matte black to limit reflections.

Constructed and placed in the forest the camera looks like a garden lamp (see figure). Here the blue wire is the ethernet cable which runs to a nearby hub, and serves as the internet and power connection. The yellow wire is the ground wire for the surge protector, to protect the camera from voltage spikes due to nearby lightning strikes.


To install the software clone the project onto a raspberry pi and run the install script.

git clone

You will have to edit the crontab manually to add the server argument (for now).

Parts List

I assume that common items such as screws and glue (pvc, silicone) are available to makers.

Item Price ($)
Ricoh Theta S $350
Raspberry pi 2 $36
6-60V - 5V 3A UBEC $19
24V POE injector $10
APC surge protector $18
200ft / 50m Cat5e cable $13
8" glass globe lamp cover $35
4" (10cm) PVC pipe $20
4" (10cm) PVC coupler $2.5
3.5" Wooden Fence post $5
36" ground anchor $30
3mm Plexiglass sheet $5
1/4" stainless steel rod $1
1/4" (coupling) nuts $1
1/4" washers $1
TOTAL ~$550

NOTE: Information below added by theta360developers

Information on the WiFi and USB APIs is available in the Unofficial API Guide.

Discussion for this project is available on the site.

Theta S now shuts down when plugged in. :/
Sept 27 Meetup - RICOH THETA 360° Integration in Products, Photosphere Navigation, and 360° Video on Drones!

There is more discussion and links to other blogs in the topic below.