DIY Motorized Camera Slider with Pan and Tilt Head – Arduino Based Project

In this tutorial we will learn how make a motorized camera slider with pan and tilt head. This Arduino based project is 100% DIY, built with cheap materials like MDF and plywood and controlled using Arduino, three stepper motors, some buttons and a joystick attached on a custom designed PCB. Despite this, the end result is quite impressive, with super-smooth camera moves enabling us to get professional looking cinematic shots.

Overview

Using the controller we can either manually move the camera around or we can set start and end points and then the camera will automatically move from one to the other position. Also using the supporting arm we can mount the slider even on a smaller tripod, at any angle we want and still get a stable movements.

DIY Motorized Camera Slider with Pan and Tilt Mechanism Arduino Based

To begin with, I designed the slider using a 3D modeling software.

DIY Camera Slider with Pan and Tilt Head 3D Model

You can download and get all dimensions from the 3D model below.

Building the camera slider

So I started with making the slider rails for which I used 22mm tick copper pipe. I decided to make the slider 1 meter long so I cut two pieces to 1 meter of length. Copper pipes can easily oxidize so therefore we need to polish them with a metal polish. In my case, I didn’t have one so I used a toothpaste for that purpose.

cleaning copper pipes

This wasn’t the perfect solution bit still I could notice a difference and got the pipes a bit cleaner.

Then I moved on with making the wooden base on which the two pipes will be attached and also it will serve for mounting the slider onto a tripod. Using a circular saw I cut two pieces of 21mm tick plywood and glued them together in order to get a single ticker piece. Then using a solid wood I made a replica of my tripod mounting plate and attached it to the plywood piece using a wood glue and a screw. Now the slider base can be easily mounted on the tripod.

wooden tripod mounting plate

I will mount the slider rails to the base using 8mm threaded rods so I made two holes in the base and inserted the 138mm long rods which I previously cut them to size. Next I had to drill 8mm tick holes in the pipes which can actually be a little tricky.

mounting the rails onto the base

For that purpose I made a simple jig where I raised the pencil to a height of 11mm or that’s half of the pipe diameter. Then I secured the pipe on a flat surface and using the jig marked the pipe from both sides. This enables to get precisely alighted holes from both sides. So first I marked the drilling points with a sharp screw tip and then drilled them progressively using 2, 4, 6 and 8mm drill bit.

marking pipes for center drilling holes

After that I inserted the rails through the threaded rods and using some washers and nuts I secured them to the slider base. In a similar way, using a piece of plywood and a threaded rod I fixed the ends of the rails.\

fixing the ends of the slider rails

Next is the sliding platform. Again I used a circular saw for cutting the 8mm tick MDF board to size according to the 3D model. I also made some 8mm hole for the threaded rods on which the bearing are going to be attached. For assembling the platform I used a wood glue and some screws. Using a cordless drill, first, I made pilot holes, then made the counter sinks and screwed the 3mm screws in place.

Once the panels were secured I continued with assembling the bearing system. The bearings that I’m using are 608Z with outer diameter of 22mm. Two washers and a nut between two bearings make enough distance between them thus enabling good contact with the 22mm rails.

slider bearing system for 22mm pipes

In order to make the platform more secure when using the slider at an angle, in similar way, I inserted two more sets of bearings at the bottom side of the platform. At the end the sliding platform turned out to work perfectly.

camera slider bearings system

Here we can notice that now when moving the platform along the slider on my small, not heavy duty tripod, the head cannot hold the weight of the platform so I had to make a supporting arm in order to stabilize the slider. So using two pieces of wood and some nuts and bolts I made a simple clamp which can be fastened to the one of the tripod legs.

tripod leg clamp diy

The clamp has a bolt on which the supporting arm can be fastened. Next I had to make a slot on supporting arm in order to be able to position the slider at different angle. I made the slot by simply drilling many 6mm holes close to each other, and then using a rasp made a fine straight lines. This supporting system ended up working perfectly.

camera slider supporting arm

I continued this build with adding legs to the slider, in case you don’t want or need to use a tripod. I made them out of 8mm MDF. Using a hand saw and a rasp I easily got the desired shape of the legs. Then using some little glue and two nuts I secured them to the ends of the slider.

attaching legs to the slider

