In addition to the instruments being sent up with the balloon, we wanted to fly a camera. A lot of the flights we’ve studied sent up a video camera of one sort or another, but since we were trying to keep both costs and weight down, we decided to send up an "intervalometer" – really just a fancy way of saying "a still camera that takes pictures automatically every few seconds".
We read about the idea from the 2009 "Project: Icarus" team at MIT. They used a Canon PowerShot A470 digital camera and hacked it using the Canon Hack Development Kit (CHDK) to temporarily reprogram it. Even fully loaded with batteries, the A470 still weighs under 7 ounces, so this seemed like a pretty sweet way to go. We decided to follow in their footsteps, right down to the hardware, so we bought a good condition A470 off of eBay:
For me the CHDK was really the coolest part of this equation: I had never hacked a camera before. The basic idea was that you load up the SD card with a script and the firmware that you use to TEMPORARILY override the camera’s internal firmware. Rebooting the camera will undo everything that you load from the SD card, so this becomes a very easy and non-destructive way to reprogram the camera.
We want the camera to last for the entire flight and we’re expecting the flight to take several hours, so the goal will be to disable as much of the normal operation of the camera as possible so as to conserve the batteries. That means turning off all flashes, disabling the view screen, and so on. After a lot of trial and error, I found that it was actually easier to perform some of this configuration in script, and the rest from the camera’s menus. The process that follows, then, is broken up into three major steps:
- Getting the SD card ready to host the CHDK and the script
- Writing the script itself
- Booting the camera up, simultaneously loading the script and configuring the settings that aren’t covered by the script.
1) Getting the SD card ready
Of course, before I could even download the CHDK, I actually needed to figure out which build to download. The builds are specific to the camera and the camera firmware, so I had some legwork ahead of me. In hunting around for how to do this, I came across this page, which led me to a lot of the other ones that I will include here. This process follows the steps found on this CHDK wiki page:
First, I needed our camera’s model – that was the easy part – Canon PowerShot A470.
Next, I needed the platform ID (P-ID) of the camera, which I found using the "ver.req" method, described on the CHDK wiki page. That ID came back as "317A NT D", which according to the table meant the camera was released in 2008.
Then, I needed the camera’s firmware. The CHDK wiki had a section that showed me how to find that. Our camera reported a firmware version of "GM1.02C", where "1.02C" was the actual version.
Now that I had the firmware, I was able to download the proper version of the CHDK from http://mighty-hoernsche.de/ – a470-102c-1.3.0-3257-full.zip. (I originally tried using the stable 1.2.0 version of the CHDK, but I later found I needed access to the set_lcd_display() command to shut off the display, and found it was only available in the newer, 1.3.0, version.)
I extracted the contents of that ZIP to my computer, and began to configure the actual SD card. I copied the entire CHDK folder and its subfolders to the root of the card. I also copied the PS.FI2 and DISKBOOT.BIN files to the root of the card. Now that I had the CHDK loaded and ready, it was time to write the script itself.
2) Writing the script
Writing the script didn’t happen as linearly as what I’m going to present here. I spent a lot of time trying to do something in script, and if I couldn’t figure it out there I switched to doing it just setting it using a menu option on the camera. I really wanted to put as much as I could into the script, to eliminate as many manual steps as I could, but I also wanted to get a functional solution, too. As a result and I spent a lot of time bouncing between the script and the manual camera configuration (step 3 below).
I had two options open to me for programming languages – uBasic and Lua. I ended up going with Lua script because I found more samples and snippets in that language. Here is the full balloon.lua script:
@param a = interval (sec)
@default a 5
@param b = shutter speed
@default b 960
– HELPER FUNCTIONS
— Turn main flash off
— Turn off red-eye flash
— Turn off the neutral density (ND) filter, if it exists
— Set the shutter speed (default is 1/1000 of a second)
– MAIN LOOP
start = get_tick_count()
sleep(a*1000 – (get_tick_count() – start))
until ( false )
First, I define a couple of parameters, "interval (sec)" and "shutter speed", that will appear in the camera menu when I pull up the script. Next, I pull in what I think is a library of sorts – "propcase" – which gives me access to some of the camera’s properties.
The helper functions are just that – functions which rename some of the more esoteric function calls to make them a little more programmer friendly. Next, the "Setup" section calls those functions:
- turning off the regular and red-eye flashes
- turning off the LCD viewer
- setting the focus out to infinity
- turns off the ND filter
- sets the shutter speed to whatever I set in the "shutter speed" property passed into the script.
Once the script was written it needs to be copied to the SD card to the CHDK/Scripts folder.
3) Booting the camera up:
Using the script wasn’t quite as easy as I had initially imagined, but it wasn’t bad. The hardest parts of this procedure was figuring out what some of the buttons were on my camera. For example, the online documentation has me pressing the "Alt" button to enable the script running under the CHDK. There wasn’t anything on my camera labeled as such, so that required a few minutes of trial and error.
I settled on the following process for loading the script into the camera:
1) Put the card into the camera
2) Select playback from the wheel (green arrow)
3) Turn the camera on
4) Hit the "Menu" button
5) On the first tab, scroll down to the "Firm Update…" option and press "Func. Set".
6) Select "OK" (using the arrow buttons on the right) and press "Func. Set" again. The firmware update will flash by briefly.
7) Switch the camera to normal mode (the “camera” icon on the wheel).
8) Hit the "Menu" button
9) Select the "Camera" tab (first one)
a) Verify the "AF Frame" (auto-focus frame) is set to "Center".
b) Change "AF-assist Beam" to "Off"
c) Go into the "Flash Settings…" submenu, and change "Red-Eye Lamp" to "Off"
10) Back out of the "Flash Settings…" submenu, scroll down and change the "Review" option to "Off". This ensures that the camera will not try to show you the shot just taken.
11) Scroll all the way back up, and switch to the second, "Tools" tab. Change to "Mute" setting to "On".
12) Exit the Menu by pressing "Menu" again.
13) Enter into "Alt" mode by pressing the printer button (lower left corner).
14) Wait for the blue/white menu to appear on the display.
15) Hit Menu again.
16) Scroll down to "Script (Program your camera) and hit "Func. Set"
17) Hit "Func. Set" on the very first option called "Load script from File…"
18) Find the balloon.lua file and hit "Func. Set"
19) Configure the script as follows:
interval (sec) = 10
shutter speed = 960
20) Hit "Menu" to return to the main screen.
21) The script is now loaded and fully configured and the camera is ready to go. Simply hit the shutter to start the script running. Hit it again to stop it.
Now that I had a functioning intervalometer script and a process for booting the camera up, it was time for an endurance test. I had done several few small runs in the course of writing the script, and the camera was taking pictures of about 1.8MB a piece. With the 8GB card, and taking a picture once every 10 seconds, I figured the card should be able to store over 12 hours of images, so the real question was how long would the batteries hold out?
I set the camera up on my desk, and started it running about 9:50pm one evening.
And of course got quickly photobombed by CJ.
The next morning, I awoke to find the camera still going! In fact, according to the timestamps on the images, the camera took pictures for 8 hours and 46 minutes – over 3000 pictures in all, spaced 10 seconds apart. Originally I was concerned that we would have to hook up an external battery pack, to provide an extra boost for the camera, but now I don’t think we will. It looks like a single pair of fresh Energizer Ultimate Lithium AAs, and all of the effort to disable unnecessary features in the camera, will be sufficient.
There is one more test I think we should run on the camera, specifically for the shutter speed. Right now, the script defaults to 1/1000th of a second, which is faster than what the MIT group set theirs to (1/800th of a second). Other than that, I think the camera is ready to go!