Introduction: Build Your Own (cheap!) Multi-function Wireless Camera Controller.

About: I have a Masters in Physics, just starting a PhD in 3D robotic vision.

Introduction

Ever fancied building your own camera controller?

IMPORTANT NOTE: Capacitors for the MAX619 are 470n or 0.47u.  The schematic is correct, but the component list was wrong - updated.


This is an entry into the Digital Days competition so if you find it useful, please rate/vote/comment favourably!  If you reallly like it and are a stumbler, hit "i like it!" :)

Update: featured on hackaday! hackaday.com/2009/10/13/a-different-breed-of-camera-controllers/
Update: new photos of the laser trigger in action!
Update: First Prize =D, thanks for voting and/or rating!

This instructable is mainly for the benefit of SLR users looking to get a bit more mileage out of their cameras, however if there are any point and shoots with IR interfaces, you might find this interesting. Certainly this will also work (with a bit of modification) with camera hacks where you can wire up logical outputs to camera trigger terminals.

This started off as a full blown tutorial, but due to some unexpected constraints i encountered later on, it may be more of a guide as to how to accomplish various things - i'll often leave you the choice on how you could do things which i think is a better way of doing things than just blindly saying "you must do this".  Think of this as a lesson in camera controller design.

I've provided schematics and full code so you can always just copy it.  It will be a simple case of transferring the design to a stripboard and adding the LCD for most people.  I've gone through how to breadboard it since the process is very similar and allows for correcting mistakes before you make the design permanent!

Features:

Single shot mode
Interval (time lapse) mode
Triggered shot (trigger from external sensor) mode with variable conditions
Included sensor designs - light, sound (many more possible!)
Total cost - under £25 (excluding tools)
LCD Display for easy change of settings
Compatible with Nikon/Canon (coded), potential support (untested) for Olympus/Pentax
No firmware modification needed
Uses IR so is both wireless and doesn't damage your camera

I had the idea for this after sitting outside in the cold clicking my remote control for hours. I was doing an 8 second interval for around 1000 shots. I thought, hey, it's just an IR LED isn't it? Why can't i replicate it and make my own remote with a built in delay?

I then found out (somewhat embarrassedly, because i thought i'd had a massive brain wave) that this has been done and there are even a couple of instructables on the topic.

Where my implementation differs from most intervalometers and diy remotes is that it allows for a lot of customisation and modularity, is compatible with both Nikon/Canon (and likely others later) and combines the ability to take a picture on a particular trigger.

The idea is simple. You want to take a picture of something quite fast (limited currently by the lag on your shutter, for me 6ms). There are a variety of methods for doing this:

1. Trial and error  you try to take the picture at the right moment
2. Improved trial and error  you black out the room, put your camera on bulb (open shutter) and fire a flash at the right time
3. Buy a dedicated trigger controller that has some kind of audio/light sensor to take the picture at your command
4. Build one yourself!

Ok, 1 and 2 are fine for messing around and can yield some very good pictures. But what im going to show you is that its possible to construct a circuit that will give you consistent results time and time again. Most importantly, in these tight times, the cost is lower than alternative models (some people have produced kits doing this kind of thing, but they cost a fortune  see links).

The versatility of the design is this:
If your sensor generates an output voltage between 0 and 5V, you can use it to trigger your camera!
On the face of it this is a boring statement, but once you begin to understand the implications it becomes very powerful. By simply monitoring a voltage level, your trigger could be light based (LDR), sound based (microphone or ultrasound), temperature based (thermistor) or even a simple potentiometer. In fact, just about anything. You could even link the circuit up to another controller and provided it can give you a logical output, thus you can trigger from it.

The only major limitation of the design currently is that it works only with IR interfaces, it would be fairly simple to modify the software and hardware to output via mini-USB or whatever sort of interface is required.

Note: Source Code:

I have provided some applications in step 13.  The code i run on my controller as of now is up there in a hex file along with the main c file and its dependencies.  You can simply run my code if you are unsure about compiling.  I've also included some sample code that you can use in various steps (they're named obviously like remote_test, intervalometer test and adc test.  If i refer to code in a step, odds are it's in there.

EDIT: An update about balloons popping - it seems i was a bit short sighted when i said you could easily shoot photos of popping balloons.  Turns out that the skin on the average balloon travels so fast that it'll have popped completely by the time your camera fires.  This is an issue with most cameras, NOT the controller (which senses the ADC at a rate of around 120kHz).  The way round this is to use a triggered flash, which is doable if you add an extra wire out and another small circuit.  That said, you could in theory use something else to pop it and play with the delay (or even change the delay code to include microseconds).  A air pellet travelling 1m at 150ms-1 takes about 6-7ms, enough time to trigger and shoot.  Just moving the gun would provide a rudimentary delay of a few microseconds.  Again, apologies about this, i'm going to play about tonight if i can get hold of some balloons, but there are still many uses for an audio trigger, like fireworks!

I've put a quick and dirty time lapse below to show that it works however :)



Don't forget to read, rate and/or vote!

Cheers, Josh

Disclaimer

In the unlikely event that something goes horrifically wrong or you somehow brick your camera/dremel your cat, i am not liable for anything.  By starting a project based on this instructable, you accept that and continue at your own risk.


If you make one of these, or use my instructable to help you - please send me a link/photo so i can include it here!  The response has been overwhelming so far (at least by my standards) so it'd be awesome to see how people are interpreting it.  I'm working on revision 2 as i type ;)


Step 1: Some Initial Thoughts...

So, how are we going to build this thing?

Microcontroller

The heart and soul of this project is an AVR ATMega8. It is essentially a slightly trimmed version of the ATMega168 chip that Arduino use. It is programmable in C or Assembly and has a variety of really useful features that we can use to our advantage.

" 28 pins, the majority of which are input/output (i/o)
" Onboard analog to digital converter
" Low power consumption
" 3 onboard timers
" Internal or external clock source
" Lots of code libraries and samples online

Having lots of pins is good. We can interface with an LCD screen, have 6 button inputs and still have enough left over for an IR LED to shoot with and some status LEDs.

The Atmel AVR series of processors has a lot of support online and there are plenty of tutorials in getting started (i will go over this briefly, but there are better dedicated tutorials) and heaps and heaps of code to mull over. For reference ill be coding this project in C using the AVR-LibC library.

I could have easily gone with PIC to do this, but AVR is well supported and all the examples i've found for remotes have been AVR based!

LCD Display

There are two main types of display, graphical and alphanumeric. Graphical displays have a resolution and you can put pixels wherever you like. The downside is that theyre harder to code for (although libraries exist). Alphanumeric displays are simply one or more rows of characters, the LCD has an onboard store of basic characters (i.e. the alphabet, some numbers and symbols) and its relatively easy to output strings and so on. The downside is theyre not as flexible and displaying graphics is virtually impossible, but it suits our purpose. Theyre also cheaper!

Alphanumerics are categorised by their row and column count. The 2x16 is pretty common, with two rows of 16 characters, each character being a 5x8 matrix. You can get 2x20s too, but i dont see the need. Buy whatever you feel comfortable with.

I chose to use a red backlit LCD (i want to use this for astrophotography and red light is better for night vision). You can go without a backlight - its entirely your choice. If you choose a non backlit route you will save power and money, but you might need a torch in the dark.

When looking for an LCD, you should ensure that it is controlled by the HD44780. It is an industry standard protocol developed by Hitachi and there are a lot of good libraries that we can use to output data. The model i bought was a JHD162A from eBay.

Input

Input will be done by buttons (simple!). I chose 6 - mode select, ok/shoot and 4 directions. Its also worth getting another small button for resetting the micro in case of a crash.
As for the trigger input, some basic ideas are a light dependent resistor or an electret microphone. This is where you can get creative or stingy depending on your budget. Ultrasound sensors will cost a bit more and require some extra programming but you can do some really neat stuff with them.

Most people will be happy with a microphone (probably the most useful general sensor) and electrets are very cheap. Be aware that itll need to be amplified too (but ill go over this later).

Output - Status

The only real output we need is status (besides the display), so a couple of LEDs will work fine here.

Output - Shooting

For taking pictures, we need to interface with the camera and for that we need a light source that can produce infra-red radiation. Thankfully there are a multitude of LEDs that do this and you should try to pick up a reasonably high power one. The unit i chose has a current rating of 100mA max (most LEDs are around 30mA).

