Raspberry Pi‎ > ‎

Raspberry Pi DIY Pan Tilt Plans

This aims to show the reader how to build a simple Pan tilt mount using readily available stepper motors and other parts. This device automatically moves the camera to pre set angles and at pre set intervals.

Raspberry Pi is a trademark of the Raspberry Pi foundation.

YouTube Video

What you will need:

  • 2 x 28BY-J 5V stepper motors with ULN2003A driver board.
  • 6 way ribbon cable, approx 45 cm long (Can be split from a bigger cable)
  • Dupont cable female to female, usually these are supplied in 40Way strips.
  • 10 x M3 x 16 mm bolts
  • 2 x 1K resistors.
  • 20 x M3 nuts
  • 8 x M2.5 x 16 mm bolts
  • 26 x M2.5 Nuts
  • 2mm heat-shrink tubing, approx 40 cm long
  • Plywood approx 30 x 40 cm should be plenty.
  • 75 cm camera ribbon cable for the Pi Camera
  • Micro roller switch switches 3A size approx (13 x 6 x 6)
  • Glue for gluing the wood parts together, I used hot melt glue.
  • Large > 15A terminal blocks for connecting to the stepper motors
  • Pi – Cobbler (Recommended, but not essential)
  • Solder, soldering iron, wire strippers cutters etc.
  • Approx 10cm of thin steel wire, approx 0.5 – 1mm. You could probably use a paper clip.
  • Raspberry Pi + PSU + camera module + Mini WI-FI dongle + Memory card with latest Raspbian

Upright piece :

(ULN2003 driver board Holes not shown as they vary between boards, check your boards and mark accordingly)
The holes for the pi should be approx 2.5mm diameter.

Top piece / horizontal support

The large hole in the centre is around 30mm diameter. The small holes are 3mm diameter.

Base (94 mm circle):

Vertical movement stepper motor holder:

Corner pieces:

Small corner braces, the exact size is not important.

Camera mount side piece:

Drill the hole in the centre with a 6 mm bit.

Camera mount / camera holder.

Drill the holes with a 2.5mm bit.

Cut out all of the parts as per the drawings above. The pieces are cut from 6 mm plywood.

Glue on the corner braces as shown below, and glue on the base.

And then the top piece.

Fit the M3 bolts in place, these attach to the ULN20003A driver boards first. The ULN2003A driver boards are bolted to the back of the upright piece.

Then the M2 bolts for the actual Raspberry Pi. Notice that there are three nuts, these
act as spacers to give the Pi some clearance off the wood.

Bolt the horizontal movement stepper into place.

Bolt the Raspberry Pi into place.

Bolt the ULN2003 Driver boards into place.

Add on a brass connector to the stepper motor, you assembly should now look something like this :

Assemble the horizontal moving part as shown below. The edges of the stepper motor mount should just touch the edges of the circle.

Bolt the vertical movement stepper motor into place using the M3 bolts.

Switch assembly:

Both of the switches are wired in exactly the same way.
Both of the roller switches need a 1K ohm resistor wired in series with the switch as shown below. Solder the resistors onto the pin marked “common” or C.

Next, cut the ends off some dupont connectors, and solder them onto the resistor and onto the “NO” (normally open) pin of the switch.

Fixing the switches into place: The switches need to be pressed as the brass connector rotates past it. This is so the the camera will always start in the same position. Hold the switch against the screw of the brass connector and use a drawing pin to mark the holes.

Drill the holes with a 2.5mm drill bit, then bolt the switch in place.

The other switch is mounted against the vertical movement stepper in exactly the same way:

The switches may have too much movement in the lever and catch on the screw, bend a small piece of wire and bolt to the switch to prevent as shown below as shown:

Extend the vertical movement stepper motor wires

The wires from the vertical stepper motor, so you will need to extend them as above. There are no changes to the stepper wiring, only and extension of the wire. Us the six way ribbon cable to do this, two wires for the switch, and four for the stepper motor. Make sure that all of the connections are covered with heat-shrink tubing.

Camera mount assembly

Bolt a M5 Bolt and washers to the semi circle of the camera mount:

Bolt the camera to the camera mount plate. Note that there are two extra M2 nuts underneath the camera to act as spacers. You will need to drill holes for the camera bolts – I used drawing pins to mark the position of the holes, and then drilled them.

Glue the semi circle onto the camera mount plate as shown. The exact positioning is not too important. It should look something like this :

I added a small metal wire clip to secure the camera cable. Drill a small (2 – 3 mm) hole in the semi circle of the camera mount:

