grahamf72 169 Posted January 16, 2014 Share Posted January 16, 2014 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 UPDATE - 26 January 2014 - Nearing Completion Well I finally managed to track down a cable with a 2.5mm plug - after checking all the local "electronics" shops again and drawing a blank, I just happened to be wandering through a department store and saw a lone 2.5mm cable in ratty packaging. Hooked it all up, and nothing. I switched to bulb mode, and still nothing. Then I touched one of the base resistors into one of the transistors, and the camera went nuts. I soon discovered my error - I hadn't made the connection between the emitters of my driver transistors and ground. With no ground reference the MSP wasn't turning the transistors on, so nothing at the camera. Fixed that, ran a sequence, and the camera woke from sleep but still did nothing. A little tweaking and I discovered my program was sound, the problem was just that the time it was holding the shutter down was too short. Dialled up 100mSec instead of 25mSec and everything leapt into action and was working perfectly. Then came the trickiest part of the whole exercise - converting my breadboarded circuit into stripboard. After a few hours with a piece of paper printed with a 1/10" grid I finally worked out a layout that would work. It is probably a long way from optimal, and when I look at the board I see a huge amount of wasted space as well as more wire links than I would like, but it works, that's the main thing. I did end up changing a few pin allocations to things that would allow a more efficient board layout. So last night I sat down and soldered it up. Updated the code with the new pin allocations, flashed it to the 2452, plugged it into the board, connected power, and nothing. Actually not quite true, the backlight flickered a bit. So I poured over the board layout, and found one fault - I had pins P1.6 & P1.7 connected to the LCD's DB7 & DB6 respectively instead of 1.6->DB6, 1.7->DB7. That shouldn't cause the backlight to flicker but it would stop the LCD starting up, so I fixed that and still just had a flickering backlight. All the voltages were what they should be - my 5V line was held at 5.1V by the Zener, my 3.3V line was exactly 3.3V. All the pins on the MSP430 were held at 0, even the rotary coder inputs which should be pulled high. Thinking I may have blown the MSP430 I unplugged it and put it back on the launchpad. With the pin changes, the backlight was now controlled by P1.0, so in theory when I put it back on the launchpad the red led should light for a few seconds before turning off. Nothing. I was pretty sure I'd wrecked the MSP430, so just to test I loaded Energia's basic blinking light program. It was then that I noticed that down the bottom of Energia it said "LaunchPad w/ msp430g2553". Changed that to the msp430g2452, and the blinking light worked. Re-flashed my code and the red led lit up for 10 seconds before turning off. Plugged the 430 back into my board, and everything lit up perfectly just like it should. Did a test run and it operated perfectly, except I noticed the backlight wasn't going out. So, now I was trying to find the reason why the backlight stayed on. My first suspicion was a bridged solder track or similar, but couldn't find any. Next idea was that maybe the controlling transistor had gone short circuit - it had been a little stubborn when I was trying to solder it, the solder didn't want to take. Desoldered it, but I was still getting 0 ohms between the backlight Cathode and ground. Maybe the 10k resistor that I had across the transistor to provide the low backlight was the issue? Removed it, and I was still getting 0 ohms. I came to the conclusion that the problem had to be on the LCD module itself - I was using a brand new module, not the one I had breadboarded. I noticed that the pin for the backlight LED went extremely close to the ground-plane - could it be shorting there? I desoldered the lead (it is sort of wrapped around the end of the board), and the short circuit went away. Soldered the lead back in place and the short circuit was still gone - there must have been a bit of stray solder or something linking it to the ground plane. With that sorted, I put the transistor & resistor back in place, and the backlight control was now working perfectly. All that remains is to put it in a case, and to change the 2 x 2AA holders for a 4AA holder when it arrives. Here's a video showing a run-down of the completed unit. Overall I'm very happy with the result. It is working, and does what I intended for it. Hopefully we'll have some clear nights soon so I can do some long exposure shots. Another Update Now attached is an updated version of the source code. New in this version is: Reflects the final pinout that I used when I went to the stripboard. Time display is improved. Instead of just displaying the time in seconds, the time is now displayed as a combination of days, hours, minutes & seconds, eg "1 hr 5 min" Improved logic within the menus - it skips over the "Burst Interval" option if the Burst Count is 1. When bulb mode is off, it states "Bulb Mode Off" Instead of just having a time of 0. Improved logic when dialing up large values - For times larger than 3 hours it now goes in 15 minute increments. Increased maximum focus time to 10 seconds. Here's a picture of the (near) finished product on stripboard and showing an example of the new time display. CameraTimerUpdated.zip PTB, petertux, cde and 1 other 4 Quote Link to post Share on other sites
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.