You should also take care to note the wavelength output. Infrared light is in the longer wavelength part of the EM spectrum and you should be looking for a value of around 850-950nm. Most IR LEDs tend towards the 950 end and you may see a bit of red light when it's turned on, this isn't a problem, but it's wasted spectrum so try to go closer to 850 if possible.

Power

How are we going to power all this? Well, it's going to be portable so batteries! I chose to use 2 AA batteries which are then stepped up to 5V. I'll go over the reasoning behind this in the next few sections.

'Casing and Construction'

How you do this bit is entirely up to you. I decided to use stripboard for the circuit after prototyping because it's cheap and flexible and saves designing a custom PCB. I have provided the schematics so you are free to make your own PCB layout - although if you do, i would be grateful to have a copy!

Again the case is entirely your choice, it needs to be able to fit the screen, buttons (in a fairly intuitive layout if possible) and the batteries. As circuit boards go, this one isn't that complicated, a lot of the connections are simply to things like the buttons/LCD.

Step 2: Power Management

Power Management

For a project like this it's obvious that portability should be a key aspect. Batteries are thus the logical choice!

Now, for portable devices it is fairly key that you pick a battery source that is either rechargeable or easily available. The two main options are the 9V PP3 battery or AA batteries. I'm sure some people will assume that a 9V battery is the best option because hey, 9V is better than 3 right?
Well, not in this case. 9V batteries whilst very useful, produce their voltage at the expense of battery life. Measured in mAh (milliamp hours), this rating tells you in theory how long a battery will last operating at 1mA in hours (though take it with a pinch of salt, these are often under ideal, low load conditions). The higher the rating, the longer the battery will last. 9V batteries are rated at up to and around 1000mAh. Alkaline AA's on the other hand have almost three times as much at 2900mAh. NiMH rechargables can reach this, though 2500mAh is a reasonable amount (note that rechargeable batteries operate at 1.2V not 1.5!).

The LCD screen needs a 5V input (�10%) and the AVR (the microcontroller) needs roughly the same (though it can go as low as 2.7 for low frequency clock speeds). We also need a fairly stable voltage, if it fluctuates about it could cause problems with the microcontroller.

To do this we'll use a voltage regulator, you need to make a choice over price vs efficiency now. You've got the option of using a simple 3-pin voltage regulator like the LM7805 (78 series, +5 volts output) or a small integrated circuit.

Using a simple regulator

If you choose to go with this option, you need to bear a few points in mind. Firstly, three pin regulators almost always need an input that is higher than their output. They then step the voltage down to the desired value. The downside is that they have awful efficiency (50-60% is good going). The upside is that they're cheap and will run with a 9V battery, you can pick up a basic model for 20 pence in the UK. You should also bear in mind that regulators have a dropout voltage - the minimum gap between input and output. You can buy special LDO (Low DropOut) regulators that have dropouts at around 50mV (compared to 1-2V with other designs). In other words, look out for LDOs with a +5V output.

Using an integrated circuit

The ideal way to go is a switching regulator. These will be, for our purpose, normally 8-pin packages that take in a voltage and give us a regulated output at a high efficiency - almost 90% in some cases. You can get step up or step down converters (boost/buck respectively) depending on what you want to put in, alternatively you can buy regulators that will take either above or below the desired output.

The chip i'm using for this project is a MAX619+. It is a 5V step up regulator that takes 2 AA's (the input range is 2V-3.3V) and gives a steady 5V out. It only needs four capacitors to operate and is very space efficient. Cost - �3.00 including the caps. Arguably it's worth the splurge just to get a bit more use out of your batteries. The only major downside is that it's not short circuit protected, so if there is a current surge, be warned! This is reasonably trivial to fix with an add on circuit however:

Another useful chip design - although not nearly as neat a solution is the LT1307. Again, a 5V regulator, but it can take a variety of inputs and has useful things like low battery detection. It costs quite a bit more at nearly �5 with inductors, large capacitors and resistors.

Voltage Rails

We are going to be using two main voltage rails (plus a common ground). The first will be the 3V from the battery, this will be used to power the LEDs and other relatively high power components. My MAX619 is only rated up to 60mA (though absolute maximum is 120mA) so it is easier to connect the microcontroller to a MOSFET to control any LEDs. The MOSFET draws almost no current and acts as a break in the circuit when the gate input is under around 3V. When the microcontroller sends out logical 1 on the pin, the voltage is 5V and the FET turns on, then just acting as a short circuit (i.e. a piece of wire).

The 5V rail will power the LCD, Microcontroller and any amplification circuits for input sensors.

Power Consumption

If we look at various datasheets, we note that the AVR takes no more than 15-20mA at maximum load.

The LCD takes only 1mA to operate (at least when i tested, budget for 2). With the backlight on, it's really up to you to decide. Connecting it straight up to the 5V rail (i tried) is fine, but make sure it has an onboard resistor (follow the traces on the PCB) before you do. It drew 30mA that way - terrible! With a 3.3k resistor it's still viewable (perfect for astro photography) and only draws 1mA. You can still get decent brightness using a 1k or otherwise. I'm fine with mine drawing just under 2mA with the backlight on! If you want, it's trivial to add a brightness knob using a 10k potentiometer.

The IR LED might take 100mA maximum, but i have had good results with 60mA across mine (experiment!). You can then halve that current because you're effectively running at a 50% duty cycle (when the LED is modulated). Anyway, it's only on for a fraction of a second so we don't need to worry about this.

The other LEDs you should play about with, you may find that only a 10mA current is enough to give you a good brightness - certainly look for low power LEDs (excluding the IR one), youre not designing a torch! I chose not to add a power indicator in my circuit, simply because it's a lot of current draw for not much use. Use the on/off switch to check if it's on!

In total, you shouldn't be running more than 30mA at any one time and with a theoretical supply of around 2500 (allowing for variation) mAh that should give you well over 80 hours straight with everything on. With the processor idled for most of the time this will at least double/triple, so you shouldn't have to change your batteries very often.

Conclusion

There we go, that was easy wasn't it! You can either go cheap and cheery with a 9V battery and a LDO regulator at the expense of efficiency or pay a bit more and use a dedicated IC to do it. My budget was still under �20 even WITH the IC, so you can drop it even further if you need to.

Step 3: A Closer Look at the ATmega8

Pins

Image 1 is the pinout diagram for the ATMega8 (exactly the same as the 168/48/88, the only difference is the amount of onboard memory and interrupt options).
Pin 1 - Reset, should be held at VCC voltage (or at least logical 1). If grounded, the device will soft-reset
Pin 2-6 - Port D, general input/output
Pin 7 - VCC, supply voltage (+5V for us)
Pin 8 - Ground
Pin 9,10 - XTAL, external clock inputs (part of Port B)
Pin 11 - 13 Port D, general input/output
Pin 14 - 19 Port B, general input/output
Pin 20 - AVCC, analogue supply voltage (same as VCC)
Pin 21 - AREF, analogue voltage reference
Pin 22 - Ground
Pin 23-28 Port C, general input/output

Usable i/o ports: D = 8, C = 6, B = 6
A total of 20 usable ports is great, for simplicity you should group your outputs either into ports (say, D as the output port) or into groups on the board - you might want the LCD to run from Port C just to keep the wires tidy in that corner.
There are three extra pins that are required for programming. Those are MISO (18), MOSI (17) and SCK(19). These will happily act as i/o pins if needed though.

Clocking

The signal that we send to the camera needs to be precisely timed (accurate to around a microsecond) so it's important we choose a good clock source. All AVRs have an internal oscillator that the chip can get its clock from. The downside of this is that they can fluctuate around 10% with temperature/pressure/humidity. What we can do to combat this is use an external quartz crystal. These are available in anything from 32768kHz (watch) to 20MHz. I've chosen to use a 4Mhz crystal as it provides a decent amount of speed yet is fairly power conservative compared to perhaps 8Mhz+.

Onboard Power Management

I really wanted to use sleep routines in my code.  In fact i wrote the first version to rely heavily on idling the processor while time lapsing.  Unfortnuately, due to time constraints, i ran into some issues with running the clock externally and interrupting using the timers.  In essence i'd have to rewrite the code to deal with the controller simply not waking up - which i could do, but time is against me.  As such, the device only draws 20mA ish so you can get away with it.  If you're really up for it, then by all means fiddle with the code, all you need to do is to clock internally and then run Timer 2 in asynchronous mode using the 4MHz crystal for the more accurate delays.  It's simple to do, but time consuming.

