Here's what has been keeping me busy (apart from my real job) since just after Christmas - a timed camera remote. It is mostly code complete, although could do with a few tweaks here and there. The hardware however isn't quite finished as I'm still waiting for a few parts to be delivered before I can finally finish it - the most critical of which is the 2.5mm stereo plug to go into the camera. Consequently it hasn't actually fired my camera yet, but I'm confident it will work correctly when the final parts arrive.
Background
Many moons ago, I created a serial port remote release for my Samsung GX10 DSLR, designed to be triggered from my Palm Pilot. I had a program for the palm that would run through a timed sequence, and could trigger the camera remote release through the Palm's serial port. A circuit diagram of the original is here: http://www.flickr.com/photos/gdaj/1317816870/ (my apologies for the link to an image on another site - this was done years ago, and is only slightly relevant to this project). It worked well but was very limited, and unfortunately after several house moves, the Palm Pilot and the cable seem to have vanished. So when I started playing around with the MSP430, I thought a proper timed shutter release would be a good project. After months of procrastination I finally set to work creating it just after Christmas.
Functions
I wanted something that could do more than just fire off a shot every n seconds for x shots. So my aim was for the timer to have multiple modes. The things I wanted it to be able to do were:
- Timed bulb shots (I love night-time photography),
- capable of handling bracketed shots - so instead of just firing the camera once every n seconds, it should fire it 3 times, or 5 times etc
- capable of bracketing multiple bulb shots - so the timer has to control longer or shorter exposure times.
- allow for the camera's inbuilt noise reduction for long exposures - my cameras will do dark-frame subtraction after a long bulb exposure, whereby they take another photograph of the same length of time but with the shutter closed. This means taking multiple bulb shots would have to allow for this time delay
I came up with a flow control that allows for all these different scenarios, but still with a fairly straight forward user interface.
The Camera Interface
I have a Samsung GX10 (Pentax KD10 copy), and a Canon EOS 450D. Both of these cameras use the same interface for the remote release. Physically, the camera has a 2.5mm stereo headphone socket. Electronically, the tip is the shutter, the ring is the focus, and the sleeve is ground. To activate shutter or focus, the tip or ring is connected to ground. An open collector transistor is suitable for this. The trick is though, that the focus has to be grounded before the shutter. If you look at the above diagram, you'll see they both get their signal from the same pin, and are therefore both grounded at the same time. This mostly works, but if the camera goes into sleep mode, the focus activation will wake it, but it won't acknowledge the shutter press. My final code allows you to set the delay between when the focus is activated and the shutter is activated, to give the camera time to wake up. This also allows you to use auto-focus if you really want to, by increasing the delay long enough to allow focus.
The Hardware
The brains behind the operation is an MSP430G2452, currently on the launchpad, but it will ultimately be on a standalone board. To drive the camera interface, all the MSP430 does is drive a pair of open-collector NPN transistors - I use BC549's but pretty much any small-signal NPN transistor will do the trick. To convey all the information to the user, a standard 16x2 text LCD module is used, in 4 bit mode. I use a transistor to switch the backlight, controlled from a pin on the 430, and also use a couple of transistors to switch power to the whole module. This allows me to turn the display completely off when not in use, or while doing a long shooting sequence to save power. Finally, the user interface is controlled by a rotary-coder switch. This uses 3 pins on the 430 - two for the grey-coded rotation and one for the push-button. I initially was using hardware debouncing with capacitors & resistors, and the fact the 430 has Schmidt inputs, but was running into hassles getting reliable operation, so changed to software debouncing. The 32khz crystal is used to manage the timing. All up I'm using all but one GPIO pin. Pin allocation is as follows:
P1.0 - LCD RS
P1.1 - LCD EN
P1.2 - LCD Backlight control
P1.3 - LCD Power control
P1.4-P1.7 - LCD D4-D7
P2.0 - Rotary Coder Pushbutton
P2.1 & P2.2 - Rotary Coder rotation sensor
P2.3 - Focus Control
P2.4 - Shutter Control
P2.5 - spare.
P2.6 & P2.7 - 32kHz crystal
Note - on the attached circuit diagram, you'll see some scribble next to the TEST pin of the MSP430 - this was a mistake and I couldn't find any whiteout. The capacitor and resistor are obviously connected to the RESET pin, not TEST.
Software
I started out using Energia, but very soon into the design I started running into RAM problems on the 2452, so I put in the 2553. I didn't get much further when I started running into RAM problems with it too. Energia is great in that it is simple to use, and has ready-to-use libraries for a lot of things. But those libraries come with overhead - for example 32 bytes of RAM just to store the list of interrupt functions, even if I'm only using interrupts on 3 pins. So I started again - still in the Energia IDE (because CCS refuses to run on my main development machine), but I didn't use any of the Energia framework. Consequently my code will look familiar to CCS developers. The main file has the .ino extension like all Energia sketches, but if you rename it to .cpp it should compile with GCC no problems. I am using C++, although the only C++ extension I'm using is function type overides. No classes to help keep the code lean. By restarting in this manner, I was able to go back to the 2452 with 6.6k of code, and no RAM problems.
For readability the code is arranged into separate files for different functions.
CameraTimerGCC.ino contains main() and has the general flow control.
clocks.cpp sets up the clocks (1MHz main clock, 32.768 crystal for ACLK, WatchDog Timer running at 4Hz) as well as implementing a Wait() routine using TIMER-A & the crystal to pause for a few milliseconds in LPM3.
encoder.cpp implements the rotary encoder. It contains the P2 interrupt which handles the grey-coded rotation sensor and the pushbutton. A variable holds the relative value of the rotation sensor and indicates if the button has been pressed.
flashsave.cpp copies the current settings to flash or reads from flash. I use the 3 user segments of flash (Segments B, C & D) as 3 "slots" to save your settings into.
lcd.cpp is a basic library to drive the LCD. Only the functions that I needed are implemented.
sequence.cpp handles the logic of shooting the programmed sequence
textconstants.cpp - pretty self explanatory holds most (I need to do some tidying up so it is all) of the text constants used for the display.
ui.cpp - implements the main menu
Sorry, I've run out of time to put my post up. I should be able to post more details later this evening.
