Posts

Digital camera control using Arduino USB Host Shield. Part 1 – basics.

Arduino taking picture of itself

Arduino taking picture of itself

I’m starting new series of articles describing exciting field of digital camera control. In modern cameras, USB port can be used not only for transferring images to a PC, but also for sending control commands to the camera. It is often possible to send commands which “press” the shutter button, modify shutter and aperture values, some cameras are even capable of doing focus control. At the same time, new shooting techniques, such as HDR and stacked focus, require that a photographer makes several shots, slightly modifying one or several shooting parameters from shot to shot. Even age-old time lapse technique could use some automation. Since camera manufacturers are, as always slow to implement there cool features, Arduino comes to the rescue.

I am announcing new code developed for Arduino USB Host shield which implements digital camera control functions via PTP. Alex Glushchenko, a developer from my native Russia, recently joined camera control project and code shown here and in the future articles is mainly his. He did most of reverse engineering and code development and my contributions to this project were mainly code testing, camera borrowing, and blogging. Code is hosted on github separately from USB Host library. Be warned – this source is preliminary and will be changed many times before it becomes stable! It is also expected to grow quite a bit – different cameras use different commands and developing universal code supporting all manufacturers (or even every camera from one manufacturer) is not possible due to the modest resources of Arduino platform. Therefore, several libraries have been developed, each covering specific set of cameras. The cameras supporting functions of a certain library are listed in library’s header file. The list of cameras is currently quite small but I’m hoping to get more cameras supported in the future.

Digital camera as USB peripheral is much more complex and less standard than a keyboard. The complexity starts at the very first level – device configuration. Very often , several different configurations are supported on a device and the default configuration is not the one we need. Therefore, the first step would naturally be learning how to recognize configuration which supports camera control commands.

There are 3 specifications describing USB digital camera works. Still Image Device specifies USB requests, descriptors and endpoints. The protocol structure is described in Media Transfer Protocol (MTP), which is better known by its previous name, “Picture Transfer Protocol” (PTP). The most interesting document, which actually lists commands supported by camera class, is known as “PIMA 15740-2000”. It is available for a fee from I3A, however, second-hand pdf copy can be obtained for free after some googling. Camera manufacturers implement their own functions, expanding PIMA definitions. In addition to that, some older cameras use their proprietary protocols instead of PTP; support for such cameras will be added eventually.

USB specification defines a class called “Still Image Capture Device”. According to it, such device has ’06’ in “Class” field of interface descriptor of the configuration. Therefore, one way to find necessary configuration is to look at configuration descriptor contents. Let’s take a look at the device descriptor (in case you are curious, it’s an iPhone). When we look at the last line, the number of configurations is 4. Older cameras may have 2 configurations and the first one is often a disk drive – this arrangement was made in pre-PTP times so you could offload pictures to a PC even if you didn’t have a driver for the camera installed. Modern cameras rely on PTP to transfer files to PC and often come with just one configuration – so far, all cameras used so to check the PTP code for the shield were of this variety.

Device descriptor:
Descriptor Length:      12
Descriptor type:        01
USB version:            0200
Device class:           00
Device Subclass:        00
Device Protocol:        00
Max.packet size:        40
Vendor  ID:             05AC
Product ID:             1292
Revision ID:            0001
Mfg.string index:       01
Prod.string index:      02
Serial number index:    03
Number of conf.:        04

A sketch which prints device descriptor was posted several articles back, make yourself a copy of it if you haven’t already. A sketch printing configuration descriptor was also posted not long ago; however, it was written to output only first configuration of the device – don’t use it. Instead, download this multiple configuration capable sketch from examples section of USB_Host_Shield repo. The following table shows all four configurations of the iPhone:

Configuration: 0

Configuration descriptor:
Total length:     0027
Num.intf:         01
Conf.value:       01
Conf.string:      05
Attr.:            C0
Max.pwr:          FA

Interface descriptor:
Intf.number:      00
Alt.:             00
Endpoints:        03
Class:            06
Subclass:         01
Protocol:         01
Intf.string:      00

Endpoint descriptor:
Endpoint address: 02
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Endpoint descriptor:
Endpoint address: 81
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Endpoint descriptor:
Endpoint address: 83
Attr.:            03
Max.pkt size:     0040
Polling interval: 40
Configuration: 1

Configuration descriptor:
Total length:     0095
Num.intf:         03
Conf.value:       02
Conf.string:      06
Attr.:            C0
Max.pwr:          FA

Interface descriptor:
Intf.number:      00
Alt.:             00
Endpoints:        00
Class:            01
Subclass:         01
Protocol:         00
Intf.string:      00

Unknown descriptor:
Length:           09
Type:             24
Contents:
0100011E0001010C24

Unknown descriptor:
Length:           0C
Type:             24
Contents:
020101020202030000000924

Unknown descriptor:
Length:           09
Type:             24
Contents:
030201010101000904

Interface descriptor:
Intf.number:      01
Alt.:             00
Endpoints:        00
Class:            01
Subclass:         02
Protocol:         00
Intf.string:      00

Interface descriptor:
Intf.number:      01
Alt.:             01
Endpoints:        01
Class:            01
Subclass:         02
Protocol:         00
Intf.string:      00

Unknown descriptor:
Length:           07
Type:             24
Contents:
01020101002324

Unknown descriptor:
Length:           23
Type:             24
Contents:
020102021009401F00112
B00E02E00803E00225600
C05D00007D0044AC0080B
B000905

Endpoint descriptor:
Endpoint address: 81
Attr.:            01
Max.pkt size:     00C0
Polling interval: 01

Unknown descriptor:
Length:           07
Type:             25
Contents:
01010000000904

Interface descriptor:
Intf.number:      02
Alt.:             00
Endpoints:        01
Class:            03
Subclass:         00
Protocol:         00
Intf.string:      00

Unknown descriptor:
Length:           09
Type:             21
Contents:
110100012260000705

Endpoint descriptor:
Endpoint address: 83
Attr.:            03
Max.pkt size:     0040
Polling interval: 01
Configuration: 2

Configuration descriptor:
Total length:     003E
Num.intf:         02
Conf.value:       03
Conf.string:      07
Attr.:            C0
Max.pwr:          FA

Interface descriptor:
Intf.number:      00
Alt.:             00
Endpoints:        03
Class:            06
Subclass:         01
Protocol:         01
Intf.string:      00

Endpoint descriptor:
Endpoint address: 02
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Endpoint descriptor:
Endpoint address: 81
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Endpoint descriptor:
Endpoint address: 83
Attr.:            03
Max.pkt size:     0040
Polling interval: 40

Interface descriptor:
Intf.number:      01
Alt.:             00
Endpoints:        02
Class:            FF
Subclass:         FE
Protocol:         02
Intf.string:      00

Endpoint descriptor:
Endpoint address: 04
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Endpoint descriptor:
Endpoint address: 85
Attr.:            02
Max.pkt size:     0040
Polling interval: 00
Configuration:    3

Configuration descriptor:
Total length:     005E
Num.intf:         03
Conf.value:       04
Conf.string:      08
Attr.:            C0
Max.pwr:          FA

Interface descriptor:
Intf.number:      00
Alt.:             00
Endpoints:        03
Class:            06
Subclass:         01
Protocol:         01
Intf.string:      00

Endpoint descriptor:
Endpoint address: 02
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Endpoint descriptor:
Endpoint address: 81
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Endpoint descriptor:
Endpoint address: 83
Attr.:            03
Max.pkt size:     0040
Polling interval: 40

Interface descriptor:
Intf.number:      01
Alt.:             00
Endpoints:        02
Class:            FF
Subclass:         FE
Protocol:         02
Intf.string:      00

Endpoint descriptor:
Endpoint address: 04
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Endpoint descriptor:
Endpoint address: 85
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Interface descriptor:
Intf.number:      02
Alt.:             00
Endpoints:        00
Class:            FF
Subclass:         FD
Protocol:         01
Intf.string:      00

Interface descriptor:
Intf.number:      02
Alt.:             01
Endpoints:        02
Class:            FF
Subclass:         FD
Protocol:         01
Intf.string:      00

Endpoint descriptor:
Endpoint address: 86
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Endpoint descriptor:
Endpoint address: 05
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

The key here is Class field in interface descriptor – we know that still image capture device is identified by class 6. As we can see, configurations 0, 2 and 3 have potential. However, after much testing I found that none of these configurations support camera control commands. Here is another example of “Class 6 device” configuration, taken from Canon XSi camera – :

Configuration: 0
Configuration descriptor:
Total length:     0027
Num.intf:         01
Conf.value:       01
Conf.string:      00
Attr.:            C0
Max.pwr:          01

Interface descriptor:
Intf.number:      00
Alt.:             00
Endpoints:        03
Class:            06
Subclass:         01
Protocol:         01
Intf.string:      00

Endpoint descriptor:
Endpoint address: 81
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Endpoint descriptor:
Endpoint address: 02
Attr.:            02
Max.pkt size:     0040
Polling interval: 00

Endpoint descriptor:
Endpoint address: 83
Attr.:            03
Max.pkt size:     0008
Polling interval: 20

Number 6 in interface Class field doesn’t guarantee functionality but at least this configuration can then be activated and checked with PTP queries. It’s worth mentioning that in some cameras different configurations can be activated via camera menu and very often configuration which has “PTP” in it’s name is not the one we need. For example, Canon 5D has “PC Connection” configuration containing FF in interface class field and “PTP/Print” one with class 06. Even though both configurations talk PTP, PC Connection configuration is the one that supports remote control. This strangeness can be explained by the fact that Canon had proprietary camera control long before PTP and their first PTP implementation was written in order to be able to interact with third-party picture printers.