ADC

The swiss army knife in the AVR toolset, the ADC stands for Analogue to Digital Converter. How it works is relatively simple from the outside. A voltage is sampled on a pin (from some sensor or other input), the voltage gets converted into a digital value between 0 and 1024. A value of 1024 will be observed when the input voltage is equal to the ADC reference voltage. If we set our reference to be VCC (+5V) then each division is 5/1024 V or around 5mV. Thus an increase of 5mV on the pin will increase the ADC value by 1. We can take the ADC output value as a variable and then fiddle with it, compare it with things, etc in the code. The ADC is an incredibly useful function and allows you do lots of cool things like turn your AVR into an oscilloscope. The sampling frequency is around 125kHz and must be set in proportion to the main clock frequency.

Registers

You may have heard of registers before, but fear not! A register is simply a collection of addresses (locations) in the AVR memory. Registers are classed by their bit size. A 7 bit register has 8 locations, as we start from 0. There are registers for just about everything and well take a look at them in much more detail later. Some examples include the PORTx registers (where x is B, C or D) that control whether a pin is set high or low and sets pull up resistors for inputs, the DDRx registers which set whether a pin is output or input and so on.

The Datasheet

A behemoth of literature, weighing in at around 400 pages; the AVR datasheets are an invaluable reference to your processor. They contain details of every register, every pin, how timers work, what fuses should be set to what and much more. They are free of charge and you will need it sooner or later, so download a copy!

www.atmel.com/dyn/resources/prod_documents/doc2486.pdf

Step 4: Allocating Pins

I already mentioned the inputs and outputs we need, so we should allocate them pins!

Now, PORT D has 8 pins which is convenient as it can act as our output port. The LCD requires 7 pins to operate - 4 data pins and 3 control pins. The IR LED only requires one pin, so that makes up our 8.

PORTB is going to be our button port, it has 6 inputs, but we're only going to need 5. These will be the mode and directional buttons.

PORTC is special, it is the ADC port. We only need one pin for the trigger input and it makes sense to put it on PC0 (a common abbreviation for port pins in this case Port C, Pin 0). We then have a couple of pins for status LEDs (one lights up when the ADC value is above some condition, the other lights up when it is below some condition). We are also going to put our ok/shoot button input here, for reasons that will become clear later.

After all this, we've used up the majority of the ports but we still have a few left if you wish to expand the project - perhaps multiple triggers?

Step 5: Communicating With the Camera

Note: Image used without permission from http://www.bigmike.it/ircontrol/

We will be using the IR emitter to send a signal to the camera. The upshot of this is it's wireless and there is NO WAY you can damage your camera (unlike connecting things into the camera's ports). If you manage to damage your camera by pointing an IR emitter at it, then I sure as hell hope you don't take your camera outside!

Software

There are two states that we need to emulate, and this is true for all cameras (indeed more or less all IR communication). Communications are sent as ones and zeroes, highs and lows.

First is the on state, when we send a logical one, we must turn the emitter on and off rapidly. We modulate the signal. Different manufacturers have different requirements for this. Nikon is 38.4kHz, Canon is somewhat less. 38k is around what most cameras use. To get this modulation we work out the period (1/f) to know that for, say, Nikon we need an on/off cycle every 26 microseconds. The modulation is symmetrical so on takes 13uS and off takes 13uS.

The Nikon sequence is (kudos to BigMike.it):

On for 2000uS
Off for 27830uS
On for 390uS
Off for 1580uS
On for 410uS
Off for 3580uS
On for 400uS

The sequence is pulsed once, there is a 63ms delay, then it is pulsed again and the shot is taken. Notice that most of those numbers are divisible by 13.

