Here’s another in the series of articles of photographic uses for the Raspberry Pi SBC (Single Board Computer). This time, it’s re-purposing an old flatbed scanner as a macro rail for focus stacking images in macro photography.
There’s a common issue with shooting macro photography, and that’s the limitation in depth of field (or depth of focus). It can be as little as 0.5mm, depending on the camera settings and magnification you’re trying to achieve. A solution to this is to take several images, each one moving closer to the subject by a tiny amount. Each image will have a different part of the subject in focus. You can then combine all the sharp parts of the images together using some free software called CombineZM, and end up with a completely sharp image from front to back of the subject. The difficulty with this is moving the camera accurately at such small distances. Once solution is to turn the zoom ring on your lens slightly, but that’s still hit-and-miss on highly magnified images (1:1 and smaller). Commercial solutions can cost as much as $600, including controller.
So, I came up with the idea of re-purposing an old flat-bed scanner that I had in the attic gathering dust. It’s so old, that the most recent drivers available for it are for Windows XP. So it hasn’t been used in a couple of years. Being a scanner capable of 2400 dpi, it was definitely accurate enough, but would it be able to move a 3KG camera and lens? If I could get at the stepper motor to drive the scan element, maybe I could attach a camera to it and move it in very fine increments, ideal for macro photography.
Once I took the cover and the glass off, I was left with a nice flat platform on which to place my camera, and a 4-wire connection to the stepper motor to drive the platform forward and back. The stepper motor drive can be seen in the above image in the bottom right.
Mounting the camera is simply a case of placing it on the platform. The drive is slow enough that it does not dislodge the camera while it moves. The camera shown is a Canon EOS 5D Mark II, but it should work with Nikon, Sony, etc. Any camera with a shutter release mechanism.
This project was made much easier by using an off-the-shelf stepper motor drive unit (see pic). It’s a dual H-Bridge motor drive unit. I had it off eBay for €9. It has the capability to drive 2 DC motors, OR 1 stepper motor with 2 coils. In this project, we’re driving one stepper motor with two coils.
So, connecting in the 4-wire stepper motor interface into the MOTORA and MOTORB connections, and adding in a PSU in the form of 3 x AA batteries to drive the motor, I then connected 4 GPIO outputs of the Raspberry Pi directly onto the 4 inputs to the stepper motor driver board. I wired the EnableA and EnableB pins to the +5V, as I want both coils in the motor to be enabled, and saved myself a few GPIO pins in the process.
The sequence I’m using to drive forward is 1000, 0100, 0010, 0001 (repeating), and backwards, is 0001, 0010, 0100, 1000 (repeating). You can see in the sequence that it’s enabling one of the coils on the motor at a time, causing it to rotate.
With a small bit of code, I was then able to drive the platform in the scanner forward and backwards ad various speeds, depending on how fast I ran the sequence to the motor (see below for the code)
The next step was to drive the shutter of the camera between each move of the platform. This was done using the following circuit.
So, now I can move the camera towards the subject in increments as little as 0.02 mm, taking an image each increment. That’s incredible resolution for something this easy to build!
Here’e a snippet of python code to move the motor a number of steps, and trigger the shutter. Run this script for each frame in your stack. I guess you could stick a loop around it if you know how many frames you want to take, but I wanted to keep it simple for this article.
import sys import wiringpi from time import sleep # Parameters: # direction (0 or 1) # number of steps (int) # delay between steps (float) gpio = wiringpi.GPIO(wiringpi.GPIO.WPI_MODE_GPIO) motor_pin_a = 0 motor_pin_b = 1 motor_pin_c = 4 motor_pin_d = 14 shutterpin = 17 gpio.pinMode(motor_pin_a,gpio.OUTPUT) gpio.pinMode(motor_pin_b,gpio.OUTPUT) gpio.pinMode(motor_pin_c,gpio.OUTPUT) gpio.pinMode(motor_pin_d,gpio.OUTPUT) gpio.pinMode(shutterpin,gpio.OUTPUT) wiringpi.pinMode(shutterpin,1) wiringpi.pinMode(motor_pin_a,1) wiringpi.pinMode(motor_pin_b,1) wiringpi.pinMode(motor_pin_c,1) wiringpi.pinMode(motor_pin_d,1) if sys.argv == '1': start=0 finish=int(sys.argv,base=10) increment=1 else: start=int(sys.argv,base=10) finish=0 increment=-1 stepdelay=float(sys.argv) a = [ '1000', '0100', '0010', '0001'] for j in range(start,finish,increment): i = j%4 if a[i][0:1] == '1': gpio.digitalWrite(motor_pin_a,gpio.HIGH) else: gpio.digitalWrite(motor_pin_a,gpio.LOW) if a[i][1:2] == '1': gpio.digitalWrite(motor_pin_b,gpio.HIGH) else: gpio.digitalWrite(motor_pin_b,gpio.LOW) if a[i][2:3] == '1': gpio.digitalWrite(motor_pin_c,gpio.HIGH) else: gpio.digitalWrite(motor_pin_c,gpio.LOW) if a[i][3:4] == '1': gpio.digitalWrite(motor_pin_d,gpio.HIGH) else: gpio.digitalWrite(motor_pin_d,gpio.LOW) sleep(stepdelay) # sleep 100ms to let things settle. sleep(0.1) # Trigger the camera shutter. gpio.digitalWrite(shutterpin,gpio.HIGH) sleep(0.1) gpio.digitalWrite(shutterpin,gpio.LOW)
Here’s a video of the rig in operation, including a video of 42 stacked images played at 6 frames per second. This shows how the point of focus changes as the camera moves towards the subject
Here’s a few sample images taken using the flatbed scanner rig (MacroPi)
For a more robust solution, I’ve ordered the following part. Functionally it is the same as the flatbed scanner, but should allow me to more easily mount on a tripod for portable motorized focus stacking.
It was everything I was looking for all in one unit. A motor, rails, leadscrew, linear motion platform, all in one unit, all pre-assembled for about €83. I’d already got a 4-wire stepper motor working with the Raspberry Pi a few weeks ago, so the software was ready to go, it just needed me to build a macro rail. This thing would save me a load of time, and I’d end up with an industrial quality solution.
Some of the specs:
Motion length – 11.4 cm / 4.5″ ~
Leadscrew length – 14 cm / 5.5″ ~
Rail step (pitch) – 16 TPI
1.8° Step Motor – Made by SANYO DENKI
The motor has 200 steps per rev, so with 16 turns per inch, (6.3 turns per centimetre), that gives me a movement of 126 steps per mm. Plenty accurate for what I need.
Raspberry Pi is a trademark of the Raspberry Pi Foundation
About the Author:
By day I’m a senior embedded Linux software engineer. In my spare time, I take pictures, and play with gadgets and technology.