Building a DIY Focus Stacking Controller with Arduino

Table of Contents

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.

Warning: it is possible to damage your camera if you make wiring errors, or if the connection to your camera inadvertently makes contact with any other traces or components. Be sure to build this project with care and use good quality, insulated connections. Test the output to the camera (without the camera attached) to be sure that it does not produce any significant voltage or current.

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.

Required Parts 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. Resistors (1/6 W) 1x 330Ω, 1x 1KΩ, 5x 10KΩ 7 $0.35 Voltage dropping resistors for the LCD IR receiver TSOP 38238/38338 (inexpensive options), SEN-08554 Sparkfun IR receiver breakout board, many other options 1 $1.50 - $10.00 Other 950nm 38KHz IR receivers should also work. Just make sure your choice will run on 5V. Reed Relays Hamlin HE3621A0510 2 $6.00 Nominal 5 V coil voltage, coil current of 35 mA or less. You can also use optocouplers with the appropriate current limiting resistors. IR remote Kenwood RC-P400, Samsung AA59-00666A, programmable remotes, many options 1 ~ $5.00 - $15.00 Needs to use either the NEC or Sony SIRC protocol. 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.

Optional/Conditional Parts 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 IR receiver sends a digital signal that triggers pin change interrupts 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 3.3V either directly from 3.3V power pin on the Arduino, or from the 5V power pin a voltage dropping resistor. 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 perhaps too small for this project, and it is a tight fit. Although I was successful in making the project fit into this case, it leaves very little room for expansion or modification. I recommend that you use a more roomy enclosure. There are many options here, including store-bought project boxes, plastic food containers, wooden boxes, and 3d printed enclosures. 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, but you can use my own build to guide you. My choice to use the SparkFun Arduino Project Enclosure 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. The UNO only has one 5V pin and it's being used by the motor/camera controller boards, so this cable sends power to the LCD screen and IR receiver.



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 is that it's behind a polarity protection diode which has a max current of 1A. The lead-free solder pads required a fairly high temperature iron to rework, but I couldn't think of a better way to directly access the power supply yet still fit everything into my case. In a roomier case, I recommend making a Y-splitter cable to send power to the UNO and the motor/camera controller boards without having to solder wires to the UNO.

The LCD screen requires a logic and supply voltage of 3.3V, but the Arduino UNO's I/O 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. To supply +3.3V to the Vcc pin, you can use the Arduino UNO's 3.3V power pin. Or, you can connect Vcc to 5V with a 270 Ohm voltage dropping resistor.





The backlight (connected to the LED pin) has a max current rating of 80mA but will operate on far less. I recommend a 330 Ohm resistor between the LED pin and digital out to limit the current. While that does result in a dimmer backlight, it is still perfectly visible and I feel better knowing that I am not drawing too many mA from a digital out. Using a transistor to supply up to 80mA to the backlight (don't forget a current limiting resistor) will get you a brighter backlight if you feel that it is 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.

The IR remote receiver library I developed supports eight different remote protocols, which includes the most common protocols currently in use. Chances are very good that you already have a remote that will work. Select a remote with at least 19 buttons suitable for digits 0-9, up, down, left, right, enter, back/cancel, half press (focus), shutter release, and backlight toggle. You will have to edit some constants in my code (don't worry, it's easy) to map your remote's buttons to different actions.

First, you need to select the correct protocol for your remote. You can either figure this out through trial and error, or you can use the approach I describe in the IR library documentation. The brand of your remote may give you a hint as to the protocol. Try the SIRC protocol for Sony remotes. NEC, SIRC, RC5, and RC6 protocols are the most common.

Once you have figured out your remote's protocol, you can upload the stacking software to your project and use the "remote test" screen to figure out your button codes. This process is described in the user manual. You can freely map any of your remote's buttons to the various actions, but be sure that each button is used for only one action.

I have pre-supplied button codes for a Kenwood RC-P400 (DPC-731 or DPC-531 portable CD player), Samsung AA59-00666A (Samsung UN39EH5003F LCD TV), and Sony Bravia KDL-55HX850 TV. If you have or purchase one of these three remotes, 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.

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.

After installing the necessary libraries below, use the Arduino IDE to upload the main stacking software to your microcontroller.

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.