supplierdeeply

Python Script Calling CHDKPTP CLI Commands on Raspberry Pi

  • 19 Replies
  • 5179 Views
*

Offline JvdP

  • ***
  • 174
Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« on: 19 / July / 2015, 12:42:36 »
Advertisements
Edit: we've made a Python script that seems to work quite well. Still working on it though. See attachment.

_____________________________________________________________


I'm succesfully running a relay from my Raspberry Pi, turning on my CHDK hacked Canon Ixus 240 HS. I have also installed CHDKPTP and it works great communicating to the camera.

Now I want to make a python script that will run a timelapse, checking if the camera is still alive every picture and if not, turn on the camera. Here's an example of the script:

Check if the camera is on by trying to connect to it
Code: [Select]
return_code = call(["chdkptp", "-c"])
print(return_code)

Then an if statement to figure out what to do
Code: [Select]
if return_code == "ERROR: no matching devices found":
#Turn on camera
#CHDKPTP Connect to cam, rec mode, rs
#Turb off camera

else:
#CHDKPTP Connect to cam, rec mode, rs

The problem is that the Python script doesn't see the CHDKPTP response that it would usually show in the command line.

I'm aware that this is perhaps more of a Python question, but perhaps there are people here who've run into the same problem so I don't have to reinvent the wheel.

Is there a good way to script this? How can I make the Python script receive the CHDKPTP communication? Or should I approach this problem differently?
« Last Edit: 10 / August / 2015, 17:28:02 by JvdP »

*

Offline reyalp

  • ******
  • 11496
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #1 on: 19 / July / 2015, 14:34:53 »
You might consider using jbaiter's python wrapper instead of shelling out https://github.com/jbaiter/chdkptp.py

My knowledge of python is very limited, but does 'call' return the output, or the program return code? If it's this function https://docs.python.org/2/library/subprocess.html?highlight=call#subprocess.call then it's the latter, and you would need to capture the output somewhere. A simple way to do this would be to send the output file and check it. The "ERROR: no matching devices found" message will go to stderr. Note to use normal shell redirection, you'd need the "shell" option to subprocess.call. Using the file handle options would be more "correct" but probably take more coding.

edit:
It would be nice if chdkptp set the exit code, but it currently doesn't. You could use some chdkptp Lua to do this:
Code: [Select]
chdkptp -c -e"exec if not con:is_connected() then os.exit(1) end"
This will make the return code 1 if the camera is not connected, otherwise the default 0.

As a general rule, invoking a new copy of chdkptp adds some overhead. An alternative would be to open chdkptp in interactive mode and feed it commands through stdin. This again would take more sophisticated coding though.

A final option would be to just write your code in Lua and run it in chdkptp, although depending specific application this may not be convenient.

« Last Edit: 19 / July / 2015, 15:06:52 by reyalp »
Don't forget what the H stands for.

*

Offline JvdP

  • ***
  • 174
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #2 on: 20 / July / 2015, 17:58:15 »
You might consider using jbaiter's python wrapper instead of shelling out https://github.com/jbaiter/chdkptp.py
You know what, that looks like a great script, but I'm already in way over my head with this. I tried installing this but I failed miserably. I'm just not familier enough with unix let alone Python to understand this. I'm just skipping by with copy paste, google and a lot of trial & error. I wish I could take the time to learn all of this properly :(

Quote
You could use some chdkptp Lua to do this:
Code: [Select]
chdkptp -c -e"exec if not con:is_connected() then os.exit(1) end"
This will make the return code 1 if the camera is not connected, otherwise the default 0.
Your example works pretty good, although I'd run it the other way around, because it will make sure that we detect the camera is connected. Anything else (return_code=0) and I will make the script reboot the camera.

Code: [Select]
chdkptp -c -e"exec if con:is_connected() then os.exit(1) end"

Quote
A final option would be to just write your code in Lua and run it in chdkptp, although depending specific application this may not be convenient.
I don't think this would give me control over the raspberry GPIO (relay) would it?



I'm trying to remoteshoot with focus on infinity by:

Code: [Select]
call("chdkptp -c -e'rec' -e'exec set_focus(50000)'", shell=True)
Now, for some reason this doesn't work? I get a ERROR: call failed:[string "set_focus(50000)"]:1: attempt to call global 'set_focus' (a nil value). The same happens directly in chdkptp. However, in chdkptp, sending lua to the camera with the same command works...

I've also tried rsint and I can succesfully set shutterspeed, but not the subject distance (sd). It simply won't focus. Do you know what's going on here?
« Last Edit: 20 / July / 2015, 17:59:47 by JvdP »

*

Offline reyalp

  • ******
  • 11496
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #3 on: 20 / July / 2015, 22:12:39 »
I don't think this would give me control over the raspberry GPIO (relay) would it?
If you have a command line program that gives you sufficient control over the GPIO, you could execute it with Lua os.execute: http://www.lua.org/manual/5.2/manual.html#pdf-os.execute (similar to what you are doing with chdkptp from python)

Just for completeness, there is also at least one Lua GPIO control module https://github.com/Tieske/rpi-gpio/tree/master/lua but I have no experience with it and getting it to work inside chdkptp may be more than you want to get into.

Quote
I'm trying to remoteshoot with focus on infinity by:

Code: [Select]
call("chdkptp -c -e'rec' -e'exec set_focus(50000)'", shell=True)
Now, for some reason this doesn't work? I get a ERROR: call failed:[string "set_focus(50000)"]:1: attempt to call global 'set_focus' (a nil value). The same happens directly in chdkptp. However, in chdkptp, sending lua to the camera with the same command works...
exec (AKA !) is Lua that executes inside chdkptp, not on the camera. To execute camera side lua and wait for it to complete, you should use luar (AKA =)

Note that for set_focus() to stay in effect for more than one shot, you would need to use set_mf() or set_aflock() first.

If you use one of these and then call set_focus(), you should see the camera focus distances update immediately on the camera screen. If the camera is in AF mode, the value is just stored for the next half shoot.
Quote
I've also tried rsint and I can succesfully set shutterspeed, but not the subject distance (sd). It simply won't focus. Do you know what's going on here?
rs and rsint should support setting subject distance with -sd=...

Note that by default -sd takes a distances in meters, unlike set_focus which uses mm.

Continuous AF or Servo AF in the Canon options may prevent sd override from working. Using set_mf() or set_aflock() may avoid this.

If using set_focus() works but -sd doesn't, let me know. It could be a bug in chdkptp.
Don't forget what the H stands for.


*

Offline JvdP

  • ***
  • 174
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #4 on: 21 / July / 2015, 16:49:39 »
If you have a command line program that gives you sufficient control over the GPIO, you could execute it with Lua os.execute: http://www.lua.org/manual/5.2/manual.html#pdf-os.execute (similar to what you are doing with chdkptp from python)

Just for completeness, there is also at least one Lua GPIO control module https://github.com/Tieske/rpi-gpio/tree/master/lua but I have no experience with it and getting it to work inside chdkptp may be more than you want to get into.
I will look into this. Thanks! :)


Quote
exec (AKA !) is Lua that executes inside chdkptp, not on the camera. To execute camera side lua and wait for it to complete, you should use luar (AKA =)
Ah, good point. I didn't know that I could use luar in a direct command line command. It didn't show up in the help (chdkptp help in bash).

Quote
Note that for set_focus() to stay in effect for more than one shot, you would need to use set_mf() or set_aflock() first.

If you use one of these and then call set_focus(), you should see the camera focus distances update immediately on the camera screen. If the camera is in AF mode, the value is just stored for the next half shoot.
I've been playing around a little and I definately have some bugs going on. Here's a few things I've tried:


1. Using set_mf(1) without set_focus()
Code: [Select]
con 10> luar set_mf(1)
ERROR: :80: attempt to call global 'set_mf' (a nil value)
user code: 1
con 11 > rs
con 12 > rs
Returning user code 1 should however indicate that the camera supports it? Right? Well, both con 11 and 12 are autofocussed.