Let’s talk briefly about PTP protocol. A unit of information exchange in PTP protocol is called a transaction. Camera commands, requests and responses travel inside transactions. In turn, transactions are exchanged within sessions – to send something to the camera, a session would have to be opened first (one exception being “Get Device Info” request, more about it later). Many times several responses are given to a single request, the first one meaning camera understood the request, the second one generated when requested command has been executed, and then another one reflecting camera changes resulted in command execution, like image file apperared after a picture has been taken. Some types of responses have specific meaning and are called events. In order to make a shot, program needs to open a session to the camera, set PC connection mode, send shutter release command, wait for “Shutter released” event, then wait until a new file appears on the memory card (another event) and only after that consider the job done and close the session. Data flow of other commands is similar; to change aperture we need to send aperture value and wait for “aperture changed” event. Skipping commands or requests for new events in the sequence usually causes camera to hang – it would execute a command or two and then become unresponsive and would have to be power cycled. Hanging of the camera is harmless and shall be anticipated during development.

Another piece of PTP device is properties. In digital camera, most properties contain shooting parameters. Typical example of a property is shutter speed value – this property can be changed. Another property is battery level. We won’t be able to change it directly but can request it’s value. There are also properties which both change by itself and can be changed externally; one good example is camera’s real-time clock.

Lastly, there are objects contained in storages. For cameras, this is mainly files on memory card and their significance in Arduino-based applications is minor.

It’s now time to start controlling our cameras. The very first piece of software is a sketch that queries PTP device and prints out it’s capabilities. It uses GetDeviceInfo command (or operation) to output device capabilities. GetDeviceInfo is the only PTP operation which can be sent to the device without opening a session first. You will need al 3 files from this directory as well as files from ptp directory copied into %arduino%/hardware/libraries/ptp directory. This sketch is not camera-specific – it shall work with any class 6 device (as well as some proprietary ones, see note about Canon 5D above). Regretfully, this sketch won’t fit into 16K Arduinos – parser strings eat too much memory and more strings will be added in the future when more vendor-specific commands become known.

Here is PTPDevInfo output of an iPhone:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
iPhone
Start
 
Device configured.: 0x0000
 
0000:ED 00 00 00 02 00 01 10 01 00 00 00 64 00 00 00
0010:00 00 00 00 20 44 00 65 00 76 00 69 00 63 00 65
0020:00 20 00 68 00 61 00 73 00 20 00 6E 00 6F 00 20
0030:00 76 00 65 00 6E 00 64 00 6F 00 72 00 20 00 65
0040:00 78 00 74 00 65 00 6E 00 73 00 69 00 6F 00 6E
0050:00 73 00 00 00 00 00 0E 00 00 00 01 10 02 10 03
0060:10 04 10 05 10 06 10 07 10 08 10 09 10 0A 10 0B
0070:10 14 10 15 10 1B 10 01 00 00 00 06 40 00 00 00
0080:00 03 00 00 00 01 38 0B 38 0D 38 03 00 00 00 01
0090:38 0B 38 0D 38 0B 41 00 70 00 70 00 6C 00 65 00
00A0:20 00 49 00 6E 00 63 00 2E 00 00 00 0D 41 00 70
00B0:00 70 00 6C 00 65 00 20 00 69 00 50 00 68 00 6F
00C0:00 6E 00 65 00 00 00 06 33 00 2E 00 31 00 2E 00
00D0:33 00 00 00 0C 38 00 36 00 38 00 33 00 30 00 50
00E0:00 45 00 32 00 59 00 37 00 48 00 00 00
 
Std. Ver.:  0x100
Vendor ID:  0x0(Unknown)
 
Vend.Ext.Ver.:  0x0
Device has no vendor extensionsFunc.Mode: 0x8C7
 
 
 
Operations supported:
 
1001  GetDeviceInfo
1002  OpenSession
1003  CloseSession
1004  GetStorageIDs
1005  GetStorageInfo
1006  GetNumObjects
1007  GetObjectHandles
1008  GetObjectInfo
1009  GetObject
100A  GetThumb
100B  DeleteObject
1014  GetDevicePropDesc
1015  GetDevicePropValue
101B  GetPartialObject
 
Events supported:
 
4006  DevicePropChanged
 
Device properties supported:
 
Capture formats:
 
3801  EXIF_JPEG
380B  PNG
380D  TIFF
 
Image Formats:
 
3801  EXIF_JPEG
380B  PNG
380D  TIFF
 
Manufacturer: Apple Inc.
 
Model:  Apple iPhone
Device version: 3.1.3
Serial number:  86830PE2Y7H

The output starts with hex dump of the response and device operations start at line 31. The first operation, 1001 or GetDeviceInfo, it the very operation that was used to retrieve this information. The “OpenSession” and “Close Session”, as you may have guessed, are used to open and close a session with the device, the rest are used for file manipulation – not very useful. Let’s now take a look at GetDeviceInfo of a real camera, in this case, Canon 400D:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
Canon 400D
Start
Device configured.: 0x0000
Opening session #: : 0x0001
OpenSession: Session opened.: 0x2001
0000:5D 01 00 00 02 00 01 10 02 00 00 00 64 00 0B 00
0010:00 00 C8 00 00 00 00 38 00 00 00 14 10 16 10 15
0020:10 01 10 02 10 03 10 13 90 04 10 05 10 06 10 07
0030:10 08 10 0A 10 09 10 1B 10 0C 10 0D 10 0B 10 01
0040:91 02 91 03 91 04 91 07 91 05 91 17 91 18 91 16
0050:91 0F 91 15 91 10 91 14 91 13 91 06 91 0A 91 0B
0060:91 0C 91 0E 91 1A 91 1B 91 1C 91 1D 91 08 91 1F
0070:91 09 91 1E 91 20 91 21 91 0F 10 01 98 02 98 03
0080:98 04 98 05 98 FE 91 FF 91 1F 90 04 00 00 00 09
0090:40 04 40 05 40 01 C1 06 00 00 00 45 D0 02 D4 07
00A0:D4 06 D4 49 D0 4A D0 01 00 00 00 01 38 09 00 00
00B0:00 01 30 02 30 0A 30 08 30 01 38 01 B1 03 B1 02
00C0:BF 00 38 0B 43 00 61 00 6E 00 6F 00 6E 00 20 00
00D0:49 00 6E 00 63 00 2E 00 00 00 17 43 00 61 00 6E
00E0:00 6F 00 6E 00 20 00 45 00 4F 00 53 00 20 00 34
00F0:00 30 00 30 00 44 00 20 00 44 00 49 00 47 00 49
0100:00 54 00 41 00 4C 00 00 00 08 33 00 2D 00 31 00
0110:2E 00 31 00 2E 00 31 00 00 00 21 30 00 30 00 30
0120:00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30
0130:00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 30
0140:00 30 00 30 00 30 00 30 00 30 00 31 00 39 00 61
0150:00 33 00 32 00 37 00 66 00 39 00 00 00
 
Std.Ver.:	0x100
Vendor Ext. ID:	0xB(Canon)
 
Vend.Ext.Ver.:	0xC8
 
Func.Mode:	0x8C7
 
Operations supported:
1014	GetDevicePropDesc
1016	SetDevicePropValue
1015	GetDevicePropValue
1001	GetDeviceInfo
1002	OpenSession
1003	CloseSession
9013	PS_CheckEvent
1004	GetStorageIDs
1005	GetStorageInfo
1006	GetNumObjects
1007	GetObjectHandles
1008	GetObjectInfo
100A	GetThumb
1009	GetObject
101B	GetPartialObject
100C	SendObjectInfo
100D	SendObject
100B	DeleteObject
9101	EOS_GetStorageIDs
9102	EOS_GetStorageInfo
9103	Vendor defined
9104	Vendor defined
9107	EOS_GetObject
9105	Vendor defined
9117	Vendor defined
9118	Vendor defined
9116	EOS_GetEvent
910F	EOS_Capture
9115	EOS_SetExtendedEventInfo
9110	EOS_SetDevicePropValue
9114	EOS_SetPCConnectMode
9113	Vendor defined
9106	Vendor defined
910A	Vendor defined
910B	Vendor defined
910C	Vendor defined
910E	Vendor defined
911A	Vendor defined
911B	Vendor defined
911C	Vendor defined
911D	Vendor defined
9108	EOS_GetDeviceInfo
911F	Vendor defined
9109	EOS_GetObjectIDs
911E	Vendor defined
9120	Vendor defined
9121	Vendor defined
100F	FormatStore
9801	GetObjectPropsSupported
9802	GetObjectPropDesc
9803	GetObjectPropValue
9804	SetObjectPropValue
9805	GetObjectPropList
91FE	Vendor defined
91FF	Vendor defined
901F	Vendor defined
 
Events supported:
4009	RequestObjectTransfer
4004	StoreAdded
4005	StoreRemoved
C101	Vendor defined
 
Device properties supported:
D045	Vendor defined
D402	Device_Friendly_Name
D407	Perceived_Device_Type
D406	Session_Initiator_Version_Info
D049	Vendor defined
D04A	Vendor defined
 
Capture formats:
3801	EXIF_JPEG
 
Image Formats:
3001	Association
3002	Script
300A	AVI
3008	WAV
3801	EXIF_JPEG
B101	Vendor defined
B103	Vendor defined
BF02	Vendor defined
3800	Undefined
 
Manufacturer:	Canon Inc.
Model:		Canon EOS 400D DIGITAL
Device ver.:	3-1.1.1
Serial num.:	00000000000000000000000019a327f9
 
Closing session #: : 0x0001
Session closed.: 0x2001

This output lists many vendor-specific functions, some of which are used for camera control. Even though standard PTP contains many camera control commands, vendors tend to write their own, sometimes duplicating even non-camera control functions. The functions which name starts with “EOS” are Canon-specific.”Vendor defined” functions are also Canon-specific functions whose purpose is yet unknown.

GetDeviceInfo is a powerful tool to compare functionality of different cameras from the same vendor. Functions with the same number often perform identical actions. For example, the following output taken from Canon xSi camera shows the same EOS_Capture command as in 400D (910f, line 64 in 400D output, line 75 in xSi output). Indeed, shutter release code for 400D works identically on xSi.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
Canon xSi
Start
 
Device configured.: 0x0000
Opening session #: : 0x0001
OpenSession: Session opened.: 0x2001
 
0000:7B 01 00 00 02 00 01 10 02 00 00 00 64 00 06 00
0010:00 00 C8 00 00 00 00 41 00 00 00 14 10 15 10 16
0020:10 01 10 02 10 03 10 06 10 04 10 01 91 05 10 02
0030:91 07 10 08 10 03 91 09 10 04 91 0A 10 1B 10 07
0040:91 0C 10 0D 10 0B 10 05 91 0F 10 06 91 10 91 27
0050:91 0B 91 08 91 09 91 0C 91 0E 91 0F 91 25 91 26
0060:91 15 91 14 91 13 91 16 91 17 91 20 91 F0 91 18
0070:91 21 91 F1 91 1D 91 0A 91 1B 91 1C 91 1E 91 1A
0080:91 53 91 54 91 55 91 57 91 58 91 59 91 1F 91 FE
0090:91 FF 91 01 98 02 98 03 98 04 98 05 98 07 00 00
00A0:00 09 40 04 40 05 40 03 40 02 40 07 40 01 C1 03
00B0:00 00 00 02 D4 07 D4 06 D4 01 00 00 00 01 38 0A
00C0:00 00 00 01 30 02 30 06 30 0A 30 08 30 01 38 01
00D0:B1 03 B1 02 BF 00 38 0B 43 00 61 00 6E 00 6F 00
00E0:6E 00 20 00 49 00 6E 00 63 00 2E 00 00 00 1C 43
00F0:00 61 00 6E 00 6F 00 6E 00 20 00 45 00 4F 00 53
0100:00 20 00 44 00 49 00 47 00 49 00 54 00 41 00 4C
0110:00 20 00 52 00 45 00 42 00 45 00 4C 00 20 00 58
0120:00 53 00 69 00 00 00 08 33 00 2D 00 31 00 2E 00
0130:31 00 2E 00 30 00 00 00 21 62 00 36 00 32 00 31
0140:00 30 00 66 00 66 00 64 00 31 00 32 00 37 00 39
0150:00 34 00 66 00 32 00 63 00 61 00 33 00 61 00 64
0160:00 32 00 33 00 64 00 31 00 32 00 39 00 36 00 63
0170:00 32 00 31 00 35 00 38 00 00 00
 
 
Std.Ver.:	0x100
Vendor Ext. ID:	0x6(Microsoft)
 
Vend.Ext.Ver.:	0xC8
 
Func.Mode:	0x8C7
 
Operations supported:
 
1014	GetDevicePropDesc
1015	GetDevicePropValue
1016	SetDevicePropValue
1001	GetDeviceInfo
1002	OpenSession
1003	CloseSession
1006	GetNumObjects
1004	GetStorageIDs
9101	EOS_GetStorageIDs
1005	GetStorageInfo
9102	EOS_GetStorageInfo
1007	GetObjectHandles
1008	GetObjectInfo
9103	Vendor defined
1009	GetObject
9104	Vendor defined
100A	GetThumb
101B	GetPartialObject
9107	EOS_GetObject
100C	SendObjectInfo
100D	SendObject
100B	DeleteObject
9105	Vendor defined
100F	FormatStore
9106	Vendor defined
9110	EOS_SetDevicePropValue
9127	Vendor defined
910B	Vendor defined
9108	EOS_GetDeviceInfo
9109	EOS_GetObjectIDs
910C	Vendor defined
910E	Vendor defined
910F	EOS_Capture
9125	Vendor defined
9126	Vendor defined
9115	EOS_SetExtendedEventInfo
9114	EOS_SetPCConnectMode
9113	Vendor defined
9116	EOS_GetEvent
9117	Vendor defined
9120	Vendor defined
91F0	Vendor defined
9118	Vendor defined
9121	Vendor defined
91F1	Vendor defined
911D	Vendor defined
910A	Vendor defined
911B	Vendor defined
911C	Vendor defined
911E	Vendor defined
911A	Vendor defined
9153	EOS_GetLiveViewPicture
9154	Vendor defined
9155	EOS_MoveFocus
9157	Vendor defined
9158	Vendor defined
9159	Vendor defined
911F	Vendor defined
91FE	Vendor defined
91FF	Vendor defined
9801	GetObjectPropsSupported
9802	GetObjectPropDesc
9803	GetObjectPropValue
9804	SetObjectPropValue
9805	GetObjectPropList
 
Events supported:
 
4009	RequestObjectTransfer
4004	StoreAdded
4005	StoreRemoved
4003	ObjectRemoved
4002	ObjectAdded
4007	ObjectInfoChanged
C101	Vendor defined
 
Device properties supported:
 
D402	Device_Friendly_Name
D407	Perceived_Device_Type
D406	Session_Initiator_Version_Info
 
Capture formats:
 
3801	EXIF_JPEG
 
Image Formats:
 
3001	Association
3002	Script
3006	DPOF
300A	AVI
3008	WAV
3801	EXIF_JPEG
B101	Vendor defined
B103	Vendor defined
BF02	Vendor defined
3800	Undefined
 
 
Manufacturer:	Canon Inc.
Model:		Canon EOS DIGITAL REBEL XSi
Device ver.:	3-1.1.0
Serial num.:	b6210ffd12794f2ca3ad23d1296c2158
 
Closing session #: : 0x0001
Session closed.: 0x2001

Modern Canon EOS cameras have function set similar to the one above. However, if we look into older cameras, they give very different output. Below is GetDeviceInfo output from my old trusty Canon 5D. As you can see, it has no resemblance to xSi or 400D. In fact, it looks like Canon Powershot A640 output, which is posted just below this one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
Canon 5D
Start
Device configured.: 0x0000
Opening session #: : 0x0001
OpenSession: Session opened.: 0x2001
0000:0B 01 00 00 02 00 01 10 02 00 00 00 01 00 0B 00
0010:00 00 64 00 00 00 00 1D 00 00 00 14 10 15 10 16
0020:10 17 10 01 10 02 10 03 10 13 90 04 10 05 10 06
0030:10 07 10 08 10 09 10 0A 10 1B 10 0C 10 0D 10 0B
0040:10 01 90 02 90 06 90 0E 90 1B 90 1C 90 1E 90 21
0050:90 0F 10 1F 90 16 00 00 00 01 40 02 40 03 40 04
0060:40 05 40 06 40 07 40 08 40 09 40 0A 40 0C 40 0D
0070:40 01 C0 05 C0 06 C0 07 C0 08 C0 09 C0 0A C0 0B
0080:C0 0C C0 0D C0 10 00 00 00 45 D0 02 D0 03 D0 2C
0090:D0 2D D0 49 D0 32 D0 31 D0 34 D0 33 D0 2E D0 2F
00A0:D0 46 D0 47 D0 30 D0 4A D0 01 00 00 00 01 38 08
00B0:00 00 00 02 30 06 30 0A 30 08 30 01 38 01 B1 03
00C0:B1 02 BF 0B 43 00 61 00 6E 00 6F 00 6E 00 20 00
00D0:49 00 6E 00 63 00 2E 00 00 00 0D 43 00 61 00 6E
00E0:00 6F 00 6E 00 20 00 45 00 4F 00 53 00 20 00 35
00F0:00 44 00 00 00 0A 33 00 2D 00 30 00 2E 00 30 00
0100:2E 00 30 00 2E 00 31 00 00 00 00
 
Std.Ver.:       0x1
Vendor Ext. ID: 0xB(Canon)
 
Vend.Ext.Ver.:  0x64
 
Func.Mode:      0x8C7
 
Operations supported:
1014    GetDevicePropDesc
1015    GetDevicePropValue
1016    SetDevicePropValue
1017    ResetDevicePropValue
1001    GetDeviceInfo
1002    OpenSession
1003    CloseSession
9013    PS_CheckEvent
1004    GetStorageIDs
1005    GetStorageInfo
1006    GetNumObjects
1007    GetObjectHandles
1008    GetObjectInfo
1009    GetObject
100A    GetThumb
101B    GetPartialObject
100C    SendObjectInfo
100D    SendObject
100B    DeleteObject
9001    PS_GetObjectSize
9002    Vendor defined
9006    Vendor defined
900E    Vendor defined
901B    PS_GetPartialObject
901C    Vendor defined
901E    Vendor defined
9021    PS_GetFolderEntries
100F    FormatStore
901F    Vendor defined
 
Events supported:
4001    CancelTransaction
4002    ObjectAdded
4003    ObjectRemoved
4004    StoreAdded
4005    StoreRemoved
4006    DevicePropChanged
4007    ObjectInfoChanged
4008    DeviceInfoChanged
4009    RequestObjectTransfer
400A    StoreFull
400C    StorageInfoChanged
400D    CaptureComplete
C001    Vendor defined
C005    Vendor defined
C006    Vendor defined
C007    Vendor defined
C008    Vendor defined
C009    Vendor defined
C00A    Vendor defined
C00B    Vendor defined
C00C    Vendor defined
C00D    Vendor defined
 