The next stage is building the pan and tilt system which will be attached on the top of the sliding platform. Using the circular saw, I cut all needed pieces, with the dimensions taken from the 3D model. I used few pieces of plywood for making the hinge mechanism of the leveling platform for the camera when the slider is set at an angle, as well as some MDF boards on which I made appropriate holes for the motor and the bearings for panning system.

I moved on with installing the stepper motor and the timing belt for the sliding platform. On one side of the platform I secured the stepper motor with a piece of MDF board and some screws and bolts. And on the other side of the slider I secured an idler pulley so now I can install the timing belt. Using two bolts and zip ties I easily secured the timing belt to the sliding platform.

With this step the sliding mechanism was completely done.

I continued with making the upper parts of pan and tilt system. According to the 3D model, I made all appropriate holes for the stepper motor and the bearings, and glued and screwed everything together.

A friend of mine 3D printed 2 80 tooth pulleys for me. In this way I got 5 times speed reduction relative to the 16 tooth pulley attached on the stepper motor.

80 tooth pulley for 5 times speed reduction

Now I needed to make a closed loop timing belt according to my setup, so I measured how much length of belt I needed, cut it and then simply glued it with a CA glue and added a piece of tape on top of it. The CA glue does a great job with rubber so the closed loop belt work without a problem.

Next I started the final assembly of the pan and tilt system. First I secured the tilt motor using some bolts and then added the two bearings in place while securing them in the slots with some epoxy. Then I secured the tilt platform on the pan platform using some 8mm bolts and at the same time I attached the 80 tooth pulley to it together with the timing belt.

installing the pan and tilt platforms

Here I noticed that the belt was a bit loose but I added a small bearing in the place where the stepper motor bolt goes to act as a belt tensioner. This thing worked out and so now the belt had enough tension to work properly.

Next I secured the pan motor and added bearings the top side of the leveling platform, as well as the on bottom side. Then I inserted a bolt through them, add a thrust bearing, the 80 tooth pulley and the timing belt, and on top of them add the previously assembled tilt head. Finally I secured it using a bolt and that’s it, with this step the construction of the slider is completed.

securing the pan and tilt head

Circuit Diagram

Ok, next comes the fun part or installing the electronics components. Here’s the circuit diagram of this DIY camera slider project.

DIY Motorized Camera Slider with Pan and Tilt Arduino Project Circuit Diagram

So the three NEMA 17 stepper motors are controlled via the three A4988 stepper drivers. For controlling the slider movement we use a potentiometer connected to an analog input of the Arduino, and for controlling the pan and tilt head we use a joystick module which actually consist of two potentiometers, so it is connected to two analog inputs. There’s also another potentiometer used for setting the speed of the automatic movement from the in and out positions. These in and out position are set with the help of push button. This push button has a pull up resistor and it’s connected to a digital pin of the Arduino board. There also a reset push button, a power switch and a power jack, as well as a limit switch for the slider and two LEDs for indicating the in and out status. We can power this project with either 9 or 12V.

You can get the components needed for this project from the links below:

*Please note: These are affiliate links. I may make a commission if you buy the components through these links.
I would appreciate your support in this way!

PCB Design

Next, according the circuit diagram I designed a custom PCB in order to keep the electronics components organized.

Camera slider PCB design

I did that using the EasyEDA free online circuit design software. The circuit had quite a few connections, so I used both the top and bottom layer and managed to get functional and good looking PCB. Once finished with this step I generated the Gerber file need for manufacturing the PCB. Then I ordered the PCB from JLCPCB, which is actually the sponsor of this tutorial.

Here we can simply upload the Gerber file and once uploaded we can again review our PCB in the Gerber viewer. If everything is all right then we can go on, select the properties that we want for our PCB, and then we can order our PCB at a reasonable price. Note that if it’s your first order from JLCPCB, you can get up to 10 PCBs for only 2 dollars.

Nevertheless, after a week the PCBs have arrived. The quality of the PCBs is great and I must admit that it is quite satisfying to have your own PCB design manufactured.

camera slider pcb quality

Assembling the electronics

Ok, so next I moved on with assembling the electronics components.  I started by soldering pin headers PCB. This enables easier connecting and disconnecting of the components when needed. I actually used pin headers for everything except the capacitors and the resistors which I soldered directly on the PCB. Therefore I continued with soldering jumper wires to all of the electronics components.