2. Using set_mf(1) before set_focus()
Code: [Select]
con 1> luar set_mf(1)
ERROR: :80: attempt to call global 'set_mf' (a nil value)
user code: 1

con 2> luar set_focus(1)
con 3> luar set_focus(65490)
con 4> rs
con 5> rs
con 4 is set to focus, con 5 is autofocussed.

3. Using set_aflock(1) before set_focus()
Code: [Select]
con 1> luar set_aflock(1)
con 2> luar set_focus(1)
con 3> luar set_focus(65490)
con 4> rs
WARNING: capture_get_data error I/O error
WARNING: error waiting for shot script nil
ERROR: /home/pi/chdkptp/lua/cli.lua:2274: attempt to concatenate local 'err' (a table value)
stack traceback:
        [C]: in function 'xpcall'
        /home/pi/chdkptp/lua/cli.lua:244: in function 'execute'
        /home/pi/chdkptp/lua/cli.lua:351: in function </home/pi/chdkptp/lua/cli.lua:342>
        (...tail calls...)
        /home/pi/chdkptp/lua/main.lua:281: in main chunk
        [C]: in function 'require'
        [string "require('main')"]:1: in main chunk
This one seems promising as the camera seems to accept the set_aflock(1), then set_focus but then crashes during rs.


4. Using set_aflock(1) after set_focus()
Code: [Select]
___> c
connected: Canon IXUS 240 HS, max packet size 512
con> rec
con 1> luar set_focus(65490)
con 2> rs
con 5> luar set_aflock(1)
con 6> rs
con2 is at the set focus, con6 is autofocussed.


It's slightly off-topic but can't my camera do manual focus? When I hit the "Manual Focus" button on the camera chdk display it comes on, but the camera still autofocusses at half shoot.

If I can't get this to work I suppose I could always just send the set_focus() for every shot, because that seems to work well.

I'm pretty sure this is also causing the rsint bugs.
« Last Edit: 22 / July / 2015, 08:03:26 by JvdP »

*

Offline reyalp

  • ******
  • 11496
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #5 on: 21 / July / 2015, 21:26:52 »
Ah, good point. I didn't know that I could use luar in a direct command line command. It didn't show up in the help (chdkptp help in bash).
The -e command line option lets you execute any of the commands you could enter at the > prompt

Quote
1. Using set_mf(1) without set_focus()
Code: [Select]
con 10> luar set_mf(1)
ERROR: :80: attempt to call global 'set_mf' (a nil value)
user code: 1
What version of CHDK are you using?  The attempt to call a nil value error means it doesn't exist in your chdk build.

set_mf was added for 1.3, so it's been in the stable releases for a long time.
Quote
Returning user code 1 should however indicate that the camera supports it
No, though I don't think I've ever documented how the camera error messages in chdkptp work, so a small digression:

The "ERROR: :80" is a Lua error message, telling you the error happened on line 80 of the script.

Since you only sent one line (set_mf(1)), so how could there be a line 80? chdkptp actually sends a some library code with each command. The "user code: 1" message means the error happened on line one of your code, as it should be, since you only sent one!



Quote
3. Using set_aflock(1) before set_focus()
Code: [Select]
con 1> luar af_lock(1)
ERROR: :80: attempt to call global 'af_lock' (a nil value)
user code: 1
The correct function is set_aflock. You can use http://chdk.wikia.com/wiki/CHDK_Scripting_Cross_Reference_Page to find function names.


Quote
Code: [Select]
con 1> luar set_aflock(1)
con 2> luar set_focus(1)
con 3> luar set_focus(65490)
con 4> rs
WARNING: capture_get_data error I/O error
...
This means the camera crashed. The following messages are due to a bug in chdkptp error handling which is fixed in svn.

According to the settings in platform_camera.h aflock should work, but it's possible canon firmware settings could interfere with it. A look through the porting thread http://chdk.setepontos.com/index.php?topic=6341 might tell you if there are known issues.

A romlog http://chdk.wikia.com/wiki/Debugging#Camera_crash_logs_.28romlog.29 might also shed light on the problem.

