Skip to main content

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, that mess everything up. I just did unzip

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 Copyright (c) 2010 John Graham-Cumming
rem Performs the following steps:
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


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"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


for a=1 to c
print "Picture", n, "taken"
next a
sleep i

goto "loop"

print "GAGA Camera Failed"

print "GAGA Camera Done"

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.


Popular posts from this blog

Your last name contains invalid characters

My last name is "Graham-Cumming". But here's a typical form response when I enter it:

Does the web site have any idea how rude it is to claim that my last name contains invalid characters? Clearly not. What they actually meant is: our web site will not accept that hyphen in your last name. But do they say that? No, of course not. They decide to shove in my face the claim that there's something wrong with my name.

There's nothing wrong with my name, just as there's nothing wrong with someone whose first name is Jean-Marie, or someone whose last name is O'Reilly.

What is wrong is that way this is being handled. If the system can't cope with non-letters and spaces it needs to say that. How about the following error message:

Our system is unable to process last names that contain non-letters, please replace them with spaces.

Don't blame me for having a last name that your system doesn't like, whose fault is that? Saying "Your last name …

All the symmetrical watch faces (and code to generate them)

If you ever look at pictures of clocks and watches in advertising they are set to roughly 10:10 which is meant to be the most attractive (smiling!) position for the hands. They are actually set to 10:09.14 if the hands are truly symmetrical. CC BY 2.0image by Shinji
I wanted to know what all the possible symmetrical watch faces are and so I wrote some code using Processing. Here's the output (there's one watch face missing, 00:00 or 12:00, because it's very boring):

The key to writing this is to figure out the relationship between the hour and minute hands when the watch face is symmetrical. In an hour the minute hand moves through 360° and the hour hand moves through 30° (12 hours are shown on the watch face and 360/12 = 30).
The core loop inside the program is this:   for (int h = 0; h <= 12; h++) {
    float m = (360-30*float(h))*2/13;
    int s = round(60*(m-floor(m)));
    int col = h%6;
    int row = floor(h/6);
    draw_clock((r+f)*(2*col+1), (r+f)*(row*2+1), r, h, floor(m…

The Elevator Button Problem

User interface design is hard. It's hard because people perceive apparently simple things very differently. For example, take a look at this interface to an elevator:

From flickr

Now imagine the following situation. You are on the third floor of this building and you wish to go to the tenth. The elevator is on the fifth floor and there's an indicator that tells you where it is. Which button do you press?

Most people probably say: "press up" since they want to go up. Not long ago I watched someone do the opposite and questioned them about their behavior. They said: "well the elevator is on the fifth floor and I am on the third, so I want it to come down to me".

Much can be learnt about the design of user interfaces by considering this, apparently, simple interface. If you think about the elevator button problem you'll find that something so simple has hidden depths. How do people learn about elevator calling? What's the right amount of informati…