For Canon it is (with 32kHz modulation - thanks to http://www.doc-diy.net/photo/rc-1_hacked/index.php):

16 cycles (30uS each)
Pause for 7.3ms
16 cycles (30uS each)

Much simpler.

Using an accurate delay library in the code, as most of the Nikon sequences are multiples of 13, we can just use for loops to go through them to get the relevant amount of on time (off time is just a normal delay). There are some guides that suggest you use assembly to get the timing precise, but as the doc-diy link shows, the timing can be pretty far off and still produce a valid trigger signal.
The delay library i use bases its delays from clock cycles (knowing the clock frequency, and the number of clock cycles it takes to execute a given function) so it's very precise, but limited to your crystal accuracy.

Other Manufacturers

If you have a different camera, simply modify the shoot(); function in the final C code.  It should be fairly easy if you know the modulation and the pulse sequence.

Olympus: http://olyflyer.blogspot.com/2007/07/how-to-make-your-own-rm-1-compatible.html
Pentax: http://sourceforge.net/projects/prcf/ look at the source code for the sequence

Hardware

As we're going to be using a high current emitter, we can't simply draw that current through the microprocessor (see the datasheet for absolute maximum ratings). What we're going to do instead is draw it straight from the battery with an electronic switch, the MOSFET.
Unlike a transistor which involves fiddly calculations to get collector and emitter currents, gain and so on, MOSFETs are surprisingly easy to use.

The 2N7000 i recommend you buy is a basic low power 'FET. There are many variety of 'FET that can be used to switch many Amps using microcontrollers that would just frazzle if they tried to draw that kind of current. There are three parts to the 'FET, the Source, the Gate and the Drain.

The source lead is connected to ground and the gate is connected to the microcontroller pin (i just connect them straight up, but you could always put a resistor in just in case - check the threshold voltage). The components you want to turn on are connected to the power rail and to the drain lead. When the threshold voltage is reached on the gate - i.e. when the micro turns on the pin - the 'FET starts conducting and acts like a wire to complete the circuit between the power rail and ground. For the 2N7000 the threshold is a maximum of 3V, minimum of 0.8V.

We also note that the drain-source resistance (the 'FET acts like a resistor bridging the components to ground) is very small - in the order of 5R max. Whilst this is very small, it could mean a noticeable drop in current across the emitter - you can compensate by lowering the value of the resistor that's in series with the emitter. This resistor, using the very useful LED Calculator () with 3V in, a forward voltage (check the emmiter's datasheet) of 1.7V and a current of 80mA to be 18R. You could get away with a 12R, but i would stick with 18R to be on the safe side. Image 1 shows how the circuit is wired up

V+ in this instance is our 3V rail. As the gate is seeing 5V, the LED would currently be turned on.
If you want to look into how MOSFETs actually work and more detailed technical information:

http://www.irf.com/technical-info/appnotes/mosfet.pdf

Step 6: Component/Supply List

SCHEMATIC: http://img8.imageshack.us/img8/8904/cameracontrollerschemat.png - read the breadboard tutorials first in case i've made any mistakes!

CPU/LCD
1x ATMega8 or ATMega88/168 (needs at least 8k of memory) £1.50
1x HD44780 compatible LCD screen £4-6 (6 if you want cool colours) from eBay
1x 10K Pot (or try different resistors) for contrast control 10-30p
1x 4MHz Crystal - 20p
2x Ceramic/Tantalum 22pF capacitors - 20p
1x 4K7-10K resistor (any will do really)
1x 10-pin Male Header/Socket (if you want a programming port on the finished board - recommended) - http://www.labombiya.com.ar/images/10pin-6pin/dsc00457.jpg
1x 28 pin DIL socket (0.3")
2x Mini LEDs Red, Green (3mm, but you can go with whatever colour you want really...)
Total: ~£8

Power
1x MAX619 DIP8 - £2.71 Farnell
1x 8 pin DIL socket
2x Tantalum 470nF capacitors - 20p
2x 22uF Low ESR electrolytic capacitors - 20p
Total: ~£3.50

IR
1x High Power IR LED (2V, 100mA) - 15p (rapid 58-0112)
1x 18R Resistor
1x 2N7000 MOSFET (or similar) - 10p
0.5m Speaker Cable (or other 2 core wire) - 50p
Total ~£0.75

Input
6x Switches SPST momentary - £1.20
1x On/Off Switch - 40p
Total ~£1.50

Light Trigger
1x Light Dependent Resistor or Photodiode - 30p
1x Potentiometer, rated the same as the maximum resistance of the LDR/diode - 10-50p
Total ~£1

Sound Trigger
1x Electret Microphone - 50p (cheap to buy in bulk on eBay)
1x 220R resistor
1x 100n capacitor (ceramic/tantalum) - 1p
1x TL072 or similar Op-Amp - 20p
1x 10uF capacitor - 10p
2x 22K resistors
1x 1K2 resistor
1x 1K resistor
1x 1M Potentiometer for varying gain (0 - 1000) 50p
Total: ~£2.00

Enclosure
1x ABS Enclosure, to fit components - your choice entirely what sort you get - 70p
1x Battery Box, dual AA - 20p
Total: ~£1

Programmer
USBasp - £12 from eBay
1x 10 pin ISP header
1x 28 pin DIL socket (0.3")
Total £12

Tools/Sundries
Soldering Iron
Solder wire
Solder sucker/Braid

Small Files
Dremel/Rotary Tool
Needle Nose Pliers
Scissors
Wire Strippers

Wires (both single and multi stranded)
Stripboard


Cost minus tools/programmer: £18 ish
Parts were bought from RapidOnline and Farnell UK.  Prices are roughly accurate.  I don't count resistors in the price because they are so cheap these days and per unit they're about £0.0025.  It's worth coughing up for a selection anyway, they cost around £5-6 for mixtures of around 600 resistors.

If i've missed a component out but use it later in a schematic, i apologise profusely!

Step 7: Lets Get Started

I recommend going about this project (unless youre experienced) in the following way:

First off, we'll set everything out on a prototyping board (breadboard). Start off with the power supply, check it works with a multimeter and perhaps pop in an LED+resistor to make sure. Then put in a programmed AVR, wire that up, connect up your power rails and try a "hello world" blinking light application.

After you know that your programmer works, you can test a basic remote control - where turning the AVR on fires a shot every so often (this also demos the interval timer function).

Next we'll add buttons.

Then we can get onto looking at the ADC, but for this we'll need the LCD. So before we play with triggers we need to solder and connect the screen to the micro and run some simple lcd routines to make sure they're all working (there is a good application for this provided by the gentleman who wrote the libarary i'm using*).  The intervalometer will also be added in a menu system.

Once that's all set up on the board and the program is working, we can start copying it over to the stripboard. The IC's will be in sockets for easy removal and it's worth adding a 10-pin header so you can program the chip whilst it's on the board. But that's getting ahead of ourselves!

*http://www.jump.to/fleury
http://homepage.hispeed.ch/peterfleury/lcdlibrary.zip

Step 8: Building the Power Supply

Now, this will be different depending on the route you decided to take. If you bought a MAX619 (datasheet attached), read on! Most integrated regulators will operate in roughly the same way. We have an input with a capacitor and an output with a capacitor to remove voltage ripples. The larger these capacitors are, the less ripple you'll get, but if like me you're using electrolytic capacitors then you want to keep it as small as possible.

Low ESR stands for Low Equivalent Series Resistance, you can read more about it here: http://www.low-esr.com/
http://www.illinoiscapacitor.com/uploads/papers_application/A0A0A86888CE4C0591627D18FF09455A.pdf

For this step, you'll need from your components and tools:

The MAX619
2x Tantalum 0.47uF capacitors
2x 22uF (Low ESR) Electrolytic Capacitors
Wires

When i'm wiring on breadboards i like to colour code wires, it really helps tracing circuit paths with complicated circuits and you can easily see which are ground wires etc.

The chip probably comes in antistatic packaging in a tube. Touch the exposed metal on your computer to ground yourself and then pop out the chip - it's fairly unlikely you'll actually damage a chip by touching it but it has been known to happen. The semi-circular notch indicates the top of the chip and the top left pin is pin 1. If we look at the data sheet for the MAX619 we can find both the pinout and a sample circuit.

Page 6 has the circuit we're going to implement. Note that the two tantalum capacitors join pins 1 and 8, 4 and 5. These are conveniently at opposite ends of the chip. We note that Vin goes to pin 2 in parallel with the electrolytic cap going to ground. Similarly, Vout is from pin 3 and with a parallel cap going to ground. Pin 6 should be grounded and we needn't connect pin 7.

Place the chip across the middle of the board, remember that rows are connected so we don't want to connect any pins together. Put in the ceramic capacitors, you might find it easier to run a small length of wire (my caps had very short legs) in series.

Decide which rail you want to be +5V and which +3V. I chose the outside to be +5V so that's where i wired Vout to. The battery should be wired up from one of the rails to pin 2. Remember to connect your electrolytic caps the right way round, the strip down the side generally indicates negative - it'll certainly be printed there.

Connect the red flying lead to the positive 3V rail and the black lead to the common ground.

The pictures should give you an idea of what it should look like. Be sure to test both 3 and 5 volt rails with your multimeter. If it doesn't work as expected, check to make sure you haven't accidentally crossed any wires or connected two leads by mistake. If you smell burning plastic, pull the leads out straight away, you have a couple of seconds before your chip goes bye bye =P

Step 9: Building the Main Circuit

In this step we'll prototype the heart of the circuit. You'll need your microcontroller, the 4MHz crystal, two 22pf ceramic capacitors, a 10k resistor and some wires for VCC and ground. We'll also put in a couple of LEDs so that we can run a test app to make sure everything works.

Place the microcontroller on the breadboard so it straddles the middle trench. This way, again, we don't connect opposite pins to each other.

First, pin 1. This is reset and should be held at logical 1 for the chip to work. Connect it to the +5V voltage rail by means of the 10k resistor (and some wire if you need it).

Working down, we get to pins 7 and 8. These are VCC and ground respectively. Connect up pin 7 with a (red) wire to the 5V rail and pin 8 to ground.

On the opposite side, connect pin 20 up to VCC too (AVCC) and ground pin 22.

Place the crystal so it connects up pins 9 and 10. Then, connect a capacitor from each of these pins to ground (you can just put the capacitors so they feed into the ground pin).

For the LEDs we're going to use pins 24 and 25. Put a resistor and LED in series with each pin (going to ground). Check the LED polarity is correct (it's unlikely you'll actually burn it out with the low voltages if you wire it backwards, but it won't turn on). The negative leg is on the same side as the flat indent in the plastic casing.

Check the pictures below to compare with your circuit and continue!

Step 10: Prepping Your Programming Environment

If you already have a programmer and are comfortable with flashing files to AVR chips, you may skip this step.

If you don't already have a programmer for your micro then now is the time to get one. The cost varies from DIY models to the GBP60+ all-in-one boards. The model i chose is the USBasp, it cost me GBP12 from eBay though you can buy from other people or just build your own.

http://www.fischl.de/usbasp/

It was the cheapest USB model i can find, is about the size of a large memory stick and is perfect for what we're doing. The only hitch i had was trying to install the drivers on Windows 7, but that's another story. The libUSB drivers are Mac and Linux compatible, mind you.

The way most AVR programs are uploaded is through an ISP (In System Programming) cable. There are both 6 pin and 10 pin varieties, both are essentially the same. The 10 pin cable just has more ground wires than the 6 pin (and only one needs to be connected). If you look at the pinout for the cable (image 1), most of those pin names should be familiar. Yep, they're from the AVR chip. The programming process is a simple matter of plugging in the cable to the programmer and then connecting it up pin for pin.

The way i do it is by use of a programming cradle. It was simple to build, just two components soldered onto a bit of stripboard with wires linking pins. Those components are a 28-pin DIL socket, or however many pins your chip has, and a 10 pin male header that will fit the ISP cable.

To build it, you simply solder both onto the board (making sure you cut the relevant tracks so as not to connect opposite pins - i used a dremel with an engraving tip for this) and work out from the pin diagrams which bits you should wire together.

One very important thing to note is that if you change your fuse bits to enable an external crystal, the chip will look for it (and its required capacitors) when you are programming and if it's not connected it won't power up correctly (the programmer will just error at you). So for mine, i soldered a couple of wires (they're the white ones in the picture) to connect to the crystal on the breadboard. You also need to connect up the ground wire to the ground of the crystal/capacitor block.

If in doubt, The Real Elliot has some excellent instructables detailing how to build the programming cradle or an entire serial programmer.

https://www.instructables.com/member/The+Real+Elliot/

Step 11: Writing and Compiling AVR Code

Writing the code is very simple, you can do it in C or Assembly Language. I chose C because i'm more comfortable in it and it's easier for others to see what i'm doing. You can use any text editor to make the .c files (and any headers, etc) and my preferred method for compiling/linking is using the command line (it is pretty easy).

First of all, download a copy of WinAVR - http://winavr.sourceforge.net/ or MacAVR http://www.harbaum.org/till/macavr/index.shtml

WinAVR is a suite of useful tools such as the compiler, code headers/libraries and more. Basically all you need to start programming and uploading your code.

Coding for AVRs is very simple. You simply write out your code using normal C, you can include standard libraries for sorting, string manipulation, maths and much more. You need to include the relevant AVR libraries such as the io, sleep, interrupt packages depending on what your code contains (the library is always necessary).

Once the code is written, it must be compiled and linked. The easiest way to do this is using a makefile. The makefile does all the hard work for you, all you do is specify the name of your C files and any assembly files (must be called .S - case sensitive) and the processor you're using. This file goes in the same directory as your source code.

There is a good template here: http://electrons.psychogenic.com/modules/arms/art/8/AVRProjectOrganizationStandardizedAVRMakefileTemplate.php

I won't go through the process of writing a make file, the template above is commented and should be obvious :)

To actually compile your code into the .hex binary that your micro can understand, we just use the command prompt. Navigate to the directory you need using the "cd" command, replacing with the directory of the file. Then simply type "make hex" and press enter. What should result is a few lines of writing that you can ignore and a .hex file should appear in the directory with your source code. If anything went wrong, the compiler will spit out an error usually with a line number and the file that the error was in. You can then go to the line reference, fix the problem and try again. The code i provide here should be compilable, or at least compiles on my machine. I won't say bug-free because no code ever is!

I will try, if i can to give a run down of what the code does.  It is pretty well commented in my opinion so should be fairly self explanatory for seasoned coders. The code we'll be using is fairly complicated and deals with a lot of things that newbies want to know, dealing with input and output, interfacing with a display, using the ADC and Timer interrupts, sleep modes and more. It was a great primer for me at any rate =D

Ok, lets go onto your first program and try to upload it!

Step 12: Your First Program

As with all programming, lets do a basic "hello world" application just to make sure that everything works and that the AVR is set up ok.

We won't mess with external clocks, we're just going to make an LED blink on and off at regular intervals. The code is attached below and is called "led_blinker.c", also in the folder are the accurate delay library we need for this project and a makefile. You should edit your makefile to correspond to the chip you're using - if you don't, it won't work when you upload it!

Lets take a look at the code then:

#include "adelay.h"
#include < avr/io.h >

First we declare what headers/libraries we're using. All you need for this is the AVR in/out library and the accurate delay library.

//io init
void init_io(void)
{
//All Ouputs on
DDRC = 0xff;
}

This function is called at the start of the program, it takes no input and returns no values, but it sets up the chip ready for input and output operations. DDRD refers to the direction register, in this case, we set it to the hex value of 0xFF which is, in binary, 1111 1111. This sets all the pins on Port C to be outputs. It may seem odd to have just one command inside a function, but this will get bigger as we add more code.

int main(void)
{
init_io();

while(1)
{
PORTC ^= (1 << 1);
PORTC ^= (1 << 2);
Delay_ms(1000);
}
return 1;
}

The main function is really simple, first we call the init function to get everything set up. Then we enter an infinite loop (AVRs should never exit the main function). The next function uses bitwise operators, if you intend to do any programming for embedded devices, you should get familiar with this. A good tutorial is here:. What the code does, in a pinch, is toggles the on off status for Pin 1 and 2 on Port C.

For some reason instructables formats ^ = into an exponent sometimes, so apologies.  It also doesn't liked the < and > around includes (i guess it thinks it's a rogue html tag).

The Delay_ms(1000) function makes the program pause for 1000ms (or one second) and then continues.

So, it should be pretty obvious where this is going, there is an infinite loop (as while(1) is always true) and each time the loop iterates, it toggles the pin and delays a second, giving us a nice 1Hz blinker.

Use the makefile below, but rename it to 'makefile' first.

Next we'll send this to the programmer and upload it!

Step 13: Compiling, Uploading and Running Your Application

Navigate to the folder using command prompt/terminal and run "make hex" as described in the previous steps. You should now have a "program" called led_blinker.hex for your microcontroller.

Plug in the programmer to the computer.

Pop your microcontroller into its programming cradle, or connect up the pins as we talked about. There should be a total of six pins connected, RESET, MOSI, MISO, VCC, SCK and GROUND. Double check your wiring before continuing. You could do this on the breadboard, but i had difficulties getting the programmer to see the chip when i plugged wires straight into the ISP cable - though there is no good reason why this wouldn't work.

Connect your cradle/breadboard to the programmer.

If you're using a USBasp, then great! What comes next is extremely simple. Download a program called eXtreme burner: http://extremeelectronics.co.in/avr-tutorials/gui-software-for-usbasp-based-usb-avr-programmers/

You will also need the drivers for USBasp from here: http://www.fischl.de/usbasp/ go for the latest package. Unpack the data and you should find a folder called bin->win-driver. When the Windows eventually asks you what to do, select the option to install your own driver and point it to that directory. Unless you're on Windows 7 x64 where unsigned drivers simply don't work.

Fire up eXtreme burner and familiarise yourself with the interface. The array of F's in front of you is flash memory, where your program will be stored. The next tab along is the EEPROM, the extra memory on board the chip that you can log data to.

The third tab is Fuse settings, for the ATMega8, the fuses we will set are:

Low: FD
High: D5

This sets the chip up for a 4MHz external crystal, turns off clock division by 8 and enables BOD (brown out detection - if the voltage goes too low for some reason, the AVR can do funny things like randomly overwrite memory. Turning on BOD lets the processor stops the chip from going crazy and simply shuts it down).

http://www.engbedded.com/fusecalc/ is a good website for working out fuses

These values will differ if you're using a different microcontroller, use the application here to work out the fuses for you. The type of clock you want is:

Ext. Crystal Osc. : Frequency 0.3-8MHz, Start Up Time PWRDN/RESET: 16k CK/14 CK + 65ms

Uncheck "divide clock by 8 internally", ensure that SPIEN is checked otherwise you won't be able to program your chip ever again! You can set BOD if you want, but it's not essential. The fuses are shown at the bottom of the page, simply copy the values (hexadecimal) into eXtreme burner.

Select the chip menu from the toolbar and set it to ATMega8 - or whatever you're programming.  Set the mode to ISP.

Then open the hex file in the program, once you've done that, the Flash window should be filled with some numbers - this is your program!

Go to the write menu with everything plugged in and select Write->Flash. A window should come up and will give you little updates as it goes along. Through USB it should take around 8-10 seconds. If you get any errors, double check your connections and try again.

Once the program has been uploaded successfully, remove the chip from it's cradle and put it back on the breadboard. Plug in the battery or turn on your power supply and the LED we plugged in should be blinking at you!

Now you're familiar with how to upload applications we can pick up the pace a bit. The next thing to add to our application is a shoot function.

Unzip the code below.  You will need to modify your makefiles for each c file (editing which file it looks for, etc).  You will need it for the following examples, or you can simply build the entire device and use the final code - have a read, edit it, play with it to suit your needs!

Attachments

Step 14: Adding Infrared Output

We're going to connect our infra-red emitter to the micro in a slightly more complicated way than with the other LEDs. Because it draws so much power, we need to find use the circuit i talked about ages ago to power it. That would be the FET circuit (shown in the images below).

Now, the output pin is going to be PD0, or PORT D, PIN 7. In numerical pins, that is number 13. Locate it (it's the second from the bottom on the left hand side of the chip) so you know where to plug things into.

Next, take a look at your FET. Check the data sheet so you know which pins are Gate, Drain and Source. Plug in the FET across three rows on the breadboard. Take a wire and connect the gate (generally the middle pin, but check) to PD7, pin 13. When we tell PD7 to go high, the FET will start conducting.

The datasheet for the 2N7000, recommended, is included below.

Connect the source pin on the FET straight to ground.

Connect the resistor in series with the Drain pin. Then, connect the LED up to the 3V power rail, making sure to get the polarity the right way round (short legs are generally negative, but do make sure).

The resistor value was calculated based on the following assumptions:

1. We have a 3V power source going through a resistor and the LED to ground via a FET
2. The LED should have a current of around 60-80mA with a forward voltage of 1.7V (could be different for your emitter!)
3. Current is equal over all components in series
4. This means that to load 60mA and drop 1.3V over the resistor, we need a resistance of 22 Ohms. The FET provides up to 5 Ohms extra, so you could go with 18 or even 12 to get a higher current going.

With that all set up, we can start writing the code!

Step 15: Writing the Code

The code is, again, attached. There are two versions. One will work with Canon, one will work with Nikon.  Check in the folders, look for "Intervalometer Test.c".  Edit the makefile so that it looks for this c file when compiling.

The process is very much the same, however. We define some names for each pin so that the code is more understandable.

Then, we write the init function again, but this time we set all of Port D to be output and only one pin on Port C to be output - the LED we added last time.

Next, we write the actual shoot function. The premise is simple, each on/off cycle for the LED takes 26uS, we divide up the pulses into 26uS chunks and then repeat on/off cycles that many times. Pauses in-between pulses are just normal delays. The code is commented as to how the timings are worked out. The loops are just for loops.

The main program is pretty simple. We initialise our input/output. Then, we go into the infinite loop, turn on the LED (not status LED) and call the shoot function. We then turn off the LED and wait 5 seconds. This loop will repeat endlessly.

If you want a really really simple intervalometer, you just made one. Simply set the delay to whatever you need (there is a Delay_s function too) and the program will loop until you turn the power off.

Upload your code to the micrcontroller as before, remember to connect up the crystal/capacitors. Test out your program and check out the range. LEDs are pretty directional so you'll need to point it more or less normal to the camera's IR port to guarantee a picture at a longer range. At a right angle to the camera, i got about 2m range. Facing the chip head on i got around 5-10m+. This range will decrease somewhat outside, but it will still work if you hold the emitter close to the camera.

Next up, buttons.

Attachments

Step 16: Buttons

Now it's time to turn this into a proper remote, one that could replace your current one.

The buttons i bought were designed for PCB mounting, so whilst they fit onto the breadboard with a little encouragement, they need to have wires soldered on for the final board.

Somewhat strangely, buttons with four leads may have some interesting ways of making connections. Pins will connect diagonally, so an input at top left will give you an output bottom right. Pins on the same side will connect too. Pins opposite each other will not connect, however.

Wire one of the button connections into the PC3 pin (25). Use another wire to connecting the button to ground. This will be our shoot button.

The principle behind these switches is simple, with an internal pull up resistor enabled, the pin is set to logical 1 - there is an internal connection to VCC via a resistor. This connection also goes to the pin itself. When the switch is pushed, the electricity takes the path of least resistance and goes through the resistor and into ground - the microcontroller sees logical zero and says "something's happened".

If you're not going to use an external resistor connected to VCC on the pin, it is very important that you don't just connect up the button. You will leave the pin "floating", neither connected to VCC or Ground and that can cause lots of problems with false logic signals.

That's all you need to do to set the circuit up. The code "Remote Test" is fairly simple.

It is exactly the same as before, except we add some more functions and add the input, enabling pull-ups when we do so. When we set the Port as an input, using the DDR register, the PORT register then turns magically into a pull-up enabler. We write 1 into the required bit (for PC3) and that's done.

Next, we have a function for detecting button input, including debouncing (google for more info) the relevant pins to check it was a true button press.

It's worth pointing out that these codes are dreadfully inefficient for power consumption. It would be far better to sleep the processor when nothing is happening (i wanted to do this, but i didn't have the time to rewrite the code to compensate).

Upload the compiled program  to the microcontroller and try out your remote!
Next we're going to add in the LCD screen.

Step 17: LCD, the Intervalometer and ADC

Now we get to the fun bit.

You first need to solder some leads onto the LCD. It should have solder pads for the purpose and if you are careful, shouldn't cause you too much trouble. Don't take off the protective film over the screen, it protects against flux spattering and you may damage it if you take it off before you finish.

The pins on the LCD are as follows:

1 GND
2 VCC
3 Contrast
4 RS
5 R/W
6 E
7 DB0
8 DB1
9 DB2
10 DB3
11 DB4
12 DB5
13 DB6
14 DB7
15 LED+
16 LED-

Connect GND to ground, VCC will go to the +5V rail.

The contrast pin should go straight to ground too, though in many diagrams it's connected to a potentiometer (i've never seen the point).  It's worth mentioning that you should check with a resistor to see what value you need.  My red LCD is happy with ground, my blue LCD (the one i ended up actually using) required a small resistor.

LED+ should be connected via a 2.2k resistor to the +3V rail and LED- to ground. You can simply wire it straight to the voltage rail, however it will draw 30mA all the time. With a resistor in series, you will limit the current significantly - of the order of around 15-20x less - without much degradation in brightness (it's more than acceptable to use in the dark).

The LCD library uses a 4-bit interface, so we only need four pins. Thus we disregard the first four data pins and only use DB4..7. DB4,5,6 should be connected to pins 2,3 and 4. DB7 on the other hand will be connected up to pin 14. The reason for this is as follows: we need PD2 (pin 5) as an external interrupt pin*. On other microcontrollers such as the ATMega88, you can use (almost) any pin as an external interrupt, but this way you can use either the Mega8 or the Mega88/168.

You should then connect RS to PD6, pin 12 , R/W to PD5, pin 11 and E to PD4, pin 6 .

If you want to use different ports, look in lcd.h and change the definitions!

That's all you need for the LCD, now onto some more buttons. You're going to need to wire up another 5. These are mode and the four directional buttons. Wire up a button to each of pins 15-19.  The process should be the same as in the previous step, so i haven't provided needless pictures for each one.

Finally, load up and run the full application as provided in step 12/13.

When you run the program, you should be shown a "splash" screen and the the first shooting mode, manual triggering. To take a picture, press shoot (as before). Press mode to cycle between menu options. For the interval timer, you may set the value of each unit of time using the up/down buttons and switch between units using left/right - hopefully intuitive...!

The next section deals with the ADC (which should be enabled by the code below).

This is the code that will stay on your chip!

*In this revision i planned to use external interrupts but never did, however the code is still written for this pin configuration.

Step 18: Sensors

The code attached below will allow you to use the ADC to trigger your photographs. It requires no extra hardware (besides a wire going into the relevant port and some kind of sensor), only software modifications.

When you use mode to cycle through the options, you will be presented with one more - triggered shooting. The first screen displays a real-time readout of what the ADC is "seeing", this gives you a basic idea of what sort of values you're "hitting" and how changing the environment will affect them. Pressing the shoot button will let you set what the controller will trigger on. As the ADC goes up to 1024, the maximum you can enter is 1024. To the left of the numbers is the operator - you can set it to >( greater than), < (less than) or = (equal to). This allows a lot of flexibility with shooting, you can pick to take a picture when a light turns on or off, or if you are using a precisely controlled sensor (such as say a thermometer, god knows why) you can trigger from an exact reading.

I put in two LEDs on my controller to display whether the trigger is currently producing a match.   This has two benefits.  One, you can test out your sensors before you do the shoot and secondly you can avoid ambiguous conditions.  For instance, microphones will often fluctuate around some central value (because sound is effectively a superposition of sine waves - see fourier analysis).  This value is normally 512 ish on my ADC (as expected).  If you have two lights displayed, you can be sure that as soon as you shoot, it'll trigger.  If you have a red light only, then you can be more sure that you won't get a false shot.  And of course, a green light means that the condition is met so you should adjust accordingly.  With a sound sensor, adding a pot will let you alter the gain of the microphone so you can "filter" (you're changing the gain of the opamp) out quieter sounds.

Wire up an LED to pin 24 and another to pin 23 with a reisistor in series to limit the current.  Go as dim as you feel you need, low power is important.  I chose to have green on PC1 (23), red on PC2 (24.

Pressing shoot again lets you set a delay, up to 999ms (though you could always add in support for more). This is handy for taking pictures of impacts a few milliseconds after the event happens - creative control, you might say.

Pressing shoot a final time will set the device going. The ADC will update a bit more frequently and when the sensor gets a condition match, the preset delay starts and the picture is taken after that (with confirmation on the screen).

Sensors

There are two main sensors we can use. The first is light. This is terribly simple:

Connect a light dependent resistor or photodiode (faster reaction time generally) up to VCC and then in series with a resistor to ground. Connect a wire going from between the LDR and the resistor to the ADC input pin. Pick a resistor that matches the maximum resistance of your LDR (you can test it with a multimeter). You should end up with a value that ranges from almost 1024 to zero depending on the brightness of the light.  If you put the LDR and resistor in the right way round, the value should be zero when you cover the component and large when you shine a bright light - a laser gives a very high value that is roughly constant.

Some applications of this include things exploding, laser tripwires or (the most fun) lightning.

Sound takes a bit more fiddling. For the sound sensor, i used an electret microphone. Electret condenser mics are found in just about anything that has records sound. They pick up a wide range of frequencies so are pretty good for this. The only problem is that they typically produce an output signal that is far too small to detect by the ADC (minimum of 5mV). So, we need to amplify it.

There are a lot of circuits online dealing with electret amplification, however, the method i found to be most reliable was using an Op-Amp. The ideal opamp has unlimited gain, so don't worry about it not being able to amplify enough (the average opamp has an open loop gain of somewhere around 10 to the 8)! I built a really simple non-inverting amplifier using a TL072 (shown in the schematic). The resistor going from the output to the non-inverting input controls the gain. I tried a gain of 100 - little to no effect. Upping this with a 470k resistor (gain of 470) i got slightly better results, clapping fairly loudly triggered the sensor. Upping this to 1MOhm produced excellent (if perhaps a bit too sensitive) results.

Remember that gain is Vout/Vin, controlled by the ratio of GAIN_CONTROL/R1, so 1M/1k gives a gain of 1000.

What i recommend is buying a 1M potentiometer and a 100K resistor. Put these in series between the output and the non-inverting input. This will be the gain control. The 100k minimum resistance provides a decent starting point, triggering on loud sounds. By upping it to 1.1M, you get a much higher sensitivity - triggering from whispers and the smallest sounds (you may find that it's hard to actually trigger on high sensitivity unless you've got a really quiet room - my computer fans were enough to set mine off). By all means fiddle until you get a decent resistance range. Sadly it is quite hard to get potentiometers over 1M cheaply, but you can buy up to 5M if you really want to push it.

The opamp can be powered from the +5V rail (as can the electret) or from a separate 9V battery. Power the electret from the 5V line, you can use more but be sure to check the datasheet of your opamp to see what the maximum output voltage will be - you don't ever want to give an input to the AVR of more than 6 volts - and it is a waste to give anything over 5 anyway (since the sensor is only 10-bit).  Opamps have what is called a swing voltage, the range over which they'll produce an output.  This is normally the input voltage minus a couple of volts either end.  So, for me with a 5V power rail, i end up triggering on around 600-700 - the opamp simply doesn't produce a larger output.  This is where adjustable gain comes into it.

You should adjust the gain so that the condition LED you want only just turns off/on (say you want >600, you'd change the pot slowly so that the green LED just turns off).  This ensures you'll have a good chance of triggering properly.

Also, don't forget to put a resistor in series with the positive mic pin (between VCC). If you don't, you'll blow it.

You can simply copy the design below, shown as both schematic and breadboard. Other websites have reported much better results with a lot less gain, so take my results with a pinch of salt (i may be missing something obvious).  Fiddle and see how you get on, the circuit is a well known opamp circuit and feel free to experiment, this is just a quick and dirty amplifier.

Diagrams are provided below for both sensors.  Replace the GAIN_CONTROL resistor with a variable resistor or a potentiometer ideally.  The opamp is powered by the 5V rail.

C2 is a bit hard to see, but it is 100n.

If you wish to test the ADC separately, there is source code for it - however - the ADC will show you its current value when you load up the trigger menu anyway.

Step 19: Putting It All Together

You can choose how you want to build it, i highly recommend you just whack it on a bit of stripboard.

Very large schematic PNG (Eagle) - http://img8.imageshack.us/img8/8904/cameracontrollerschemat.png/4743/cameracontrollerschematm.png

I've uploaded the Eagle file too (for easier viewing), but it's not ready for PCB-ing, you'll need to double check components for correct sizing.

1.  Prep the enclosure (picture 1), masking out the top for easy drawing
2.  Cut out holes for parts (picture 2), very badly in my case
3.  Work out the layout of the breadboard, noting where you should cut tracks
4.  Solder on the two DIL sockets first
5.  Add a programming header if you want (makes life easier)
6.  Solder the crystal and capacitors
7.  Connect the programming header to the relevant pins and check if your computer "sees" the chip when you put it in the socket
8.  Solder the power supply components
9.  Solder the MOSFET and nearby components (note MOSFETs are very sensitive to heat, you should use a heat sink such as a crocodile clip (or even a paper clip) when soldering them)
10.  Solder wires onto all the buttons 
11.  Connect these wires to the breadboard in the appropriate locations
12.  Solder the LED to one end of the speaker wire (noting which side is  positive and which is negative.
13.  Solder the speaker wire to the 3V rail on the board and to the drain lead of the MOSFET.
14.  Solder a wire going into the ADC port and another to ground
15.  Solder two more wires for the status LEDs (and also solder the resistors for them)
16.  Solder the LCD to the stripboard
17.  Solder the battery box to the board
18. Attempt to fit all your components into your enclosure (i slighlty failed this part!)
19. Power on and see what happens!

You will probably encounter some problems, when i built this circuit, i realised i'd soldered in a much larger value resistor with the MOSFET and it took me a long time to notice (after i'd changed the FET twice, checked the LED, etc).  It is easy to make mistakes with this kind of thing (especially without a PCB that holds your hand with component placing).

Take special care when fitting everything in your project enclosure.  Mine is a very tight fit and i don't really like it.  It works and that's fine, but you need to really take time to work out what has to go in in what order.  I can't stress that enough.  You don't want to solder everything in, glue it down and then realise that you forgot to add some dreadfully important cable!

Now, i apologise i didn't go into more detail about this.  I have supplied a photograph of the breadboard i used and i hope to add a diagram of where everything was fitted.  The reason i am tentative is because i had to make a few changes (such as adding an extra resistor for the contrast of the LCD) and i'm not entirely sure it's as efficient as it could be.  With the schematic, it should be fairly simple to design a layout - especially if you breadboarded it first (given that stripboard and breadboard layouts are essentially the same with row connections).

Step 20: Sensor Applications

Sound

UPDATE: EDITED

A microphone is one of the most versatile sensor inputs in your arsenal.

The obvious idea of balloons popping and things breaking is, however, a little more complex.  Because a balloon bursts so quickly, camera lags are often too long to actually take the picture.  A prefocused D90 takes 0.07 seconds to shoot, wheras a balloon could be fully burst in under a millsecond (I am told by reliable sources).  How to get round this? 

a) Shoot it with something!  If you shoot the balloon with something travelling under the speed of sound, you can trigger instantly or one/two milliseconds after you get the trigger condition met.  Again you run up against the balloon popping a bit quickly...!

b) Rig up a flash and resort to bulb mode - i hate to do this because it adds complications like requiring a pitch black room to prevent overexposure - but if you add another wire out and some code to send a signal down it when you want to take a picture, you can fire the flash faster than your camera can open its shutter.  This is, i'm afraid, one of the only ways you can take these pictures until you can buy a camera with shutter lag under half a millisecond.  But, the controller is still capable - remember - you've got all the source code and schematics, modify and try it!

First note down the ambient value. Then, clap your hands and see how the value changes.  You can use the LEDs to assist you with this.

Set the ADC trigger value to be around your hand clapping value or slightly above (use the potentiometer to set the gain).

The delay is where you can be creative and you might need a little mechanics. If you set a short delay, or even zero, you will take a picture the instant the noise peaks.

Some other applications that you might not have thought of include sports. If you're taking a picture at a cricket/baseball match with a long lens, you can set the audio trigger up to fire precisely when the batter hits the ball. Set a delay of 10ms afterwards and you'll see the batter post-swing with the ball (hopefully) flying towards the edge of the picture.

The usual list of high speed photography subjects that can use a sound trigger are:

1. The classic, water balloon filled with water (tricky)
2. Things breaking (see balloons)
3. Guns firing or things being shot at
4. Popcorn (put it on a hot pan and wait for the pop!)
5. Anything else that makes a sound :)

Light

NOTE: The pictures below were all taken using the controller and the circuit i mentioned in an earlier step.  Delays were set from around 20ms to 150ms.  I didn't have a proper rig so apologies for not knowing exact timings - it'll vary on your setup anyway.  Note to self, by a pipette or dropping bottle!


Light is where we can be a bit more inventive.

One idea is to shine a laser pointer at an LDR. What you've just made is a simple tripwire. You could use it to take a picture when someone enters a room, when your dog eats its dinner. You could even put it outside and take a picture when a bird sits on your bird table (though this is better done with an infrared or ultrasound motion sensor).

Another application for the above is quite nifty. Ever wonder how people get those lovely pictures of water droplets hitting the surface of a pool? Well, if you set up your laser and your LDR so that the beam shines through the path of some droplets, it's a simple matter of aiming your camera at the surface of the water, focus it manually and then set the trigger to fire when the beam is broken. When the water falls through, the light will diffract and scatter and your camera fires. You then calculate how long it'll take the beam to fall and you set the delay accordingly.

Next is lightning. Now, with a fast LDR or even better, a photodiode (though these cost a bit more), you can take pictures of lightning strikes. When the lightning flashes, you have a small window in which to take your picture. Prefocus the camera on infinity and point it at the horizon, you don't want it trying to focus when you take the picture. Lightning strikes in a specific way, there is first a stepped leader, from the cloud to the ground. Then, the main visible part of the lightning, an upward stroke along the same path. After that there are normally a couple of extra discharges and the whole process takes around a tenth of a second.

The D90 that i have has a shutter lag of around 63ms pre-focussed. What this means is that if you stop your aperture down to say f/10 and take a 1 second exposure when the trigger sees lightning, you should get the shot. Provided the shutter lag is under 100ms, you'll hopefully get it. Don't bother about putting delay, the shutter will be open for plenty of time.

One thing i almost forgot about was fireworks. No longer do you have to guess when to take the shot or pray on bulb that everything will work! Simply point your LDR to the sky, wait for the flash, set a reasonably long delay - most fireworks will linger for a second or so, perhaps 100ms to allow the explosion to fully expand - and then take a second or two's exposure. Hey presto - instant gratification =D With Guy Fawkes' night approaching fairly soon in the UK, i'll be sure to try this one out. You could trigger this with sound, but it's unlikely to be as good unless you're very close to the explosion due to sound being pretty slow.

Ultrasound

Ultrasound sensors can be used to create distance or proximity modules based on the time it takes for an ultrasound pulse to return from a reciever to a transmitter.  This generally needs to be done in software, so would either need a separate controller  - perhaps an ATTiny45 or an ultrasound module like this one: http://www.rapidonline.com/Electronic-Components/Sensors/Ultrasonic-Sensors/Ultrasonic-range-finder-SRF05/82276.  Going the DIY route is by far cheaper!

The Tiny45 does have a PWM controller to produce an "analogue" voltage signal which you could use, or it could just send out a single pulse.

This could be used as a much more effective way of taking pictures of things going past than a light sensor.  Applications include macro wildlife photography (say of birds when they sit on the bird table) or security.

Odd sensors, temperature and float

You could do some odd things like take pictures when things overheat, when things overflow - hey, it's your imagination not mine!

I've seen some awesome pictures online of some other light triggered pictures including a lighter being flicked on. You could expand this theme with a match being struck in the dark.

More choices! And the LDR is cheap and easy to implement as well =D

Logic Levels

The most versatile option is adding a connection from an external circuit.  Sending a logic level one or zero will work as a trigger input.  This gives you infinite flexibility.  You can add a really complicated circuit that will provide a "shoot" logic level based on a combination of lots of sensors rigged up to each other.  The possibilities are endless!


A side note on water droplets:

This video is an excellent example of the formation of a perfect droplet.  You can see the stages in my uploaded photos too.  First the drop impacts, creating the "crown".  This quickly decays into a more globular structure forming a concave indent on the surface.  A secondary drop is then projected upwards (in a kind of 3D parabola - sombrero type shape) if the initial impact was large enough.  This is in the fourth picture below.  Finally this subsides and you're left with a slightly disturbed surface.

It's a good way of picking the shots you want.  Clearly, the ideal moment to take a picture is about 10-20ms after the droplet hits the water.  The crown decays rapidly so there's only a small window to take the picture.  If you don't want to involve trial and error with this, you MUST drop the water from the same height every time with similar sized droplets - otherwise altering the decay has little effect.

http://www.youtube.com/watch?v=RU376Bo__60

Step 21: Using the Controller

I won't insult your intelligence by explaining the manual shoot option!

Shoot = Ok/Shoot
Mode = Change Mode/Back

So if you're in a submenu like setting a delay, you can press mode to return to trigger condition setting.

One thing i forgot to mention!  If you are in interval shooting, the screen will go blank after 5 seconds of inactivity.  Holding any button except shoot will display the shooting status.  If you hold down shoot for a second or two and release, the interval shoot will be cancelled.

Time lapses look cool, but they're tricky beasts to master.  When thinking about time lapses, you should consider how fast the scene is going to change.  If you're taking pictures of stars panning across the sky, you probably want around 10 second intervals (with 4 second shutter, mid-high ISO, large aperture, etc).  If you're taking pictures of plants growing, perhaps every 5-10 minutes would be better.  Some excellent time lapse films can be made by constructing a stroboscope (flashing lights) to "slow down" some fast moving, periodic action.  The result is often amazing because you can take pictures of water droplets falling and splashing in slow motion, clock mechanisms firing, that kind of thing.

Whilst i added the option of up to 9 hours interval timing, Nikon cameras have an annoying feature of turning off the remote function after a maximum of 15 minutes of use.  In practical terms this means you can't take time lapses (at least on a D90) with intervals of more than around 14m50s (to play safe).  On the plus side, with camera memory sizes being huge these days (i get 500 RAWs on an 8GB card), you can afford to take more pictures than you need.  More pictures will simply give you a smoother picture anyway!  If you need reallly long intervals, you can probably do it by hand or you could wire the controller to the camera (just change the shoot function to suit your needs).

Now, having power management options would be really handy here.  It would certainly be a boon to be able to dial down your current consumption when the device is idle - and you should definitely consider changing the source code to do it.  I plan to release an instructable some time later with updated code/hardware.

With the trigger, it's up to you.  I'll give you one application - the laser trigger.

Mount a laser in a clamp, or duck tape it to something so that it points on your LDR - which is plugged into the controller.  You should see a value (~800-1024) that is fairly static.

Point your camera at a bowl of water below the beam.  Measure the distance from the surface of the water to the beam (a ruler is fine for this).  Everything (in theory) falls at the same rate, depending on surface area and so on.  Using basic mechanics you can work out how long a delay to dial in depending on the height that the thing you're dropping will fall through.

s = sqrt(2a*s_init)t + 1/2 at^2 will do you nicely.  s is the distance, u is the initial velocity, a is acceleration and t is time. s_init is the height that the object falls before it hits the laser (determines the "initial" velocity as it hits the laser).

In any case, solve this equation for t and you should have a pretty accurate idea as to when your object will hit the water.

This is overcomplicating, you could do it by trial and error if you wanted, and you should definitely play with the numbers so you get different images each time.  The only thing you need to do is make very sure that you drop your object from the same height each time.

When the object breaks the laser beam, the adc will trigger, the delay will wait until the object has just impacted the surface of the water and your camera *should* take a picture of it.


Step 22: Improvements and Conclusion

For my first real project in electronics, i was really pleased with this.  I had a lot of problems along the way - many of which aren't documented - but which meant i couldn't put in this or that picture/code snippet.

Some improvements i'm going to make on the next revision:

1.  Power management, i'm disappointed about this one, but i'm going to make sure i can idle everything when i need to.
2.  Add a 3.5mm jack to recieve input from sensors.
3.  Add a proximity sensor perhaps using ultrasound, this would be an externally controlled module.
4.  CNC/Laser cut the box so it doesn't look like an idiot made it =P
5.  Put in a red LCD rather than blue
6.  Add a MOSFET or switch for backlight control
7.  PCB!

And general software improvements of course...

If i missed anything vital out, please for god's sake tell me!  I apologise if it wasn't too easy, but hoepfully you have a good idea of how camera controllers can be built easily and cheaply.

All the best,

Josh

(If you're interested, i'm currently in my 2nd year of an undergraduate physics degree at sunny Warwick University, GB)

Digital Days Photo Contest

First Prize in the
Digital Days Photo Contest