Quote
It's slightly off-topic but can't my camera do manual focus? When I hit the "Manual Focus" button on the camera chdk display it comes on, but the camera still autofocusses at half shoot.
I guess you mean the MF shortcut from the help display? The way CHDK overrides work (at least if you haven't used set_mf or set_aflock) CHDK waits for the camera to AF and then applies the override. If you set an sd override distance, subsequent shots should have the override applied even though the camera will appear to AF.
Don't forget what the H stands for.

*

Offline JvdP

  • ***
  • 174
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #6 on: 22 / July / 2015, 09:08:59 »
What version of CHDK are you using?  The attempt to call a nil value error means it doesn't exist in your chdk build.

set_mf was added for 1.3, so it's been in the stable releases for a long time.
1.3.0-3274

Quote
The correct function is set_aflock. You can use http://chdk.wikia.com/wiki/CHDK_Scripting_Cross_Reference_Page to find function names.
I'm sorry, this was a typo, I've removed this from my previous post. However, with the right spelling the camera crashes 100% of the time! I must have a bug in my port.

Quote
According to the settings in platform_camera.h aflock should work, but it's possible canon firmware settings could interfere with it.
Just for information, I have Servo AF "OFF" in Canon Menu.

Quote
A romlog http://chdk.wikia.com/wiki/Debugging#Camera_crash_logs_.28romlog.29 might also shed light on the problem.
I've posted a romlog in the porting thread with a description of the problem.

*

Offline reyalp

  • ******
  • 11496
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #7 on: 22 / July / 2015, 16:00:46 »
Quote
According to the settings in platform_camera.h aflock should work, but it's possible canon firmware settings could interfere with it.
Just for information, I have Servo AF "OFF" in Canon Menu.
Another question: Which camera(s) are you actually using? Your first post said ixus220, the chdkptp output quoted in replay #4 above says ixus240?

My comment above was for the IXUS 220

The comments in the IXUS 240 code suggest that SD overrides should work in af and with set_mf, but not with set_aflock.

edit:
Quote
1.3.0-3274
This is very old. The 1.3 release was r3809, so I would strongly suggest updating to the current version.
« Last Edit: 22 / July / 2015, 16:05:53 by reyalp »
Don't forget what the H stands for.


*

Offline JvdP

  • ***
  • 174
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #8 on: 06 / August / 2015, 12:44:18 »
Another question: Which camera(s) are you actually using? Your first post said ixus220, the chdkptp output quoted in replay #4 above says ixus240?

My comment above was for the IXUS 220

The comments in the IXUS 240 code suggest that SD overrides should work in af and with set_mf, but not with set_aflock.

edit:
Quote
1.3.0-3274
This is very old. The 1.3 release was r3809, so I would strongly suggest updating to the current version.
I'm sorry for the mishap, I was wrong when I said IXUS 220, I have 240 camera's. Also I've now updated to 1.4.

I will take this discussion over to other threads (porting thread for my camera and the thread for "Setting focus from scripts or menus"), since it seems a problem with mf with my specific camera.
« Last Edit: 06 / August / 2015, 16:49:19 by JvdP »

*

Offline JvdP

  • ***
  • 174
Re: Python Script Calling CHDKPTP CLI Commands on Raspberry Pi
« Reply #9 on: 09 / August / 2015, 16:50:42 »
So I've written a Python script with the help of a friend. I've attached it.

The script is still a little "wobbly" and we're ironing out the bugs. But one of them seems to be related to CHDKPTP?

Here's the command line:

Code: [Select]
[2015-08-09 20:45:19] Check if camera is On. camera_error state: False
-e'exec if not con:is_connected() then os.exit(1) end'
open_camera_dev_usb: ptp_opensession failed 0x2ff
open_camera_dev_usb:usb_ptp_device_reset(): Device or resource busy
usb_ptp_get_device_status(): Device or resource busy
open_camera_dev_usb: ptp_opensession 2 failed: 0x2ff
ERROR: connection failed

So what happens is that I check if the camera is on by sending the code that reyalp suggested. The camera is on but the communication to the USB seems to go wrong?

 

Related Topics