Focus stacking (or z-stacking) is a technique for increasing the depth of field in macro and microphotography. This is done by taking many shots (slices) at sequential focus points and combining them into a single image using software. Automation can reduce vibrations and tedium, and this is relatively easy to do with a stepper motor, some reed relays, and a controller. Here, I provide schematics, software, and notes for building your own focus stacking controller. It's easier than it looks!
A number of instructional videos for this project have been created by Eyesore Industries and are available on YouTube. I cannot guarantee that they will be kept up to date as I continue to revise this project, but even if not, I am sure these videos will continue to be a useful supplement to this article.
This stacking controller uses a monochrome LCD screen, and is controlled with an IR remote which permits a more compact and expandable project. It operates in two main modes. In position mode, you can move the focusing rack back and forth, take pictures, and set the "start" and "end" positions which define where a stack will begin and end. In the stacking mode, you set various parameters that alter the stacking behaviour, and then begin the stack. The device moves to the first slice position, stops, take the shot(s), advances to the next position, and so on until the stack is complete.
You do not need to do everything exactly as I have done. The choice of a different project box, for example, will lead you to make different layout and wiring decisions. If you change anything that affects how the controller functions, you may need to modify the software.
For my build, I purchased components from SparkFun, DigiKey, eBay, and Newark and tried to use common, inexpensive components. I can't promise that the suggested parts will remain available in the future, but there are always compatible alternatives. Prices are only estimates current to 2012, and do not include shipping.
|Component||Suggested Part||Qty||Approx. Extended Price (USD)||Notes|
|12 V bipolar stepper motor||Portescap 44M100D2B (low torque), Mercury Motor SM-42BYG011-25 (higher torque), many other options||1||~ $15 - $30||Use a 7-12V bipolar stepper that draws 600mA or less per winding. Do not exceed the voltage and current limits of the quad half-H-bridge. For more guidance, see the stepper motor notes.|
|Quad half-H-bridge||L293D||1||$3.50||The L293D supports steppers with up to 600mA per winding (1200mA in total) and includes internal output clamp diodes. This is quite a bit of power for this project since fine focus knobs turn easily.|
|8 bit shift register||74HC595||1||$0.60|
|Arduino microcontroller||Arduino UNO||1||$30.00||You may use different Arduino boards or even just the ATmega chips, but if you do, small tweaks to the circuit and code may be needed.|
|LCD screen||Nokia 5110 monochrome LCD||1||$10.00||Available from sparkfun.com and eBay.|
|1kΩ Resistor (1/6 W)||Flexible||1||$0.05||Voltage dropping resistor for the LCD's SCE pin|
|10kΩ Resistor (1/6 W)||Flexible||1||$0.05||Voltage dropping resistor for the LCD's data pins|
|IR receiver||SEN-08554 Sparkfun IR receiver breakout board||1||$10.00||Available from sparkfun.com.|
|Reed Relays||Hamlin HE3621A0510||2||$6.00||Nominal 5 V coil voltage, coil current of 35 mA or less.|
|IR remote||Kenwood RC-P400 or Samsung AA59-00666A||1||~ $5.00 - $15.00||You can probably use a remote that you already own. See notes on the IR Remote.|
|7-12V DC power supply||Flexible||1||$6.00||Pick a DC supply with a 2.1mm center-positive barrel connector. It must satisfy the Arduino's requirements (7-12V), as well as provide adequate voltage and current to drive the stepper motor at the desired torque. Add up the current draw for all parts and make sure the supply can satisfy it.|
|Project Box||SparkFun Arduino Project Enclosure||1||$12.00||You can save money by using whatever containers you have lying around, or build your own enclosure.|
|2.5mm Stereo Headphone (TRS) Female Jack||CUI Inc SR-2501||1||$2.63||Used for connecting to camera shutter release cable. Panel mount or Free Hanging is easy to work with.|
|4-pin Female Mini-DIN connector||CUI Inc MD-40J||1||$2.00||Used for connecting to stepper motor. Other types of connectors can be used.|
|4-pin Male Mini-DIN connector||CUI Inc MD-40||1||$2.00||Used for connecting to stepper motor. Other types of connectors can be used. These can be cannibalized from standard S-video cables.|
|Shutter Release Cable||1||Some cameras use 2.5mm stereo headphone cables. Others have proprietary cables. See notes on the camera connection.|
|Breadboard||Stripboard||As needed||$5.00||If using stripboard, go with 0.1" pitch and be sure it actually has strips and not just pads!|
|Female headers, straight||PRT-00115 (from sparkfun.com)||As needed||$1.50||0.1" pitch, square pin. You can cut these to size with wire cutters, although you lose a pin in the process.|
|Break away male headers, straight||PRT 00116 (from sparkfun.com)||As needed||$1.50||0.1" pitch, square pin.|
|Component||Suggested Part||Qty||Approx. Extended Price (USD)||Notes|
|9 position top actuated SPST DIP switch||CTS Electrocomponents 209-9MS||1||$1.30||May replace with multiple DIP switches or 10 position switch if 9 position switch cannot be sourced.|
|Heat sink for the Quad half-H-bridge||Aavid Thermalloy 501200B00000G||1||$1.00||Highly recommended. Many products exist for attaching heat sinks to chips. I used thermal epoxy, but that has the drawback of being fairly permanent.|
|3-pin Polarized Connector (Male Header)||PRT-08232 (from sparkfun.com)||1||$0.45||Useful for a reversible connection to the 2.5mm stereo microphone jack.|
|3-pin Polarized Connector (Female Housing)||PRT-08096 (from sparkfun.com)||1||$0.45||Needs to mate with the above. Useful for a reversible connection to the 2.5mm stereo microphone jack.|
|4-pin Polarized Connector (Male Header)||PRT-08231 (from sparkfun.com)||1||$0.45||Useful for a reversible connection to the 4-pin mini-DIN jack.|
|4-pin Polarized Connector (Female Housing)||PRT-08097 (from sparkfun.com)||1||$0.45||Needs to mate with the above. Useful for a reversible connection to the 4-pin mini-DIN jack.|
|Crimp pins for the above polarized connector housings||PRT-08100 (from sparkfun.com)||1||$1.95||Useful for reversible connections between the circuitry and panel-mount jacks.|
|22 to 25 AWG hook-up wire, stranded and solid, different colors (at least red and black)||Length depends on need||I assume you already have wire, so have not included a price.|
|Heat-shrink tubing, various sizes||VERSAFIT-KIT-6-0 or SparkFun PRT-09353||Depends on need||$8.00 - $10.00||Optional, but good for insulating connections.|
When a button is pressed on the remote control, the Sparkfun IR receiver breakout board sends a digital signal through the Out pin to interrupt 0 (digital pin 2) on the Arduino UNO. These signals are interpreted and allow the user to interact with the stacking controller. A user interface is provided on the Nokia 5110 LCD screen, which is attached to the Arduino's digital pins 8 through 13 and receives power from the 5V power pin. The Arduino controls the L293D (stepper motor controller) and Hamlin HE3621A0510 reed relays (for triggering the camera shutter) via an 8-bit shift register attached to digital pins 3 through 5.
The shift register's first two bits enable or disable the two pairs of half-bridges on the L293D. When the half-bridge pairs are disabled, the associated stepper motor winding is effectively disconnected from the circuit. The next four bits of the shift register set the polarity of power supplied to the stepper's windings. The stepper can be moved in either direction using full-step or half-step resolution. Full-step resolution provides more torque, but movements are coarser. While the L293D itself operates off of the 5V regulated supply from the Arduino, the VS and GND pins must be attached directly to the power supply to avoid drawing too much current through the Arduino. Pins 4, 5, 12, and 13 of the L293D are connected together and act as a heat sink in addition to ground pins.
The last two bits of the shift register control the half-press and full-press reed relays, respectively. The half-press relay (Rel1) completes a circuit over the shutter release cable that triggers the half-press mode of the shutter release, which usually functions in auto focus and auto exposure and keeps the camera in a ready-to-shoot state. The full-press relay (Rel2) triggers the camera shutter.
Prior to laying out a breadboard or PCB, soldering, and selecting an enclosure, I recommend building this project using jumper wires and a solderless breadboard for ease of troubleshooting.
The SparkFun Arduino Project Enclosure showing the arrangement and fit of all components.
The SparkFun Arduino Project Enclosure is just about the smallest enclosure that this project will fit into, unless you use custom PCBs and surface mount components. There are many options here, including store-bought project boxes, plastic food containers, scavenged enclosures from deceased electronics, or even completely DIY approaches. If you use an opaque box, be sure to cut windows for the LCD screen and IR receiver. The size of the window needed for the Nokia 5110 LCD screen is 1.32" x 0.85".
The inside of the lid of the SparkFun Arduino Project Enclosure showing the LCD window, cabling for the stepper motor and camera connectors, and the male headers for the IR receiver.
The breadboard layout is entirely up to you. My choice to use the SparkFun Arduino Project Enclosure dictated a maximum size that required me to split the board into two halves, as shown below, using stackable headers to connect the two boards. This would not be necessary for more spacious enclosures.
Illustration showing the layout of the stepper motor and camera controller boards. These layouts are based around stripboard, and the gaps show where the copper traces must be cut or ground away. Note that this is for single-sided stripboard, with through-hole components on one side, soldered to copper traces on the other side. Test all trace breaks to ensure no conductivity across them.
A photo of the stepper motor and camera controller boards. Although difficult to see in these photos, the "top" board (the camera controller board) uses male headers that stick out below the board, which insert into the female headers on the bottom board. Note the "power supply splitter cable" from the stepper controller board. Because the UNO only has one 5V pin that is being used by the motor and camera control circuit, this cable sends 5V and GND to the LCD screen and IR receiver. A direct ground to the power supply is necessary to sink potentially high current used by the L293D when driving the stepper (the Arduino UNO is limited to 400mA). It was convenient to use the power supply ground for the other components as well, to avoid yet another wire running to the Arduino.
I soldered wires directly to the Arduino UNO's power supply jack to provide a high current supply to the motor and camera controller boards. The reason you can't use the Arduino's Vin and GND pins is that the Vin pin is behind a polarity protection diode which has a max current of 1A, while the GND pins can only sink up to 200mA each. The lead-free solder pads required a fairly high temperature iron to rework, so you might want to avoid this particular method unless you have worked with lead-free solder before and can solder quickly.
The LCD screen requires a logic voltage of 3.3V, but the Arduino UNO's pins are at 5V. Based on SparkFun's recommendations, I have used 10k voltage dropping resistors for all logic pins except for SCE, which uses a 1k resistor. These resistors are spliced directly into the wires running from the LCD to the Arduino. Since the LCD uses low current, you can use lower gauge wire here, which is more flexible and takes up a bit less space.
The backlight (connected to the LED pin) has a max current rating of 80mA. I have had good luck powering it directly from the digital out pin of the Arduino (40mA). Using a transistor to supply the full current to the backlight (don't forget a current limiting resistor) will likely get you a brighter backlight, but I don't consider this necessary. Because the backlight is connected to pin 13, which pulses high when most Arduino models start up the bootloader, you will see the LCD's backlight pulse on twice when first plugging in your controller. This is completely expected behavior and is an indication that your Arduino is working correctly.
In my layout, the power supply cable for the LCD has a small board spliced into it which provides a female header for attaching the IR receiver breakout board, as well as a cable (in white above) that connects the IR receiver's output to the Arduino.
You can solder wires to the pads of the IR receiver, but in my build I soldered in a 3-pin male header so that the pins stick out behind the receiver. My IR receiver plugs into a small power supply splitter board that you can see in the photos above. The VCC and OUT pads on the IR receiver should be connected to the Arduino's 5V pin and digital pin 2 respectively. The IR receiver's GND pin can either connect to one of the Arduino's GND pins, or directly to the supply ground. In my design, it connects to the supply ground.
Be sure that the IR receiver can "see" (don't put it inside an opaque project box). It either needs to be mounted on the outside of your project box (this is what I did) or given an IR-transparent window through which to see.
You can use almost any remote with buttons suitable for digits 0-9, up, down, enter, motor foward, motor reverse, seek forward, seek backward, start, stop, menu, shutter exposure lock, shutter release, and backlight toggle. To keep this project lightweight and responsive, the IR receiver code is extremely simplified compared to available IR libraries. It should work with most remotes, but there are some types of protocols that it simply won't work for.
I have included the timings and codes for a Sony TV remote (widely compatible with various Sony remotes), Kenwood RC-P400 (convenient size) and Samsung AA59-00666A (easier to find and has more buttons). If you have any of these remotes or purchase one of them, simply uncomment the relevant code in the stacking software prior to uploading it to the Arduino. If you have access to a programmable remote, you can set it for a Sony TV (e.g., KDL-55HX850) or Samsung UN39EH5003F LCD TV and use the provided codes.
Different remotes are still reasonably likely to work, so consider giving a remote you already own a try before buying a new remote for this project. To figure out the button codes, attach the LCD screen and IR receiver to the Arduino as explained in this article, then upload the IR remote decoding sketch provided below. Once you see "Ready" on the LCD screen, press a button on your remote. A button code and a bit count should appear on the LCD screen for each button pressed. Write down the button codes and bit counts associated with each button you want to use and make sure that the button codes are all different. My anecdotal experience is that this procedure worked flawlessly with three out of the four remotes I had around the house.
In the stacking software, set REMOTE_MINBITS to the lowest bit count you observed and REMOTE_MAXBITS to the highest bit count you observed. Copy over the same timings (REMOTE_HIGHMIN, REMOTE_HIGHMAX, and IR_TRIGGER) that worked in the IR remote decoding sketch. Finally, decide which buttons you want to use for each function, and copy over the relevant button codes for each of the BT_ defines.
If no button codes show up or if button codes are not unique, your remote may work if you adjust REMOTE_HIGHMAX, REMOTE_HIGHMIN, or IR_TRIGGER. To do so, you will want to either attach the IR receiver to an oscilloscope, or use the Arduino itself to analyze your remote's protocol. One way is to use this Arduino IR Remote library and run the IRrecvDump example to identify your remote's protocol. Then, consult this IR Remote knowledge base to learn more about the protocol. With this information, you might be able to modify my software to get your remote to work.
Unless you've made changes to the circuit, you will want a 7-12V bipolar stepper motor with four leads that draws 600mA per winding or less. You can also use many six-lead unipolar steppers by leaving the center taps unused and treating the motor as a bipolar stepper. I recommend getting a motor with 3.6 or 1.8 degrees/step, which I've found to be a good compromise between precision and speed. When buying, pay close attention to torque, degrees per step, and resistance per winding (determines current). The motor should not exceed the voltage and current limits of the quad half-H-bridge.
To avoid heat issues, use the least powerful motor that will do the job. If a powerful stepper is used, this may warrant a different case and more robust heat sinks to avoid damage to your project. Connecting the heat sink/gnd pins of the L293D to a ground plane with high surface area is ideal. You can also attach a heat sink to the top of the chip with thermal paste or thermal epoxy.
To figure out how much current your stepper will use per winding, just use Ohm's law: current (A) = voltage (V) / winding resistance (Ω). You can reduce the current draw by supplying the motor with less than the rated voltage. For the Portescap 44M100D2B at 12V, that is 12V / 70Ω = 171 mA per winding and 342 mA peak (when both windings are on). For the Mercury Motor, this is 368 mA per winding, and 736 mA peak. I have used both of these motors without experiencing heat issues. I often run these motors at 9V instead of 12V.
One way to put a weak motor to good use is by gearing it down. You can do this with gears, or with timing pulleys and belts. Put a smaller gear or pulley (fewer teeth) on the motor, and a larger gear or pulley on whatever you want to turn. This will increase the motor's effective torque and decrease its step size. If the gear on the stepper motor has half the number of teeth as the gear on the focus knob, this will approximately double the torque and halve the step size. You can also get stepper motors with built-in gearing.
I recommend wiring your stepper motor to a 4-pin male Mini-DIN cable (S-video cable). Figuring out the wiring of a known stepper motor is as easy as consulting the data sheet. There will be two windings in your bipolar motor, in this project referred to as "A" and "B", and each winding is connected to two wires. The wires are then labelled A1, A2, B1, and B2. A1 and A2 are on the same winding and have opposite polarities, while A1 and B1 are on different windings but have the same polarity. If you can't find a data sheet, attach two wires at a time to an ohmmeter and test the resistance across them. Two wires connected to the same winding will have a relatively low resistance across them, while two connected to different windings will have extremely high or infinite resistance. This tells you which wires are paired to the same winding. Arbitrarily call one pair "A" and the other pair "B". Next, figure out the polarity of each wire. This might require trial and error until the motor moves properly, so use temporary wiring to start with. If the motor moves oddly but you have correctly paired the wires, reversing the polarity of a single pair of wires should correct the issue. Label one pair of like-polarity wires "1" and the other "2". You should now have four leads labelled: A1, A2, B1, and B2. Wire these to the Mini-DIN cable such that, once connected to the female jack, they will complete a circuit with the matching outputs from the L293D.
Attaching the stepper motor to the knob of your focussing block, microscope, or linear stage can be done in many ways. You can use timing pulleys and timing belts, or direct couplings.
To connect to your camera, you will need a cable with a 2.5mm stereo TRS ("headphone") plug on one end, and the necessary camera-specific attachment on the other end. Some cameras use standard TRS jacks, allowing you to use audio cables from electronics retailers. Other cameras use proprietary connectors, requiring you to splice cables together. You can get inexpensive camera remotes from eBay, snip the cables off, and splice them to 2.5mm stereo headphone cables. If you leave some cable on the remote, you can attach a female 2.5mm stereo jack to it and use the remote as intended by plugging your spliced cable into it.
There should be three wires in the shutter release cable. One of them is a ground, and the other two wires will trigger either the AF/AE lock mode (half press) or the shutter (full press) when connected to the ground. By trial and error, you can quickly figure out which wire is which. The ground wire attaches to pin 4 of both relays, the AF/AE lock wire attaches to pin 1 of Rel1, and the shutter release wire attaches to pin 1 of Rel2. Ground yourself before handling bare cable/jack while it's plugged into your camera, and be sure not to accidentally connect it to a power supply. Improper handling could damage your camera!
I added a DIP switch that allows you to completely re-arrange the wiring of the shutter release cable by just flipping a few switches. So far this has been an unnecessary feature as I have only used Canon cameras, but I thought it was nice to have this feature just in case. You can easily omit the DIP switch and directly wire the shutter release cable to the relays. If you get a different camera in the future, you can always splice a new cable.
Once you have assembled the hardware, download the main stacking software below and use the Arduino IDE to upload it to your Arduino board. If you are using your own choice of remote, the IR remote decoding software will help you to figure out the remote's protocol and button codes.
Older versions of the stacking software:
Main Stacking Software Rev. Jan 14 2015
Main Stacking Software Rev. Feb 23 2014
Main Stacking Software Rev. June 11 2013
Main Stacking Software Rev. Jan 27 2013
Main Stacking Software Rev. Dec 13 2012
Main Stacking Software Rev. Dec 11 2012
In the future, I plan to expand this project with features for doing timelapse photography with a moving camera platform, as well as the control of a barn-door equatorial mount for astrophotography. These future expansions should not require circuitry changes, but only new versions of the software. You can also alter the software as you see fit, giving you the power to make this device accomplish many things beyond its original intent.
I owe the community at photomacrography.net many thanks. The members of this web forum have been an amazing source of feedback and inspiration on numerous projects that I have undertaken. The photomacrography.net community has greatly increased my enthusiasm for macrophotography, and without this enthusiasm, this project likely would not have happened.
I must also thank the Arduino community for its dedication to open-source, DIY culture, and information sharing. Similar remarks are directed at the SparkFun community, and the DIY community as a whole. The internet is absolutely full of articles on microcontrollers, stepper motors, and the like. Without this information to help me, I would not have succeeded with this project.