Introduction: Easy Build Focus Stacking Rig

    • Repurposed 3D printer parts and Arduino based FastStacker software enable simple and inexpensive build of full featured focus stacking rig.

    Sergey Mashchenko (Pulsar124) has done a great job of developing and documenting a DIY Arduino based focus stacking rail as described on his wiki ( Many people have built his project and as he notes on his wiki, his project has been widely discussed in relevant forums. I recently completed a version of this build myself as I document in a comment on his wiki. I built a controller around Pulsar124's design using an Arduino, keypad, stepper driver, and a Nokia 5110 LCD display. There was a good deal of soldering involved and the old stock LCD was very problematic. The forums showed others having issues with the LCD as well. The software of Pulsar124's project is very nice. It is mature and full featured and I wanted to make it easier to build a system that uses it. I ported his software to run on a 3D printer control platform consisting of an Arduino mega, a RAMPS 1.4 shield, and a full graphics smart controller LCD panel with associated cables. I provide that software here with instructions for putting the stacker controller together that it runs on. For the rail itself, instead of starting with a commercial Velbon rail as in the original project, I designed a simple 3D printer based rail which I also document here. I take no responsibility for this code or design if anyone messes up their camera or anything else.


    Stacker Controller

    The following parts are sold together very inexpensively as a "3D printer kit" or "RAMPS kit" but you may purchase them individually or scavenge them from an unused 3D printer.

    • Arduino mega
    • RAMPS 1.4
    • 1 stepper driver (the kits usually come with at least 4)
    • Full Graphics Smart Controller LCD display with connector board and ribbon cables. If buying, pick one with an onboard potentiometer for backlight level control.
    • header jumpers for configuring stepper driver
    • repRap style limit switches and associated cables

    Also required for the controller:

    • 4x4 switch keypad
    • voltage divider parts
      • 150K resistor
      • 390K resistor
      • 0.1 uf capacitor
      • 2 single male header pins (optional)
    • Camera interface relay board parts
      • 2 reed relays- 10ma coil, built in snubber diodes
      • 1/8" phono jack
      • 3 pin 0.1" header
    • 6-cell AA battery pack with NiMH rechargeable batteries for battery powered operation
    • Wall wart supply delivering nominal 9VDC for AC operation
    • Jumper wires or wires/pins/connector pin housings to make the connection between the keypad and RAMPS headers. 8-pin to 2 X 4-pin connection required.
    • Wires or cable to connect limit switches to RAMPS header. I used the cables that came with the limit switches in the RAMPS kit, extending them as described below.
    • Cable to connect the stepper to the RAMPS header. I used a 59" stepper cable from Amazon.
    • Manual camera shutter control cable that works with your type of camera- find on ebay or Amazon for a couple bucks. Cut off and discard the handheld push button unit and retain the cable and connector specific for your camera.

    Focus Rail

    • 3D printed pieces using supplied STL files- motor end, far end, and sled.
    • NEMA 17 stepper motor with 300mm T8 leadscrew shown or your length preference. If lead screw not integrated, use coupler to join stepper to leadscrew
    • Brass nut for lead screw - plain or spring loaded anti-backlash
    • 4 LM8U bearings
    • 2 8mm steel rods 340mm long or sized to your leadscrew
    • Base plate 100mm x 355mm (or appropriate length) I used a piece of 4" x 14" aluminum stock with the surface cleaned up. Many other base options are possible.
    • Bolts to attach end pieces to base - I used 1/4-20
    • Nuts/bolts for attaching limit switches - 4-40 or 3mm
    • RepRap style limit switches. The RAMPS kits often come with 3 or 4 of these. Standard microswitches can also be used with the hole patterns on the end pieces accepting either.
    • The following, in top to bottom order starting from the camera, used to mount your camera to the rail sled
      • 50mm universal quick shoe plate with 1/4 screw, fits Arca-Swiss standard (mounts to camera)
      • 200mm Nodal Slide focusing rail plate with quick release clamp for Arca mount (accepts plate above)
      • 50mm Arca Swiss clamp, quick release plate clamp, fits Arca style plate (mounts sliding nodal plate to sled)
    • Zip ties, 4"

    Step 1: RAMPS and Arduino

    The picture shows one of the typical RAMPS kits.

    The software for this build is here:

    Install the FastStacker software onto the mega board. Prior to compiling and uploading the Faststacker software to the board, use the Arduino IDE library manager to install the u8g2lib graphics library into your Arduino environment. If you use a different rail, limit switches, etc., refer to the original build Wiki for customization advice.

    Install all three jumpers in the X stepper motor driver spot of the RAMPS as shown in picture then install a stepper motor driver in this spot. This configures for 16 microstep operation. Plug the RAMPS shield into the Arduino mega. Connect the graphic LCD to the RAMPS with the interface card and ribbon cables provided with the LCD paying attention to the labels on the connectors at each end. Note that this LCD does not support programatic control of the backlight so that function is stubbed out in the software port.

    In the following steps, multiple connections are made to the RAMPS board by plugging into various headers. The diagram of the RAMPS board summarizes these connections for reference with further details provided in later steps.

    Step 2: Voltage Divider

    The stacker controller includes functionality to monitor battery voltage (or whatever the input power source is). A voltage divider is formed from 2 resistors and a 0.1uf noise suppression capacitor as per the original design. In this build, the voltage divider is plugged into pins of the otherwise unused, y stepper header. The mega's internal 2.56V voltage reference is used for the measurements.

    The two dividing resistors are referred to as R3 and R4 in the original project documentation and code and we continue that here. Assuming R3 is the one directly connected to "+" of the battery ( Y header pin16) and R4 is connected to ground (Y header pin 9), the divider ratio is R4/(R3+R4).This build assumes a nominal input voltage range of 6.9V to 9V. When operating from batteries it uses 6 AA NiMH rechargeable batteries. When operating from AC, it uses a 9V nominal wall wart. We will scale 9.2V to 2.56V with these resistors: R4=150K, R3= 390K.

    Build the voltage divider as shown. The pins are not strictly necessary, you can plug the resistor leads right into the header. However, the leads on the resistors I had seemed small and I was afraid they might not stay inserted reliably, so I added the pins. I am not sure the capacitor is really needed- it seems to work ok without as shown in the picture of the minimalist version of the divider using a single solder connection.

    Plug the divider into the Y-stepper header on the RAMPS as follows and as shown in picture:

    Pin 16 (Vcc)- free lead of 390K resistor.

    Pin 9 (gnd) - free lead of 150K resistor

    Pin 8 (Y stepper enable, arduino A7)- tap of voltage divider

    Step 3: Keypad

    2 types of commonly available keypads are shown. The stacker.h file includes key mappings for both with the black/white unit enabled by default. Uncomment the other mapping instead if you are using one of the red/blue membrane type. Refer to the original project documentation if yours is different.

    If you have trouble with some keys not working, but not a full row or column, and you are using one of the black/white units, measure the resistance of the row-column connections for all the keys. The black/white style keypads use some sort of printed carbon traces on the board inside that cause some row-column connections to be high resistance causing some keys to not respond when used with some platforms, e.g., arduino pro mini.

    The keypad has an 8 pin connector. 4 of these pins connect to one header on the RAMPS and the other 4 connect to another header. I made 8 pin to dual 4 pin ribbon cables for both keypad types as shown in the pics. They are the same except for the sex of the pins connecting to the keypad. I use pin housings and crimp on male and female pins along with wire and a crimp tool to make the cables but jumper wires or other pre-crimped options can be used. This video from Pololu shows many product options to build these sorts of cables: Jumper wires of the type shown are an easy option.

    Use the cable to connect the keypad to the RAMPS per the pictures and as follows (keypad pin numbering given below assumes pin 1 is to the left when looking at the front of the keyboard, pin 8 to right):

    keypad pins 1-4 connect to the RAMPS Servos header, the pins listed in order, left to right, starting at the pin closest to the reset button. This connects as follows:

    keypad 1- D11

    keypad 2- D6

    keypad 3- D5

    keypad 4- D4

    keypad pins 5-8 connect to the RAMPS endstop header and make connections as follows:

    keypad 5- Ymin- D14

    keypad 6- Ymax- D15

    keypad 7- Zmin - D18

    keypad 8, Zmax- D19

    Step 4: Camera Interface

    A small board holding 2 reed relays, a 3-pin header and an 1/8" audio jack acts as the interface between the RAMPS and the camera. I suggest using relays with built in snubber diodes. Add your own, if you do not. Pick one that requires no more than 10ma to activate (500ohm coil). I happened to have some Gordos 831A-4 relays that I used, but, for example, DigiKey has the Littlefuse #HE721A0510, Digi-Key Part Number HE101-ND that looks suitable. The schematic is shown.

    A cable is made from the manual shutter control by snipping and tossing the push button control after noting which wires are AF, shutter, and common. This cable is attached to a 1/8" audio plug that plugs into the jack on relay board.

    The relay board connects to the RAMPS with a short 3 wire servo cable as shown. You can use a standard servo cable, use jumpers, or make your own. The camera interface relay board plugs into the AUX-2 header of the RAMPS board, making the following connections-

    Aux 2, pin 8- GND

    Aux 2, pin 7- AF- D63

    Aux 2, pin 6 - shutter- D40

    I experimented with using a relay module for this function to avoid having to build a board, but the commonly available module I tried consumed too much current from the 5V rail.

    Step 5: Stepper Connection

    Plug in the stepper cable to the X stepper header. I used a 59" stepper extension cable as shown in 2nd pic. If the stepper turns in the wrong direction, reverse the stepper connector plugged into the RAMPS board.

    Step 6: Limit Switches

    The FastStacker software does not discriminate between the two endstops and does not care which one was hit. The RAMPS stacker software is configured to be able to work directly with 2 standard repRap limit switches and their associated cables which plug into the Xmin and Xmax endstop header positions on the RAMPS. The picture shows where these plug in. In this configuration, each limit switch on the rail is connected with +5V, GND, and an individual signal wire is run for each limit switch. The software ORs the two inputs together. This allows an easy plug and play reuse of the cables that come with the RAMPS kit and it allows the LED indicators on the repRap endstop boards to light when the stops are triggered. The signal lines of the two repRap switches cannot be connected together when the boards are receiving +5, if they are, triggering one and not the other will short +5 to GND. I made the cable harness shown from the original cables, sending a single power pair to the switches but retaining their individual signal wires and lengthening all the wires. This still uses 4 wires in the run between the controller and rail.

    A simpler approach just uses 2 wires- GND and either of the Xmin or Xmax endstop header pins which are run to the two Normally Open endstop switches, which are wired in parallel. If an endstop switch is triggered, the signal line is pulled to ground. Fewer wires, but no LED lighting when a switch is triggered.

    The hole patterns on the rail end pieces also support standard size microswitches (not the mini ones like on the repRap boards) in which case, use the 2- wire configuration.

    Step 7: Power and Bench Test

    Apply 7-9V nominal to the power input connector of the RAMPS. Note in the picture, which set of terminals on the power connector are used. This is the low power set of Vcc inputs, not the high power inputs that drive the RAMPS MOSFETS. The system should boot and tell you to push any key to start calibration. When you do, the stepper will begin to rotate. Let it do so for a few seconds, then trigger one of the limit switches. The motor should reverse. Let it run for several 10s of seconds, then hit a limit switch again. The motor will reverse again and move to what it thinks is the 4mm position. At this point, run through the operation of the various keys on the keyboard, referring to the original project documentation, to make sure the keys are all being read correctly. Note that the backlight control function from the original project is not supported on this system- the LCD does not support it. Run some stacks and listen for the click of the relays activating and when all seems well, verify the interface to your camera. That should be it for the electronics.

    Step 8: Rail

    The three 3D prints are easy prints and fine layers are not required- I used .28mm. It goes together as in the pictures. Please note that some pictures in this Instructable show a previous iteration of the rail design before I moved the endstop switches from on top of the end pieces to inside of the end pieces. The sled accommodates either the anti-backlash nut as shown or the standard nut. Start at the motor end, attaching the motor and endstop, add the rails, then slide the sled on and rotate the leadscrew by hand to thread it on the nut. Push the far end piece onto the rails, add the zip ties, and the assembly is largely done except for bolting to whatever base you choose. There are many options for a base. The aluminum plate I used is strong and easily tapped for mounting to a tripod. Aluminum extrusion or wood are other possibilities.

    Step 9: Enclosure

    There are many possible ways of packaging the electronics shown in the 1st picture. There are lots of designs on Thingiverse for boxes that hold the RAMPS/mega/LCD combo that could be a start for a 3D printed version. I used a laser to make an acrylic console style box from the design given in the attached SVG file. The box was created using and the hole patterns added in Lightburn. It is intended for 2.8mm material. I designed the box to hold the battery pack behind the electronics and fed its power output lead out a notch in the back. A hinged lid allows the battery to be removed easily. The power input jack for the system is brought to a hole on the back of the box where it is super glued. When running from battery, the battery lead is plugged into the jack as shown. The AC adapter plugs into the same jack when operating from AC. The battery pack can be charged without removing it from the box as shown in the picture.

    Step 10: Operation

    Here I refer you back to Pulsar124's excellent user guide: I made a laminated cheat sheet as shown to help me remember keyboard commands until I got familiar with them. As mentioned previously, the LCD does not support control backlight control, so the #-4 command does not work.

    See the attached video for a very quick demo of some basic operations.

    Step 11: Build Notes and Thoughts

    The port started with FastStacker V1.16. This is mainly because that is the version I used for my pro-mini based build. That was because I could not get V1.17 to fit on the pro-mini and I did not really care about the telescope control capability of 1.17. On the mega, this version, which I have called 1.16a takes less than 20% of the memory, so there is plenty of room for V1.17 and more. The RAMPS port involved pin mapping and replacement of the old LCD driver with the u8g2lib graphics driver. The larger LCD provided the luxury of extra characters that I used for labels, messages, and units of the existing UI to make it a bit more accessible to occasional users. As noted, the LCD does not support programmatic backlight control, so that command is stubbed out. I made some changes in the voltage monitoring area, using the internal voltage reference and adding another critical limit voltage constant that is used to verify low voltage before shutting down the rail. I also targeted the design to run from 6 cells rather than 8 as in the original build. The 6 cells are more power efficient, take up less space, and reduce stress on the 5V regulator on the mega with no impact on physical performance. I used the beeper on the LCD to give a short beep when displaying one of the error messages. I left the default backlash number at 0.2mm as it was originally, even though I suspect it is less with the anti-backlash nut, but I have not tried to measure it. If you disable backlash compensation and are working at a steep angle, turn off power saving so you are sure to maintain position. One feature I wish were in the software is keyboard control of the direction of backlash compensation ( without reversing the direction of operation of the rail operation using the *-1 command). This could be mapped to the unused backlight control keypress. Depending on the orientation of operation, I am not sure the current direction of compensation is always correct, i.e., that you can always assume that the sled moving away from the motor is always the direction that does not need compensation. I guess it really does not matter for large stacks. The code is configured for 16 mcrosteps. There was a constant in the code used to check reasonable #'s of frames for 1pt stacks that I have defined in stacker.h as RAIL_LENGTH and set it to 180 which is the approximate travel range for this rail. Change if your rail is different.

    This platform offers other additional capabilities besides memory that this build does not tap. The graphics capabilities of the LCD could be used for more than drawing the battery SOC indicator. The optical encoder knob is tempting and I took a shot at integrating it into the project. I found a good driver, integrated it into the build and main loop, and tried to fake out the software into thinking the "1" and "A" keys were being pressed when the knob was turned. It sort of worked, but was herky-jerky and provided no useful capability so I pulled it out. There are several unused stepper driver spots on the RAMPS board that could be used to control additional steppers, if that could be of utility.

    The 3D printer controllers like RAMPS provide great starting points for builds like this and I hope that a few more people are able to benefit from Pulsar124's cool software hosted on this easy to integrate platform.