In this way I can easily mount the components on the controller case and at the same time connect them to the PCB.

arduino diy camera slider electronics components

As for the controller case, I decided to make it out of 4mm tick transparent acrylic because I wanted the beauty of all electronics components to be visible. I used a circular saw to cut the panels for case to size. Then using a drill and Forstner bits I made the opening on the front panel for the buttons, the potentiometers, power switch and the joystick. After that using a 5 minutes epoxy I assembled the case, and as for the top I inserted and glued two bolts through which the front panel can be inserted and secured using nuts on top of it.

transparent acrylic controller case

Finally I started assembling the electronics by inserting the Arduino board and the A4988 stepper drivers onto the PCB. Then I continued with inserting and securing the buttons and the other components on the front panel.

Once I had them secured I connected the components to the appropriate pin headers on the PCB. On the side panel of the case I added the power jack, and then inserted the PCB into the case. On the same panel there is also a hole through which I put jumper wires for connecting the drivers with the stepper motors, as well as the limit switch which I placed it at the end of the slider.

Using some heat-shrink tubing I organized the jumper wires coming out of the controller case and finally, what was left to do is to connect the controller with the three stepper motors and the limit switch.

As for powering the slider I used three 3.7V Li-ion batteries connected in series producing around 11V. And that’s it, the slider is done and works perfectly.

Arduino Source Code

Now what’s left in this tutorial is to take a look at the Arduino code and explain how the program works. As the code is a bit longer, for better understanding, I will post the source code of the program in sections with description for each section. And at the end of this article I will post the complete source code.

The program is based on the AccelStepper library by Mike McCauley. This is an incredible library which enables easy control of multiple stepper motors at the same time. So once we include this library and the MultiStepper.h library which is part of it, we need to define all Arduino pins that going to be used, define the instances for the steppers, as well as some variables need for the program below.

#include <AccelStepper.h>
#include <MultiStepper.h>

#define JoyX A0       // Joystick X pin
#define JoyY A1       // Joystick Y pin
#define slider A2     // Slider potentiometer
#define inOutPot A3   // In and Out speed potentiometer
#define JoySwitch 10  // Joystick switch connected
#define InOutSet 12   // Set Button
#define limitSwitch 11
#define inLED 8
#define outLED 9

// Define the stepper motors and the pins the will use
AccelStepper stepper1(1, 7, 6); // (Type:driver, STEP, DIR)
AccelStepper stepper2(1, 5, 4);
AccelStepper stepper3(1, 3, 2);

MultiStepper StepperControl;  // Create instance of MultiStepper

long gotoposition[3]; // An array to store the In or Out position for each stepper motor

int JoyXPos = 0;
int JoyYPos = 0;
int sliderPos = 0;
int currentSpeed = 100;
int inOutSpeed = 100;

int XInPoint = 0;
int YInPoint = 0;
int ZInPoint = 0;
int XOutPoint = 0;
int YOutPoint = 0;
int ZOutPoint = 0;
int InandOut = 0;

In the setup section we set the initial speed values for the steppers, define some pin modes, as well as add the three steppers to the multi stepper control instance called “StepperControl”. Using the while loops we move the slider to the initial position, or it moves until it press the limit switch and then it moves back 200 steps in order to release the limit switch.

void setup() {
  // Set initial seed values for the steppers
  stepper1.setMaxSpeed(3000);
  stepper1.setSpeed(200);
  stepper2.setMaxSpeed(3000);
  stepper2.setSpeed(200);
  stepper3.setMaxSpeed(3000);
  stepper3.setSpeed(200);
  pinMode(JoySwitch, INPUT_PULLUP);
  pinMode(InOutSet, INPUT_PULLUP);
  pinMode(limitSwitch, INPUT_PULLUP);
  pinMode(inLED, OUTPUT);
  pinMode(outLED, OUTPUT);

  // Create instances for MultiStepper - Adding the 3 steppers to the StepperControl instance for multi control
  StepperControl.addStepper(stepper1);
  StepperControl.addStepper(stepper2);
  StepperControl.addStepper(stepper3);

  // Move the slider to the initial position - homing
  while (digitalRead(limitSwitch) != 0) {
    stepper1.setSpeed(3000);
    stepper1.runSpeed();
    stepper1.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
  }
  delay(20);
  // Move 200 steps back from the limit switch
  while (stepper1.currentPosition() != -200) {
    stepper1.setSpeed(-3000);
    stepper1.run();
  }
}