Device properties supported:
D045    Vendor defined
D002    Vendor defined
D003    Vendor defined
D02C    Vendor defined
D02D    Vendor defined
D049    Vendor defined
D032    Vendor defined
D031    Vendor defined
D034    Vendor defined
D033    Vendor defined
D02E    Vendor defined
D02F    Vendor defined
D046    Vendor defined
D047    Vendor defined
D030    Vendor defined
D04A    Vendor defined
 
Capture formats:
3801    EXIF_JPEG
 
Image Formats:
3002    Script
3006    DPOF
300A    AVI
3008    WAV
3801    EXIF_JPEG
B101    Vendor defined
B103    Vendor defined
BF02    Vendor defined
 
Manufacturer:   Canon Inc.
Model:          Canon EOS 5D
Device ver.:    3-0.0.0.1
Serial num.:
 
Closing session #: : 0x0001
Session closed.: 0x2001
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
Canon Powershot A640
Start
Device configured.: 0x0000
Opening session #: : 0x0001
OpenSession: Session opened.: 0x2001
0000:AD 01 00 00 02 00 01 10 02 00 00 00 64 00 06 00
0010:00 00 64 00 00 00 00 3E 00 00 00 14 10 15 10 16
0020:10 17 10 01 10 02 10 03 10 13 90 1F 90 04 10 05
0030:10 06 10 07 10 08 10 09 10 0A 10 1B 10 0C 10 0D
0040:10 0B 10 0F 10 12 10 01 90 21 90 1B 90 1E 90 19
0050:90 06 90 1C 90 02 90 2C 90 2D 90 2E 90 24 90 25
0060:90 0E 90 0F 90 10 90 11 90 28 90 23 90 29 90 2A
0070:90 2B 90 34 90 0E 10 08 90 1A 90 09 90 0B 90 1D
0080:90 0D 90 0C 90 14 90 15 90 18 90 12 90 01 98 02
0090:98 03 98 04 98 05 98 1A 00 00 00 01 40 02 40 03
00A0:40 04 40 05 40 06 40 07 40 08 40 09 40 0A 40 0B
00B0:40 0C 40 0D 40 0E 40 01 C0 05 C0 08 C0 09 C0 0A
00C0:C0 0B C0 0C C0 0D C0 0E C0 0F C0 11 C0 13 C0 13
00D0:00 00 00 45 D0 4A D0 2E D0 2F D0 02 D0 03 D0 34
00E0:D0 47 D0 46 D0 2D D0 48 D0 2C D0 30 D0 49 D0 32
00F0:D0 33 D0 31 D0 02 D4 07 D4 01 00 00 00 01 38 08
0100:00 00 00 01 30 02 30 06 30 0A 30 08 30 01 38 01
0110:B1 01 BF 0B 43 00 61 00 6E 00 6F 00 6E 00 20 00
0120:49 00 6E 00 63 00 2E 00 00 00 15 43 00 61 00 6E
0130:00 6F 00 6E 00 20 00 50 00 6F 00 77 00 65 00 72
0140:00 53 00 68 00 6F 00 74 00 20 00 41 00 36 00 34
0150:00 30 00 00 00 0A 31 00 2D 00 33 00 2E 00 32 00
0160:2E 00 31 00 2E 00 30 00 00 00 21 46 00 32 00 31
0170:00 44 00 42 00 35 00 38 00 31 00 44 00 46 00 37
0180:00 44 00 34 00 38 00 30 00 43 00 39 00 41 00 34
0190:00 32 00 33 00 37 00 37 00 39 00 43 00 39 00 38
01A0:00 46 00 33 00 39 00 38 00 32 00 00 00
 
Std.Ver.:       0x100
Vendor Ext. ID: 0x6(Microsoft)
 
Vend.Ext.Ver.:  0x64
 
Func.Mode:      0x8C7
 
Operations supported:
1014    GetDevicePropDesc
1015    GetDevicePropValue
1016    SetDevicePropValue
1017    ResetDevicePropValue
1001    GetDeviceInfo
1002    OpenSession
1003    CloseSession
9013    PS_CheckEvent
901F    Vendor defined
1004    GetStorageIDs
1005    GetStorageInfo
1006    GetNumObjects
1007    GetObjectHandles
1008    GetObjectInfo
1009    GetObject
100A    GetThumb
101B    GetPartialObject
100C    SendObjectInfo
100D    SendObject
100B    DeleteObject
100F    FormatStore
1012    SetObjectProtection
9001    PS_GetObjectSize
9021    PS_GetFolderEntries
901B    PS_GetPartialObject
901E    Vendor defined
9019    Vendor defined
9006    Vendor defined
901C    Vendor defined
9002    Vendor defined
902C    Vendor defined
902D    Vendor defined
902E    Vendor defined
9024    Vendor defined
9025    Vendor defined
900E    Vendor defined
900F    Vendor defined
9010    Vendor defined
9011    Vendor defined
9028    Vendor defined
9023    Vendor defined
9029    Vendor defined
902A    Vendor defined
902B    Vendor defined
9034    Vendor defined
100E    InitiateCapture
9008    PS_StartShootingMode
901A    PS_InitiateCaptureInMemory
9009    PS_EndShootingMode
900B    PS_ViewfinderOn
901D    PS_GetViewfinderImage
900D    PS_ReflectChanges
900C    PS_ViewfinderOff
9014    PS_FocusLock
9015    PS_FocusUnlock
9018    Vendor defined
9012    Vendor defined
9801    GetObjectPropsSupported
9802    GetObjectPropDesc
9803    GetObjectPropValue
9804    SetObjectPropValue
9805    GetObjectPropList
 
Events supported:
4001    CancelTransaction
4002    ObjectAdded
4003    ObjectRemoved
4004    StoreAdded
4005    StoreRemoved
4006    DevicePropChanged
4007    ObjectInfoChanged
4008    DeviceInfoChanged
4009    RequestObjectTransfer
400A    StoreFull
400B    DeviceReset
400C    StorageInfoChanged
400D    CaptureComplete
400E    UnreportedStatus
C001    Vendor defined
C005    Vendor defined
C008    Vendor defined
C009    Vendor defined
C00A    Vendor defined
C00B    Vendor defined
C00C    Vendor defined
C00D    Vendor defined
C00E    Vendor defined
C00F    Vendor defined
C011    Vendor defined
C013    Vendor defined
 
Device properties supported:
D045    Vendor defined
D04A    Vendor defined
D02E    Vendor defined
D02F    Vendor defined
D002    Vendor defined
D003    Vendor defined
D034    Vendor defined
D047    Vendor defined
D046    Vendor defined
D02D    Vendor defined
D048    Vendor defined
D02C    Vendor defined
D030    Vendor defined
D049    Vendor defined
D032    Vendor defined
D033    Vendor defined
D031    Vendor defined
D402    Device_Friendly_Name
D407    Perceived_Device_Type
 
Capture formats:
3801    EXIF_JPEG
 
Image Formats:
3001    Association
3002    Script
3006    DPOF
300A    AVI
3008    WAV
3801    EXIF_JPEG
B101    Vendor defined
BF01    Vendor defined
 
Manufacturer:   Canon Inc.
Model:          Canon PowerShot A640
Device ver.:    1-3.2.1.0
Serial num.:    F21DB581DF7D480C9A423779C98F3982
 
Closing session #: : 0x0001
Session closed.: 0x2001

When analyzing output posted above, we can see that this camera actually supports standard PTP “Initiate Capture” command (100E, line 87) as well as “Capture Complete” event (400D, line 118).

Here is a bonus for those who managed to get to this point – a sketch that performs shutter release on Canon EOS camera. It had been tested on 400D and xSi and will most likely work on cameras with the same 910f EOS_Capture command listed in GetDeviceInfo output. The sketch is available in the PTP examples on github, and copied below for your viewing pleasure:
[EDIT] This code doesn’t work with current PTP/EOS library. The correct code is here

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/* EOS Capture Example. Works on cameras listed in canoneos.h */
#include <inttypes.h>
#include <avr/pgmspace.h>
 
#include <spi.h>
#include <max3421e.h>
#include <max3421e_constants.h>
#include <max_LCD.h>
#include <usb.h>
 
#include <ptp.h>
#include <canoneos.h>
 
#define DEV_ADDR        1
 
// Canon EOS 400D
#define DATA_IN_EP      1
#define DATA_OUT_EP     2
#define INTERRUPT_EP    3
#define CONFIG_NUM      1
 
#define MAX_USB_STRING_LEN 64
 
void setup();
void loop();
void ptpmain();
 
CanonEOS  Eos(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, (PTPMAIN)&ptpmain);
 
void setup() {
  Serial.begin( 9600 );
  Serial.println("Start");
  Eos.Setup();
  delay( 200 );
}
 
void loop() {
    Eos.Task();
}
 
void ptpmain()
{
    if (Eos.OpenSession() == PTP_RC_OK)
    {
                Eos.Initialize(true);
                Eos.Capture();
                delay(2000);
                Eos.Initialize(false);
		Eos.CloseSession();
    }
}

As you can see, the sketch is quite short for the amount of work it is doing and simple to understand thanks to Alex’s library structure design. Main functionality is presented on lines 41-51 – Open Session, Capture, Close Session. Delay is inserted to give camera time to save captured image; in real life applications it’s necessary to poll camera for “Object Created” event instead.