Attach the camera mount to the stepper motor, using the brass connector on the stepper motor.

Getting power to the ULN2003 driver boards:

Both of the ULN2003 driver boards need 5V power. To run the power to the boards I made a split cable as shown below. Cover the connections with heat shrink.

This photo shows the how the split wires connect to the ULN2003 driver board.

Wiring it all up:

Here is a schematic of the wiring of the switches and stepper motors, showing how they connect to the GPIO port. The 26 circles in the centre are the Raspberry Pi's GPIO port.

Note: the GPIO pins are actual pin numbers and not GPIO names.

Create a file in /home/pi called for your script. It can be called anything, I used pipan2.py,
And copy the script below into this file:

import time
import RPi.GPIO as GPIO
import os


current_h = 0
current_v = 0
h_step_counter = 0
v_step_counter = 0
step_delay = 0.003 # Experiment with this value to suit your motors
steps_per_degree = 4096/360

h_motor_pins = [19,15,13,11] # Horizontal stepper motor pinout
v_motor_pins = [16,12,10,8] # vertical stepper motor pinout
h_switch_pin = 21 # Horizontal switch pinout
v_switch_pin = 23 # Vertical switch pinout

motor_seq = [1,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,1]

# Set the switch pins as input with pull up resistors

GPIO.setup(h_switch_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set the switch pins to pull up
GPIO.setup(v_switch_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set the switch pins to pull up

# Set up the motor pins
while current_h < 4:
    GPIO.output(h_motor_pins[current_h], False)
    GPIO.output(v_motor_pins[current_h], False)
    current_h += 1

current_h = 0

def update_motors():
    global h_step_counter
    global v_step_counter

    if (h_step_counter >= 8):
        h_step_counter = 0
    elif (h_step_counter < 0):
        h_step_counter = 7
    if (v_step_counter >=8):
        v_step_counter = 0
    elif (v_step_counter < 0):
        v_step_counter = 7

    x = 0
    base_h = 4 * h_step_counter
    base_v = 4 * v_step_counter
    while x < 4:
         GPIO.output(h_motor_pins[x], motor_seq[base_h + x])
         GPIO.output(v_motor_pins[x], motor_seq[base_v + x])
         x += 1

def move_unit (target_h, target_v):
    global current_v
    global current_h
    global v_step_counter
    global h_step_counter

    if target_h > 180:
        target_h = 0
    elif target_h < 0:
        target_h = 0
    if target_v > 180:
        target_h = 0
    elif target_v < 0:
        target_h = 0
    t_h = target_h * steps_per_degree
    t_v = target_v * steps_per_degree
    while current_v != t_v or current_h != t_h:
        if current_h < t_h:
            current_h += 1
            h_step_counter += 1
        elif current_h > t_h:
            current_h -= 1
            h_step_counter -= 1

        if current_v < t_v:
            current_v += 1
            v_step_counter += 1
        elif current_v > t_v:
            current_v -= 1
            v_step_counter -= 1
        #print("Current H, V", current_h / steps_per_degree, current_v / steps_per_degree, "Target:", target_h, target_v)

do_h = 0
do_v = 0

if GPIO.input(h_switch_pin) == False:
    do_h = 1
if GPIO.input(v_switch_pin) == False:
    do_v = 1

i = 0

while i < 190:
    if do_h == 1:
        h_step_counter +=1
    if do_v == 1:
        v_step_counter +=1
    i += 1

while GPIO.input(h_switch_pin) == True or GPIO.input(v_switch_pin) == True :
    if GPIO.input(h_switch_pin):
        h_step_counter -= 1
    if GPIO.input(v_switch_pin):
        v_step_counter -= 1


lapsecount1 = 0
lapse4 = ''

while True:
    #Use for taking 'timelapse'
    #lapse1 = 'raspistill -t 1 -w 800 -h 600 -o /home/pi/lapse1/lapse1_' + str(lapsecount1) + '.jpg'
    #lapsecount += 1
    move_unit (10, 65) # Angle to move unit
    move_unit (45, 100)
    move_unit (60, 45)
    move_unit (120, 0)

Now you can run the script:

Open a terminal and type :
sudo python pipan2.py

The script should run and start moving the camera on its own.

You will probably want to view the camera output on your computer. To do this, follow the instructions at http://www.raspberrypi.org/camera

How to change the camera angle / movement

The angle the camera points to is determined by the following, which is in the python script :

move_unit (horizontal angle, vertical angle in degrees)

The time between movements is followed by :

time.sleep(time in seconds)