In the loop section we start by checking whether the slider has reached the limit positions, or that’s the limit switch or 80cm on the other side of it.

// Limiting the movement - Do nothing if limit switch pressed or distance traveled in other direction greater then 80cm
  while (digitalRead(limitSwitch) == 0 || stepper1.currentPosition() < -64800) {}

With the next if statement we increase the Pan and Tilt speeds with each press of the joystick switch.

// If Joystick pressed increase the Pan and Tilt speeds
  if (digitalRead(JoySwitch) == 0) {
    currentSpeed = currentSpeed + 50;
    delay(200);
  }

Then we check whether we have pushed the Set button, which is used for setting the IN and OUT positions. With the first push of the button we store the IN positions of stepper motors and also light up the IN LED.

switch (InandOut) { 
      case 0:   // Set IN position
        InandOut = 1;
        XInPoint = stepper1.currentPosition(); // Set the IN position for steppers 1
        YInPoint = stepper2.currentPosition(); // Set the IN position for steppers 2
        ZInPoint = stepper3.currentPosition(); // Set the IN position for steppers 3
        digitalWrite(inLED, HIGH); // Light up inLed
        break;

In the same way, with the second push we store the OUT positions and light up the OUT LED.

case 1: // Set OUT position
        InandOut = 2;
        XOutPoint = stepper1.currentPosition(); //  Set the OUT Points for both steppers
        YOutPoint = stepper2.currentPosition();
        ZOutPoint = stepper3.currentPosition();
        digitalWrite(outLED, HIGH);
        break;

Then with the next push of the button, we read the value of the auto speed potentiometer which is use to set the maximum speed of the motors. Also we put the IN positions into the “gotoposition” array which is used in the moveTo() function which calculates the required speed for all steppers separately. Then using the runSpeedToPosition() function the slider automatic moves to In position.

case 2: // Move to IN position / go to case 3
        InandOut = 3;
        inOutSpeed = analogRead(inOutPot); // Auto speed potentiometer
        // Place the IN position into the Array
        gotoposition[0] = XInPoint;
        gotoposition[1] = YInPoint;
        gotoposition[2] = ZInPoint;
        stepper1.setMaxSpeed(inOutSpeed);
        stepper2.setMaxSpeed(inOutSpeed);
        stepper3.setMaxSpeed(inOutSpeed);
        StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
        StepperControl.runSpeedToPosition(); // Blocks until all steppers are in position
        delay(200);
        break;

In exactly the same way, in case number 3 or with another push of the button, we move the slider to the OUT position.

case 3: // Move to OUT position / go back to case 2
        InandOut = 2;
        inOutSpeed = analogRead(inOutPot);
        // Place the OUT position into the Array
        gotoposition[0] = XOutPoint;
        gotoposition[1] = YOutPoint;
        gotoposition[2] = ZOutPoint;
        stepper1.setMaxSpeed(inOutSpeed);
        stepper2.setMaxSpeed(inOutSpeed);
        stepper3.setMaxSpeed(inOutSpeed);
        StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
        StepperControl.runSpeedToPosition(); // Blocks until all are in position
        delay(200);
        break;

In case we hold the Set button pushed for longer than half a second the 4th case statement will be executed, which resets the IN and OUT position so we can set new ones.

Next is the joystick Pan and Tilt control. The analog value we are getting from the joystick is from 0 to 1024, or when it rests in the middle the values is around 500. So if we move the joystick to left and the analog value is greater than 600, we will set the speed of the particular motor to positive, and opposite, of we move the joystick right, we will set the speed of the motor to negative, which means it will rotate the opposite way.

// Joystick X - Pan movement
  JoyXPos = analogRead(JoyX);
  // if Joystick is moved left, move stepper 2 or pan to left
  if (JoyXPos > 600) {
    stepper2.setSpeed(currentSpeed);
  }
  // if Joystick is moved right, move stepper 2 or pan to right
  else if (JoyXPos < 400) {
    stepper2.setSpeed(-currentSpeed);
  }
  // if Joystick stays in middle, no movement
  else {
    stepper2.setSpeed(0);
  }

In case it stays in the middle, the speed is set to 0. This method is used for both axis of the joystick as well as the slider potentiometer. Actually, in the case of the potentiometer we use its analog value to also increase the speed of the motor as we further turn the potentiometer.

// Slider potentiometer
  sliderPos = analogRead(slider);
  // If potentiometer is turned left, move slider left
  if (sliderPos > 600) {
    sliderPos = map(sliderPos, 600, 1024, 0, 3000);
    stepper1.setSpeed(sliderPos); // Increase speed as turning
  }
  // If potentiometer is turned right, move slider right
  else if (sliderPos < 400 ) {
    sliderPos = map(sliderPos, 400, 0, 0, 3000);
    stepper1.setSpeed(-sliderPos); // Increase speed as turning
  }
  // If potentiometer in middle, no movement
  else {
    stepper1.setSpeed(0);
  }

Lastly, we call the runSpeed() functions for each of the three stepper motors and that executes the above commands, or rotates the motors appropriately.

// Execute the above commands - run the stepper motors
  stepper1.runSpeed();
  stepper2.runSpeed();
  stepper3.runSpeed();

Here’s the complete source code:

/*
  DIY Camera Slider with Pan and Tilt Head
  by Dejan Nedelkovski,
  
Home
Library - AccelStepper by Mike McCauley: http://www.airspayce.com/mikem/arduino/AccelStepper/index.html */ #include <AccelStepper.h> #include <MultiStepper.h> #define JoyX A0 // Joystick X pin #define JoyY A1 // Joystick Y pin #define slider A2 // Slider potentiometer #define inOutPot A3 // In and Out speed potentiometer #define JoySwitch 10 // Joystick switch connected #define InOutSet 12 // Set Button #define limitSwitch 11 #define inLED 8 #define outLED 9 // Define the stepper motors and the pins the will use AccelStepper stepper1(1, 7, 6); // (Type:driver, STEP, DIR) AccelStepper stepper2(1, 5, 4); AccelStepper stepper3(1, 3, 2); MultiStepper StepperControl; // Create instance of MultiStepper long gotoposition[3]; // An array to store the In or Out position for each stepper motor int JoyXPos = 0; int JoyYPos = 0; int sliderPos = 0; int currentSpeed = 100; int inOutSpeed = 100; int XInPoint = 0; int YInPoint = 0; int ZInPoint = 0; int XOutPoint = 0; int YOutPoint = 0; int ZOutPoint = 0; int InandOut = 0; void setup() { // Set initial seed values for the steppers stepper1.setMaxSpeed(3000); stepper1.setSpeed(200); stepper2.setMaxSpeed(3000); stepper2.setSpeed(200); stepper3.setMaxSpeed(3000); stepper3.setSpeed(200); pinMode(JoySwitch, INPUT_PULLUP); pinMode(InOutSet, INPUT_PULLUP); pinMode(limitSwitch, INPUT_PULLUP); pinMode(inLED, OUTPUT); pinMode(outLED, OUTPUT); // Create instances for MultiStepper - Adding the 3 steppers to the StepperControl instance for multi control StepperControl.addStepper(stepper1); StepperControl.addStepper(stepper2); StepperControl.addStepper(stepper3); // Move the slider to the initial position - homing while (digitalRead(limitSwitch) != 0) { stepper1.setSpeed(3000); stepper1.runSpeed(); stepper1.setCurrentPosition(0); // When limit switch pressed set position to 0 steps } delay(20); // Move 200 steps back from the limit switch while (stepper1.currentPosition() != -200) { stepper1.setSpeed(-3000); stepper1.run(); } } void loop() { // Limiting the movement - Do nothing if limit switch pressed or distance traveled in other direction greater then 80cm while (digitalRead(limitSwitch) == 0 || stepper1.currentPosition() < -64800) {} // If Joystick pressed increase the Pan and Tilt speeds if (digitalRead(JoySwitch) == 0) { currentSpeed = currentSpeed + 50; delay(200); } // If Set button i

So that would be all, I hope you enjoyed this Arduino project and learned something new. Feel free to ask any question in the comments section below.

Leave a Reply

Your email address will not be published.