Due to the amount of material, writing about camera control can be challenging. Many things are much easier to the writer to present rather than explain; presentation style is also easier for the reader to digest. I’m currently working on simple camera controller design consisting of USB Host Shield, LCD display, rotary encoder plus a button or two and will be using it to present ways to use the library in various automatic shooting applications. I’m hoping to finish it in the next week or two, weather permitting, and publish the next program. Stay tuned!

Oleg.

190 comments to Digital camera control using Arduino USB Host Shield. Part 1 – basics.

  • Santiago

    I enjoyed this article the bit on multiple configurations is very useful for various projects.

  • niwi

    Hi,

    I’m working with your project files. Do you need the PTP device information output from other cameras?

    I just checked the gphoto2 files for the commands and found some others. But some of the commands are still unknown. How can we identify them?

    And another question is, what is else possible?

    I’m thinking of a remote control with the Arduino, maybe with a GPS device connected. After a picture is taken the GPS data could be stored onto the flash card in the camera as simple text file or as .xmp.
    Also if it is possible to get the focus distance (current distance value of the lens), the aperture and the focal length, it should be possible to calculate the depth of field.

    Best regards, Nils.

  • Nils,

    PTP device information from other cameras would be much appreciated! There is a page -> http://www.circuitsathome.com/ptpusb-control-camera-data , where I post what we know already; if you have access to other cameras the PTPDevInfo output from them would be very helpful. E-mail it to mazurov@circuitsathome.com.

    We are finishing with Canon EOS cameras, the “new” command set, supported in 400D, 450D, 5D Mark II. The next system supported is going to be Canon Powershot( we are half-way through it), then Nikon, Olympus, and anything else working via PTP. As far as camera commands, it will be possible to control shutter release, speed, aperture, other parameters, as well as transferring files to and from the camera (the file transfer to the camera is not very well understood yet). Focus distance is a big question; right now, I can’t say if this would be possible.

    As far as adding other devices to camera controller, that shouldn’t be a problem. I have an experimental setup with shutter release working concurrently with WiFi module on Asynclabs BlackWidow board; PTP plus webserver fits in 22K.

    Good luck with your project and let me know if you need anything else.

    Oleg.

  • Sandro

    Oleg, congratulations for the nice work on the USB host!!! I bought one at Sparkfun last week. My first intention is to use it on my quadrotor to take aerial photos, controlling it with the transmitter’s sticks. Actually, at now I have a very simple code that works with a hardware trigger based on a circuit described in . It’s nice but limited to only shoot the camera.

    By other hand, with your USB Host hardware and the PTP’s library, will be possible to control zooming and everything else. So thank you so much by that nice shield and your codes and support. I’m very happy with it! I was searching it for a long time… and now it’s here, on my hands in Brazil.
    I will read all your articles and try to learn how to use it on my S3IS. 🙂

  • Camille

    hello I’d like to implement this Operation Code on My EOS1000D
    PTP_OC_CANON_EOS_RequestDevicePropValue(0x9127 )
    I’d like to know first the Device Prop Value for just increment and decrement them

    I send a (int32_to_char4)16 bytes packets:
    code = (int16_to_char2)PTP_OC_CANON_EOS_RequestDevicePropValue(0x9127 )
    type = (int16_to_char2)PTP_CONTAINER_TYPE_COMMAND;
    param1 = (int32_to_char4)PTP_DPC_CANON_EOS_Aperture (0xD101 )
    resonse:
    lenght 12 byte
    general error code 0x2002
    have you try this command?

  • Omi

    Love this project! I have a Canon 500D I want to interface with but at present I only have a 16k Arduino. I’m waiting to buy the blackwidow so I won’t get a 32k arduino for a while. Is there anything I can strip out to get the sketch below 14336 bytes? 🙂

    I am familiar with C but not with large programs. Thanks!

    • Omi

      Nevermind, I trimmed devinfoparser.h and .cpp down to exactly 14336 bytes 🙂 I got some junk in the Capture formats and Image formats because I deleted those constants.

  • Tim

    Thank you so much Oleg for starting this project. I started to mess around with the host shield and a rebel XS (i think?) I got it to work no problem, what I was wondering though is possible to query the camera to get exposure info from it. I would love to be able to find out what the current shutter speed is and file name info. I figured out how to use the non-PTP device properties but I’m not sure how to work with the operation codes? I spent about an hour today figuring out the hex value that corresponds with each shutter speed, i’m guessing you’ve already got this info but if not I have it in a spreadsheet if anyone wants it.
    Thank you again.

    • Tim

      I guess what i’m trying to figure out is how to poll the camera. You mentioned you would need “to poll camera for “Object Created”” Which function would I use to do this?

      Thanks

  • Sandro

    I’m doing a transcription of the EOSCapture code to PSCapture (using canonps.h) for PowerShoot series.
    I done the descriptor dumping and device info extraction of S3IS. All is OK.

    About the transcription: Please, can you tell me where this data come from?

    #define DEV_ADDR 1

    // Canon EOS 400D
    #define DATA_IN_EP 1
    #define DATA_OUT_EP 2
    #define INTERRUPT_EP 3
    #define CONFIG_NUM 1

    Thank you in advance!

    Regards

    • DEV_ADDR should be set to 1 – it’s USB device address, only one is supported at present. The rest comes from configuration descriptor; look in the article for configraton descriptor data. CONFIG_NUM is configuration value (conf.value). You use this number to “turn on” certain configuration. DATA_IN_EP, DATA_OUT_EP and INTERRUPT_EP are in, out, and interrupt endpoints, this comes from “Endpoint address”. “IN” endpoints, such as data in and interrupt have upper bit set to 1 so endpoint 1 would have its address output as “81”.

      Send me descriptor dump from your camera at mazurov@circuitsathome.com , I’ll tell you which numbers to use.

  • gleb

    Oleg,

    Thanks for all the work, working excellent,

    One question: is there a way to query camera parameters, for example, current exposure speed, or aperture?

    Thanks!

    Gleb

  • Camera sends parameters by itself, you can’t query it; one time in the beginning is sends all its’ parameters, then it sends new parameter value when it gets changed. When you change camera mode, for example, from Av to Tv, you get fresh dump of all parameters. The code demonstrating parameter parsing is in the works.

    • gleb

      thanks, looking forward to it, mainly I am trying to see if I can switch camera to Av mode, read back the recommended exposure time, then switch back to manual mode and bracket around the recommended exposure time value.

  • will

    Oleg,

    Thank you for providing the libraries and examples. I have a 550D, which I have emailed you the PTPdevinfo from to add to the listings.

    The basic capture example works fine, and I would really like to be able to engage the focus through the software using the MoveFocus function. It appears as though this is only valid while in live view or video mode. Any chance you know how to force the camera into live view if the mode dial is on any of the image capture modes?

    Video mode poses more issues, since as soon as it recognizes the arduino host, it flips the mirror down, preventing you from actually taking any video (or focusing, for that matter).

    I tried monitoring the USB port to see what commands were being called as you initiate live view in the EOS utility. It looks like it sends RemoteReleaseOn, followed by RemoteReleaseOff, then PCHDDCapacity and a few separate SetDevicePropValueEx commands.

    Also, starting/stopping video recording appears to use a SetDevicePropValueEx command, too.

    Unfortunately my USB sniffer (Device Monitoring Studio) is rather awful in trial form, so it’s pretty tedious to sift through all the data.

    • Will,

      I sent you small sketch showing LiveView on/off and moving focus – you can only move focus in LiveView. EOS capture works only if camera is able to focus in auto (it won’t if, for example, lid is on or lens is facing target with no contrast) or lens is switched to manual focus. Moving focus only works when lens is set to autofocus.

      Thank you for PTPdevinfo dump, I’ll add it to the list today or tomorrow!

      Oleg.

      • Boris

        Hello Oleg,

        Can you share the small sketch with the LiveViewOn/Off + Focus?

        Using the Eos.SwitchLiveView(true) gives me a Err 80 on the camera (5DmkII) and the MoveFocus function does nothing, or It freezes with the next Eos.XXXX call.

        Is this because my main code is in the mail loop and not in the pptmain function?

        Can I use a endless while in the pptmain function? (to do all the Eos/PTP stuff I want)

        Regards,

        Boris

        • will

          Unfortunately I won’t have a 5DmkII handy until tomorrow night, so I’m only going off my 550D at the moment. Theoretically the commands should be applicable, as they’re listed in the 5DmkII ptpdevinfo dumps.

          I use a while loop within ptpmain to monitor switches and execute the various EOS commands. The SwitchLiveView function within the currently available camera control library needs a slight change (canoneos.cpp).

          To enable live view the SwitchLiveView function uses the SetProperty command (0xD1B3), and needs to pass it one of three values:
          0 – off
          1 – output to LCD on camera
          2 – output to PC

          The provided function will only send 0 or 2 as the argument, but since you’re using the Arduino as the host, it’s not like it will be able to display the live view, so you actually want to send it a value of 1.

          Change this line in the SwitchLiveView function:
          if ((ptp_error = SetProperty(EOS_DPC_LiveView, (on) ? 2 : 0)) == PTP_RC_OK)

          To this:
          if ((ptp_error = SetProperty(EOS_DPC_LiveView, on)) == PTP_RC_OK)

          Also, as Oleg has mentioned, focus commands only work while live view is enabled. If you are unable to get the live view property change to work, then just turn it on yourself using the button on the camera, then you can test the focus commands.

          This works fine with my 550D:

          void ptpmain()
          {
          if (Eos.OpenSession() == PTP_RC_OK)
          {
          Eos.Initialize(true);

          Serial.println(“live view”);

          Eos.SwitchLiveView(true);

          delay(100);

          while(1) {
          Eos.MoveFocus(0x0002);
          delay(500);
          Eos.MoveFocus(0x8002);
          delay(500);
          }
          }
          }

        • will

          Followup: tested a 5DmkII tonight. The live view function does not work. I will sniff the USB traffic tomorrow to find out what the difference is.

          All the other commands work that I tested, including: image capture, movefocus, digital zoom, video start/stop.

          • will

            Further testing of a 5DmkII reveals that it will accept the liveview property change when the output is set to the PC. You can hear the mirror flip and send it movefocus commands. However, the image doesn’t display on the camera’s LCD (which is expected).

            Sending the 5DmkII the liveview property change with the output set to the camera LCD does not work. It ignores it. I have also tried this using the EDSDK sample and modifying it to send kEdsEvfOutputDevice_TFT instead of kEdsEvfOutputDevice_PC.

            Guess we’ll have to keep digging for a way to get it to work!

          • Hi WIll, please can you tell me which is the command to start/stop video? I am already able to do every other operation, but still not vide start/stop. Thank you

          • Try this:
            Eos.SetProperty(0xd1b8, 4); should start video capture
            Eos.SetProperty(0xd1b8, 0); should stop video capture

            Let me know if this worked.

  • Boris

    Thanks a lot.

    I’ll make some test this Week-End (checking commands from the SDK)

    Regards,

    Boris

    • Boris

      Thanks Again for the Example…

      It works…. I’m trying to make Liveview (on screen) work with the 5D with magnification.

      I do have an “almost usable” focus point store/recall… (using the 3 different step lenths to avoid drift).

      Next par is rotary encoder…

  • Hi there,

    I have a Canon EOS 1D Mark IV and want to build a small remote control using the Arduino. Can someone share with me the small sketch to see if it will ever work with my 1D too? Im want to control the focus manually with a rotary encoder (thanks to Oleg) and the video start/stop with a pushbutton. The LiveView will be activated on the camera directly.

    Also a great feature will be to have the possibility to save 2 focus positions and do rack focusing between these two points with the remote control.
    The same way like the “magic lantern hack” in the 5D Mark II.

    Would be great if someone could help me because Im a complete newbie in programming. I have ideas but no programming experience.

    thanks
    Daniel

    • will

      Saving focus points represents a big problem because of how the camera handles the focus commands. Sending a focus command ALWAYS returns a success, even if it doesn’t actually change the focus.

      What you have to keep in mind is that depending on the focus step size you use, and the focal length of the lens you are using, the time it takes for the camera to actually change the focus varies. In order to set two focus points you would need to have the arduino change from one point to the other (using a couple switches or an encoder), but slowly enough to guarantee that each focus command actually modifies the focus of the camera (so you need to limit the rate the commands are sent). Then, when you want to rack focus between the two saved points, the maximum speed that this can occur also has to be slow enough to ensure that each command is properly accepted, otherwise the focus points will not be accurate, at all.

      Basically, it is possible, but the rack focus will be relatively slow, or else it will not be accurate. You can tune it for a specific lens to maximize the speed, too, but this will require a great deal of testing, as it’s all trial and error, since there’s no feedback from the camera to help you.

    • will

      I realized after submitting the above reply that I wasn’t entirely clear. If you do a simple loop in your sketch to send 10 move focus commands, one after another as fast as possible, all 10 will return the PTP success value, but only perhaps 2 or 3 will actually move the focus. This is why saving focus points is difficult. You can’t simply count how many commands were sent between each point, and cycle back and forth with that number. The only way this works is if you slow down the send rate until you’re sure each focus command actually moves the focus. Additionally, when you’re setting the focus points in the first place, the send rate also has to be slow enough to get an accurate count of valid move focus commands.

      I don’t know if the same focal length between two different lenses (e.g. the EF 50mm f/1.4 USM versus the EF 50mm f/1.8 non-USM) will have the same focus change response times, so it pretty much comes down to a lens by lens basis for figuring out the timing. Zooms are an even bigger problem, as my EF-S 15-85 not only scales the increments differently at 15mm versus 85mm, but the time it takes to change 1 focus increment is also different at the various focal lengths.

      • Just adding to Will’s post – I checked ( eyballometrically ) the speed of focus change in Helicon Focus program, http://www.heliconsoft.com/heliconfocus.html , and it’s about 10 steps per second. It feels very slow on 180/3.5 macro lens but may be better on shorter ones. The focusing speed can be evaluated – the program has free trial period. From my experience, Helicon is the most reliable of PC remote control programs for Canons.

        I was thinking about another way of doing rack focusing by moving and remembering viewfinder focus point and then changing it and pre-focusing. I’m yet to find commands for this, though.

  • I’ve seen this firmware hack from magic lantern where rack focusing & focus stacking is possible in-camera on a 5D Mark II. Take a look at the videos.
    http://magiclantern.wikia.com/wiki/Focus

    Therefore I thought it should work with a remote through USB too.

    • If you move focus using USB commands, you can get focus change rate close to speeds “1”, “2”, and “4” from this video, maybe a little faster.

    • will

      Except that the magic lantern is firmware running on the camera, whereas with USB we’re stuck with whichever focus commands Canon gives us, along with no feedback.

      It *is* possible with USB, but you have to determine the correct speed to issue the commands so that it’s accurate.

      I agree with Oleg. With the smallest focus step size, about 10 per second seems to be the max you can send before losing commands. With the second step size, it’s more like 4 per second.

  • Is this true that you can communicate with the Canon EOS through the SD or CF card slot?
    There are rumours that Canon controls the camera through a CF slot adapter instead of USB. I’ve read that somewhere on a forum when I was searching through the net.
    They’ve used the 5D Mark II for shooting b-roll for a movie on a steadycam and in the slot there was a CF card with onboard wlan. But I can’t find that link in my firefox history.

  • johnj

    To improve focus demand on Canon DSLRs, I think you need some feedback to close the loop.

    One way would be to fix a 1600 ppi resolution optical sensor (eg from an optical mouse, AVAGO chip) close to the focus ring to measure accurately the focus ring movement, then you can use a mix of large and small steps to greatly improve the time to get in focus and be very precise..

    I have seen some hacks of a mouse for use with arduino …

  • will

    johnj, this would only work on a lens without a USM motor, since the focus ring does not turn with USM.

  • Camille

    Sometimes my software bug between the camera and ush host Max3421
    I done that:
    1)I remove the USB cable between Host and Camera (Camera view a high impedance an probably reset it’usb ???)
    2)Push the reset switch on Arduino board
    3)Put the USB cable betwin Host and camera
    And it’s run!!
    It is possible to done a software “big” reset on the Max3421( USB+USB- drive to High impedance???);
    I try that with no result:
    1) Max.vbusPwr ( 0 );delay( 500 );
    Max.vbusPwr ( 1 );delay( 500 );(why this function is not implement?)
    2) Max.reset();delay( 500 );
    Max.powerOn();delay( 500 );
    Max.init();delay( 500 );
    Thanks

    • Camille,

      It’s sometimes tricky to get reliable connect to the camera as they are often OTG devices rather than simple peripheral. They are also self-powered devices and don’t draw power from VBUS so toggling it won’t do you any good. The detection on USB bus is implemented with pull-up/pull-down resistors, if you want to imitate physical disconnect you can disconnect pull-downs from the host side; there a control bits described in MAX3421 programming guide. You can try to send “Reset” to device, look at Usb::Task() state machine to see how this can be done. The proper way would be just to restart the state machine from the very beginning.

      Oleg.

  • Camille

    Thanks for the documentation email Oleg…many hours later I try pulldown resistor way on my EOS and nothing!
    When the EOS no responding even though you make a hard reset switch on arduino board the eos still no responding
    if you remove Usb cable canon eos reset(??)without reset board, and all is OK
    I think that initialisation and tasks don’t be able to kill that sort of bugging
    I test that with no result. When EOS no responding I send HOSTMODEResetDevice()
    It’s well reset task:
    USB_DETACHED_SUBSTATE_INITIALIZE
    USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE
    USB_ATTACHED_SUBSTATE_SETTLE (mode=C1)
    USB_ATTACHED_SUBSTATE_RESET_DEVICE(mode=C9)
    USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE
    USB_ATTACHED_SUBSTATE_WAIT_SOF
    USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE
    USB_STATE_ADDRESSING
    USB_STATE_CONFIGURING
    USB_STATE_RUNNING
    And failed EOS still Bugging!!!!!!!!!

    When the EOS no responding I call HOSTMODEResetDevice
    //I had this function
    void MAX3421E::HOSTMODEResetDevice(void)
    {
    //b7DPPULLDN=0//Clear PULLDN
    //b6 DMPULLDN=0//Clear PULLDN
    regWr( rMODE, bmSEPIRQ|bmHOST );
    delay( 2000 );
    }

    //I had that in busprobe:
    void MAX3421E::busprobe( void )
    {
    byte tmpbyte = regRd( rMODE );//MENIER
    if ( !(tmpbyte&bmDPPULLDN)||!(tmpbyte&bmDMPULLDN) )
    {
    #ifdef __TRACE_MAX3421E
    Serial.println( “SoftwareDisconectDevice reconnect” );
    #endif // __TRACEMAX3421E
    regWr( rMODE, bmDPPULLDN|bmDMPULLDN|bmSEPIRQ|bmHOST);
    vbusState = SE0;//disconnect mode
    (………..)

    //I had that in getVbusState:
    byte MAX3421E::getVbusState( void )
    {
    busprobe();//MENIER
    return( vbusState );
    }

  • Camille,

    I will try to replicate it on my cameras and let you know. If I remember correctly, you have 1000D, correct?

    Oleg.

  • Camille

    Hello Oleg,
    I think there is no way to initialize the EOS when it’s bugging as is….
    in fact EOS detecte VBUS for initiate, I had (remove vbus5v strap) a IRF4905 to command Vbus State and all is ok!!! for a strong reset!
    (please Mr Oleg can you add one on your next shield version?)
    I have done a ascii mapping of your schield (correct?)
    What is the used of BPNT_0,BPNT_1?
    Thanks

    // MAPPING
    // ______________________________________
    // | NC | AREF
    // | CIRCUIT@HOME GND |<- GND
    // | USBHOSTSHIELD SCLK|<- 13 SCLK——————–PB05
    // | MISO||RESET MOSI||3V3 SS||5V INT||GND GPX||GND |
    // VIN ->|VIN RESET|<- 07 ————————PD07
    // | NC | 06 PWM———————PD06
    //PC0 14 A0 | NC __________ NC | 05 PWM———————PD05
    //PC1 15 A1 | NC | | NC | 04 ————————PD04
    //PC2 16 A2 | NC | | NC | 03 PWM———————PD03
    //PC3 17 A3 | NC | | NC | 02 ————————PD02
    //PC4 18 A4 | NC | USB | NC | 01 TX———————-PD01
    //PC5 19 A5 | NC | | NC | 00 RX———————-PD00
    // |______________| |____________|
    // |__________|

  • Camille,

    BPNT_0, BPNT_1 are breakpoints – you can set/reset it somewhere in the program and observe it with oscilloscope or logic analyzer.

    Disconnecting VBUS is a good idea – I was thinking about this myself but you made it first! I don’t think placing MOSFET permanently on the shield is a good idea but we can make it as a mod. Let me try your idea with my cameras and then I will write an article about it so other people can make this mod too. BTW, what made you use such a big MOSFET for this mod?

    Oleg.

  • Camille

    I used PMOSFET IRF4905 for one reason:
    It’s the only PMOSFET i have got in my house(good reason is’nt it?)
    It’s run very well and prevent any bug
    If i well understand BPNT_0, BPNT_1 can be remove from the code and they don’t be connected to the shield?

    //……………………….MAPPING…………………………………………
    //…………..______________________________________
    //………….|……………………………..NC.|…AREF
    //………….|………..CIRCUIT@HOME………..GND.|<-..GND
    //………….|………..USBHOSTSHIELD……….SCLK|<-..13.SCLK——————–PB05
    //………….|…………………………….MISO||RESET………………………..MOSI||3V3……………………………SS||5V……………………………INT||GND…………………………..GPX||GND……………………………..|….
    //……VIN..->|VIN…………………………RESET|<-..07.————————PD07
    //………….|……………………………..NC.|….06.PWM———————PD06
    //PC0..14..A0..|.NC…………__________……….NC.|….05.PWM———————PD05
    //PC1..15..A1..|.NC………..|……….|………NC.|….04.————————PD04
    //PC2..16..A2..|.NC………..|……….|………NC.|….03.PWM———————PD03
    //PC3..17..A3..|.NC………..|……….|………NC.|….02.————————PD02
    //PC4..18..A4..|.NC………..|…USB….|………NC.|….01.TX———————-PD01
    //PC5..19..A5..|.NC………..|……….|………NC.|….00.RX———————-PD00
    //………….|______________|……….|____________|….
    //……………………….|__________|……………..

  • BPNTx shall be commented out everywhere. Let me know if you see it anywhere in the code (#defines don’t count ).

  • ilukester

    Hey oleg,
    I tried out that sample code that you posted and when I go and compile it I get this error.
    PTPDevInfo works perfectly.

    error: no matching function for call to ‘CanonEOS::CanonEOS(int, int, int, int, int, void (*)())’C:\Users\*****\********\arduino-0018\libraries\Arduino_Camera_Control/canoneos.h:131: note: candidates are: CanonEOS::CanonEOS(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, PTPStateHandlers*)

    C:\Users\*****\********\arduino-0018\libraries\Arduino_Camera_Control/canoneos.h:95: note: CanonEOS::CanonEOS(const CanonEOS&)

    In function ‘void ptpmain()’:

    Thanks

  • ilukester

    Thanx for that. So I have the 550D(aka T2i) and I have been playing with some of the “commands”. I cannot use the bulb function. Eos.StartBulb() gives me
    Transaction: Response recieve error: 0x2019
    Transaction: Response recieve error: 0x2005

    Then Eos.StopBulb() gives me basically the same error. I am going to guess that it is Camera specific

    Transaction: Response recieve error: 0x2005
    Transaction: Response recieve error: 0x2019

    • Bulb works on XSi, which is quite similar to T2i. Have you tried this command in “Manual” or some other mode?

      • ilukester

        Yeah I tried it in Manual mode. I even rolled the shutter speed to BULB… Also tried it in the other Modes like Av,Tv, and full auto and such.

        • I sent working Bulb sketch to e-mail address you left with the comment – let me know if this address is wrong and you’d like me to use another one.

  • Camille

    I test the new EOSEventLab.pde on my EOS 1000D
    I have the same problem it can’t read the END packet check, I have tested with gphoto2 and it’s run well…
    I going to be creazy so near of the result….

    08 00 00 00 00 00 00 00 Transaction: Response recieve error.: 0x0004
    EOSEventCheck error:: 0x2002
    Transaction: Command block send error: 0x0004

    • Camille,

      Some cameras timeout while Arduino parses this large initial packet. The fix is to close session after packet is received. Basically, the sequence is this: open session, get initial packet, parse it, close session, open session, skip the first packet, start parsing subsequent packets.

      Oleg.

      • Camille

        I change EventCheck(PTPReadParser *parser) adding close open() session():

        uint16_t CanonEOS::EventCheck(PTPReadParser *parser)
        {
        uint16_t ptp_error = PTP_RC_GeneralError;
        OperFlags flags = { 0, 0, 0, 1, 1, 0 };

        if ( (ptp_error = Transaction(0x9116, &flags, NULL, parser)) != PTP_RC_OK)
        Message(PSTR(“EOSEventCheck error:”), ptp_error);
        CloseSession(); //add
        OpenSession(); //add
        return ptp_error;
        }
        RESULT:
        14 00 00 00 8A C1 00 00 B7 D1 00 00 01 00 00 00 00 00 00 00
        08 00 00 00 00 00 00 00 Transaction: Response recieve error.: 0x0004
        EOSEventCheck error:: 0x2002
        CloseSession
        Transaction: Command block send error: 0x0004
        OpenSession
        Transaction: Command block send error: 0x0004

  • Camille

    I can’t run the shield on a MEGADUINO is there an issue?

    • Check pin assignment. I’ve never heard about MEGADUINO, but I know for a fact that in order for the shield to work with Arduino Mega some pins need to be re-routed.

  • Jeff

    Where can I find the exampl sketch that works with th 5d mII to set live view with the diplay on the cameras lcd. Thanks

    • Jeff

      I finally figured it out. You need to set the LiveView device to 2 (PC) to get the mirror to pop up. If you then set the LiveView device to 1 (TFT) the lcd turns back on.

  • serankko

    Can somebody please explain me how this works:

    uint16_t SetProperty(uint16_t prop, uint32_t val)

    and give me a real example

    Thanks a lot

  • serankko

    Never mind… I’m not as dumb as I thought… I know how it works…

  • Mark

    Hi,

    I tried to compile the example that shoots the camera once every 5 seconds and I get this error:
    …/ptp.h:130: error: ‘Max’ was not declared in this scope

    I am able to compile and run ‘boardtest’ and ‘devinfo’ with no problem.

    Thanks,

    Mark

  • Mark

    OK –

    I found the problem. The first character of each include file is lower case in the example and they need to be upper case per the lines below:

    #include
    #include

    – A little thing but one of those typical c-coding situations where the errors cascade and the user has no clue as to what actually happened.

    The code now runs and I plugged in my Canon “xsi” (450D) and it works perfectly. Now on to trying other commands and other cameras. . .

    Thanks to felis, Oleg and others who made this possible – we are standing on the shoulders of giants!

    When I get some time to continue playing with this, I’ll upload devinfo for additional cameras.

    Thanks,

    Mark

    • Mark,

      Thanks for letting me know – I made corrections on Canon EOS Library Description page; the example should compile fine.

      BTW, felis and Oleg are the same person (yours truly). I’m just running the shop, Alex is the one deserving the credit – he is doing the hard work reverse engineering. I’ll let him know :-).

  • Mark

    Oops –

    The corrected code didn’t show up due to unintended html translation so here is is, again:

    Spi.h
    Max3421e.h

    These need to start with capital letters but are shown lower case in the example.

    Mark

  • Jeff

    I seem to be getting a lot of timeouts (0xff) from USB::dispatchPkt. The easiest way for me to replicate is to run the EventLab example. At some point I get a timeout error. Any ideas as to what might be causing this or how to fix it. Thanks

    • Jeff

      Found my problem. Noise. The test environment I was using had the Arduino on a bread board and the host shield on the breadboard. I had wire wrapped the necessary connecting lines. The wire wrap lengths were about two inches. When I went back and connected the two “directly” the problem went away.

  • I’ve often dreamed of PTP control with Arduino, and here it is; complete! As a heavy user of Canon Powershot cameras, I suspect this will open up a new range of possibilities for me and for the book scanning community at diybookscanner.org.

    Thank you for creating this product and especially for documenting it so heavily. I bought one, as well as an Arduino Pro Mini and programming cable from SparkFun.

  • Ryan

    A lot of the functions you have listed as “Vendor Defined” and don’t have any names available for – esp for the 7D etc are listed on the magic lantern wiki:

    http://magiclantern.wikia.com/wiki/PTP

    i.e.

    DS_RESETMIRRORLOCKUPSTATE = 0x9130;
    DS_POPUPBUILTINLFLASH = 0x9131;
    DS_ENDGETPARTIALOBJECTEX = 0x9132;
    DS_MOVIESELECTSWON = 0x9133;
    DS_MOVIESELECTSWOFF = 0x9134;

  • Gisela Noci

    Hi Oleg
    I am wanting to control a Cannon PowerShot G7. Will your Powershot code manage this camera, and if so, is there any chance I could get a preliminary version from you so that I can start to understand it?
    Thanks in anticipation
    Gisela Noci

  • Daniel

    Someone did it already commercially.
    View this thread – professional focus remote control via Arduino PRO:
    http://www.cinema5d.com/viewtopic.php?f=17&t=19746&st=0&sk=t&sd=a

    That thing looks fantastic.

  • Dmitry

    Hi Oleg!

    Thanks for your blogs. It is really helpful.
    I’d like to implement usb-hub support for usb host shield. Could you please give me a link to the usb protocol documentstion?
    I’ve googled it but everything I could find is Usb in NutShell book here.

    Your code contains a number of calls of Transaction method (witch is, as you desribe here is a piece of comnunication information in ptp). Where can I find some documentation of how and why is it working?

    And, unfortunatelly, trying to get usb hub device info with this code sample, my usb hub does not want to responce on Ptp->OpenSession command. The result code is “Transaction: Command block send error: 0x000D
    “.

    Thanks, Dmitry.

  • jackel

    Hi there,

    i try connect my canon eos 30D with the usb host shield via STK600 (ATMEGA 2560). After some days of programming i got usb to work, this means that i reach the level “USB_RUNNING”. After that the code tries to open a session (PTP), but this get’s me a time out. I used the Debugger and i found out the position in the code where its happens :

    byte USB::dispatchPkt on line :

    rcode = 0xff;
    while( millis() < timeout ) { //wait for transfer completion
    if( rcode != 0x00 ) { //exit if timeout
    return( rcode );
    }

    The function is called twice from :
    rcode = Usb.outTransfer(devAddress, epDataOut, len, (char*)data);
    The first time in the loop everything is fine, in the second the time out happens.

    I tried to modified the time, but nothing happends (it only takes longer to get the timeout)

    Maybe you have an idea what i can try.

    Thank you!!
    Cheers
    Micha

  • jackel

    Hey, got it work. Something from in the timing. But now i have an other problem (ok, not really a problem). I want to download a Thumb Image, but i don’t know how. I tried

    HexDump hex;
    Eos.GetThumb(0,&hex);

    I don’t know what to set in the first parameter (uint32_t handle).

    The Parse Method is called, but i get an error :
    00:0C 00 00 00 02 00 0A 10 04 00 00 00 Transaction: Response recieve error: 0x
    Maybe you can help me again ?
    Cheers
    Micha

  • Renee

    I’m having the same issue that someone above had with the 550D not working with the Bulb sketch. It seems like most of the sketches aren’t working besides the simple capture one.

    Everything seems to compile ok but when I run my camera shows Busy for a sec and the terminal says a session is open but nothing follows.

    I think the problem for the Bulb sketch is that it’s calling for Operation(0x9125) in canoneos.cpp

    According to the ptp dump for the 550D there is no 9125 Operation supported. However I know bulb mode can be activated with the EOS utility so it must be in there. Is it one of the Vendor assigned codes?

    Unfortunately my programming skills are only good enough for me to sort out problems but I’m no good at getting anything to work after that 😀

  • Nolan

    Using 7D can’t get PTPDevInfo.pde to run without this error. Help me please.

    ‘MAX3421E’ does not name a type

    In file included from canoneos.h:21,
    from canoneos.cpp:17:
    ptp.h:24:22: error: Max3421e.h: No such file or directory
    ptp.h:25:17: error: Usb.h: No such file or directory
    In file included from canoneos.h:21,
    from canoneos.cpp:17:
    ptp.h:76: error: ‘MAX3421E’ does not name a type
    ptp.h:77: error: ‘USB’ does not name a type
    ptp.h:85: error: ‘EP_RECORD’ does not name a type
    ptp.h:115: error: ISO C++ forbids declaration of ‘MAX3421E’ with no type
    ptp.h:115: error: expected ‘;’ before ‘*’ token
    ptp.h:116: error: ISO C++ forbids declaration of ‘USB’ with no type
    ptp.h:116: error: expected ‘;’ before ‘*’ token
    ptp.h: In member function ‘void PTP::Setup()’:
    ptp.h:123: error: ‘Max’ was not declared in this scope

  • Renee

    Not sure about your OS, on my Mac I have it installed under HomeDirectory/Documents/Arduino/libraries/USB_Host_library

    • Nolan

      My OS is mac and I did what you said renee. But, I still get this error:

      expected class-name ‘{‘ token

      In file included from ptp.h:25,
      from canoneos.h:21,
      from canoneos.cpp:17:
      Usb.h:86: error: expected class-name before ‘{‘ token
      In file included from canoneos.h:21,
      from canoneos.cpp:17:
      ptp.h:76: error: ‘MAX3421E’ does not name a type
      ptp.h:115: error: ISO C++ forbids declaration of ‘MAX3421E’ with no type
      ptp.h:115: error: expected ‘;’ before ‘*’ token
      ptp.h: In member function ‘void PTP::Setup()’:
      ptp.h:123: error: ‘Max’ was not declared in this scope

      thanks for the help

      • Looks like compiler can’t access Max3421e.cpp module. I double-checked the code on github, it compiles clean. You may want to re-download libraries from github and re-install them.

        • Nolan

          @oleg – I am still new to this maybe I am doing this wrong, re-downloaded and still getting errors. To run the PTPDevInfo.pde i only need two libraries(USB_Host_Shield and Arduino_Camera_Control) correct? Also, I’m unsure if i am putting those libraries in the correct spot on my mac. Currently they are in HomeDirectory/Documents/Arduino/libraries/

          and i am running the PTPDevInfo.pde sketch from within its place in the Arduino_Camera_Control library

          @karsten – I only have one ptp.h file located in the Arduino_Camera_Control lib.

          • karsten

            Hello Nolan, if your arduino ide resides in /Applications/Arduino.app, then Olegs libs have to reside in /Applications/Arduino.app/Contents/Resources/Java/libraries/ afterwards (and a restart of the arduino app) they should show up in the menu “Sketch -> Import Library”

            To copy them to the correct place you should use a terminal or Finder and “Show Package Contents” (right mouse button)

            hope you can get this up an running now!!!

          • Nolan

            @Karsten – I placed oleg’s libraries where you said and I get a new error:

            In file included from /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:6,
            from /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/../ptp/ptp.h:25,
            from devinfoparser.h:8,
            from devinfoparser.cpp:1:
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:102: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:103: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:105: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:106: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:107: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:108: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:112: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:113: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:114: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:115: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:121: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:122: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:124: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:125: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:126: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:127: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:128: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:134: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:135: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:136: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:137: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:138: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:139: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:140: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:141: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:142: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:148: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:149: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:150: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:151: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:153: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:158: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:159: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:161: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:162: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/ch9.h:163: error: ‘byte’ does not name a type
            In file included from /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/../ptp/ptp.h:25,
            from devinfoparser.h:8,
            from devinfoparser.cpp:1:
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:48: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:50: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:51: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:52: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:55: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:59: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:60: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:71: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:72: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:74: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:75: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:76: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:82: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:87: error: expected class-name before ‘{‘ token
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:100: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:101: error: ‘byte’ has not been declared
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:102: error: expected ‘;’ before ‘(‘ token
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:103: error: ‘byte’ has not been declared
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:104: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:106: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:107: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:108: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:109: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:110: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:112: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:113: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:114: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:115: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:116: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:117: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:118: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:120: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:121: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:122: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:123: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:124: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:131: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:135: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:139: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:143: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:147: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:151: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:154: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:158: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:161: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:164: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:168: error: ‘byte’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/Usb.h:171: error: ‘byte’ does not name a type
            In file included from devinfoparser.h:8,
            from devinfoparser.cpp:1:
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/../ptp/ptp.h:77: error: ‘MAX3421E’ does not name a type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/../ptp/ptp.h:116: error: ISO C++ forbids declaration of ‘MAX3421E’ with no type
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/../ptp/ptp.h:116: error: expected ‘;’ before ‘*’ token
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/../ptp/ptp.h: In member function ‘void PTP::Setup()’:
            /Applications/Arduino.app/Contents/Resources/Java/libraries/USB_Host_Shield/../ptp/ptp.h:124: error: ‘Max’ was not declared in this scope

          • Nolan

            @Karsten & Oleg – I finally got it to compile cleanly, thanks for all your help. You can ignore the above error comment. Also, you may have to include the time library from the arduino site for a clean complile.

  • karsten

    I can confirm a clean compile under Arduino 0022 with MacOS 10.6.6.
    Please make sure that you don’t have multiple ptp.h files, i.e. in other arduino projects. My first compilation attempt was broken this way.
    @oleg is my usb shield on its way?

  • karsten

    @nolan
    have you been able to compile the basic examples that come with the arduino ide? Your error messages seem to be really strange, I’d try to delete an reinstall the whole arduino package.

  • nolan

    @Karsten – I got it to compile cleanly(all examples from olegs code), thanks for all your help. It was a simple mistake with directories on my end. Though, I did have to install the “time” library from the arduino website. If i run into anymore problems i’ll be sure to post. Thanks again.

    • karsten

      you’re welcome, no problem at all … btw. the need of the time library was mentioned in the eos blog-post …