Sunday, September 05, 2010

GAGA-1: Camera Hacking

I decided to spend the weekend doing some work on GAGA-1 and got the camera in fairly good shape.

I'm using a Canon A560 (two, in fact, that I bought off eBay for about £35 each). There are lots of reasons to use this camera: it's lightweight (very important since I need to minimize the payload weight), it's been flown on high-altitude balloon projects before (e.g. by Robert Harrison), it was recommended to me by the CU Spaceflight guys and it's hackable with CHDK.

CHDK is an amazing project that lets you run new firmware on a wide range of Canon cameras that enable full control of the camera. For my purposes I'm using the uBASIC interpreter that's part of CHDK to script automatic photo taking (code below). First, a few notes on getting CHDK loaded on my A560 from a Mac (you should start by reading the Mac FAQ.

1. Get the correct build for the camera from here. I'm using the 'full' version.

2. Unzip the file from the command-line and not from Archive Utility otherwise Mac OS X adds Extended Attributes (specifically, com.apple.quarantine) that mess everything up. I just did unzip a560-100a-0.9.9-933-full.zip.

3. Use SDMInst to format and upload to the SD Card. You only need to do this once, after that you can mess around with adding scripts in CHDK/SCRIPTS on the SD card directly using the normal Mac file system.

4. Set write protect/lock on the SD card. Put card in camera. You will see a special CHDK splash screen indicating that you are running the firmware from the card and not from the camera. Click the 'direct print' button on the camera and you enter ALT mode.

5. In ALT mode you have access to all of CHDK's functions. Here's what happens when you hit MENU on ALT mode:


Since I'm working with a custom script (called GAGA-1.BAS) I load it from the Scripting parameters menu item. Once loaded the parameters for that script are visible in the menu:


My script has three parameters: a start-up delay that gives me time to do a quick visual check of the camera and insert it into the box before it starts operating, the number of pictures to take in a burst and the delay between bursts. The camera will sleep for five minutes, wake up and take three pictures and then go back to sleeping for another five minutes.

Once back on the main screen the GAGA Camera Control script is mentioned at the bottom of the screen. This indicates that simply hitting the shutter button will start the script.


The 'opt' value top-right is the temperature of the optical parts of the camera. I expect this will drop when GAGA-1 hits the stratosphere. It's possible to get and log these values so I may add a log file to the SD card recording the temperature drop.

And here's what that looks like: start-up of the script, self-check and taking a few shots:



I ran a full test with new Duracell batteries (the ordinary gold-topped ones) today and the camera took 61 photographs at maximum resolution, running continuously for 103 minutes. This is ok, but not good enough. Most balloon flights will be in the 120 to 180 minute range so I need extend the time.

One big problem was that I had the display shut off set at three minutes, with a five minute wake up that meant the LCD was on 3/5 of the time wasting a lot of battery. The next test will be done with the minimum time (20 seconds). The next test also needs to use the right batteries: Energizer Lithium Ultimate.

I fully expect to get to 180 minutes with five minute wake-ups taking 10 pictures at a time with that combination. But, as with everything else in GAGA-1, it'll need testing.

Here's the script itself. The actual photographing code is a tiny loop towards the end which uses the CHDK shoot command to take a picture. Everything else is self-test using the property cases to ensure that I don't mess up. The idea is that the camera is manually configured (and in Manual Mode). The script checks that there's nothing silly going on (like the flash being enabled).

rem GAGA Camera Control Code
rem
rem Copyright (c) 2010 John Graham-Cumming
rem
rem Performs the following steps:
rem
rem Performs a self-check
rem Waits for a predetermined amount of time
rem Enters loop doing the following:
rem Take a number of photographs in succession
rem Wait a predetermined amount of time

@title GAGA Camera Control

@param s Start-up delay (secs)
@default s 10

@param c Pictures per iteration
@default c 10

@param i Iteration delay (secs)
@default i 300

rem The sleep command uses microseconds do the s and i need
rem to be converted

s=s*1000
i=i*1000

print "GAGA Camera Control"
sleep s

rem Now enter a self-check of the manual mode settings

print "Self-check started"

p=get_prop 49
if p <> -32764 then
print "ERROR: Not in manual mode"
goto "fail"
endif

p=get_prop 5
if p <> 0 then
print "ERROR: AF Assist Beam should be Off"
goto "fail"
endif

p=get_prop 6
if p <> 0 then
print "ERROR: Focus Mode should be Normal"
goto "fail"
endif

p=get_prop 8
if p <> 0 then
print "ERROR: AiAF Mode should be On"
goto "fail"
endif

p=get_prop 21
if p <> 0 then
print "ERROR: Auto Rotate should be Off"
goto "fail"
endif

p=get_prop 29
if p <> 0 then
print "ERROR: Bracket Mode should be None"
goto "fail"
endif

p=get_prop 57
if p <> 0 then
print "ERROR: Picture Mode should be Superfine"
goto "fail"
endif

p=get_prop 66
if p <> 0 then
print "ERROR: Date Stamp should be Off"
goto "fail"
endif

p=get_prop 95
if p <> 0 then
print "ERROR: Digital Zoom should be None"
goto "fail"
endif

p=get_prop 102
if p <> 0 then
print "ERROR: Drive Mode should be Single"
goto "fail"
endif

p=get_prop 133
if p <> 0 then
print "ERROR: Manual Focus Mode should be Off"
goto "fail"
endif

p=get_prop 143
if p <> 2 then
print "ERROR: Flash Mode should be Off"
goto "fail"
endif

p=get_prop 149
if p <> 100 then
print "ERROR: ISO Mode should be 100"
goto "fail"
endif

p=get_prop 218
if p <> 0 then
print "ERROR: Picture Size should be L"
goto "fail"
endif

p=get_prop 268
if p <> 0 then
print "ERROR: White Balance Mode should be Auto"
goto "fail"
endif

v=get_vbatt
if v < 3000 then
print "ERROR: Batteries below 3V"
goto "fail"
endif

print "Self-check complete"
print "Starting picture capture"

n=0

:loop
for a=1 to c
shoot
n=n+1
print "Picture", n, "taken"
next a
sleep i

goto "loop"

:fail
print "GAGA Camera Failed"
end

:done
print "GAGA Camera Done"
end


Remaining TODOs:

0. Buy larger SD card
1. Rerun Duracell battery test with faster LCD cut off time
2. Run test with Energizer Lithium Ultimate batteries
3. Run freeze test at -18C
4. Make self-check happen before initial delay
5. Figure out whether the display shut off and auto shut down can be self-checked
6. Can we check that RAW mode is off?
7. Is it possible to check that there's space on the SD card? Check that the date/time seems sensible?

UPDATE. Ran test using Energizer Lithium Ultimate batteries. What a difference some lithium makes! Instead of 103m the test ran for 451 minutes (over 7.5 hours). This was taking 3 pictures every 5 minutes. The camera took a total of 264 shots before I stopped it. At that point the battery was running low with the Canon indicator flashing.

The display shut off time was set at 20 seconds and I disabled RAW photo-capture.

No comments: