Electronics, project

DIy motorised camera slider

upload.jpg

For anyone shooting and editing video, sooner or later you realise a desire to have some more dynamic shots. Simply cutting from one static position to another can only take you so far.

Even with a good timelapse, it can add a great deal of visual interest to have the camera moving during the period. 

So how to achieve these aims? 

 

Enter the motorised camera slider. These can be purchased in varying shapes and sizes ranging from 100-600 pounds. The function is simply to slide a camera smoothly along under motor control such that you can adjust the speed of movement to your needs. The more expensive ones will also pan the camera. This is particularly useful if you want to make videos of yourself, or a specific subject that you want to keep somewhat centred in the frame whilst moving around. 

Obviously this is not a site about buying an off the shelf device...

Tools

Lathe

Drill/driver

Saw - just to rouh cut scraps to size as necessary.

Materials

flat piece of wood for track - I used the side of an old shelf unit

Delrin (you could do the same with a dense wood) 

Bearings

Tension bolts

2 stepper motors

2 motor drivers

1 arduino

2 rubber belts (often from vacuum cleaners)

1 lenth of string

Method

This design is based loosely on some cnc axis designs I've seen. Except where in a cnc built timing belt is used to ensure very precise movement and torque, in this build I'm just using string because it doesn't matter a huge amount if things slip slightly. it also reduces the cost and need for special parts.

another good reason for this design is the flexibility over length. you can run the string as long or short as you want. All of the complexity is in the cartridge so once that is built you can change the track easily for differing lengths depending on your needs. 

In my case I have kept the electronics separate, and so trail the motor wires back and forth with the movement. It would be equally possible to mount the electronics on the moving platform and provide power as the only cable, or even to mount batteries to power everything. 

The main drive

The linear motion is provided by a motor shaft turning against the string under tension. The tension provides enough grip to move rather than just slip. To maximise the grip, the string is wrapped around as much of the shaft as possible which is achieved with a couple of v-wheels mounted beneath the motor to guide the string through a narrow path up and around the motor shaft.

The shaft of the motor itself is too small and slippery to work well, so I turned a small piece of delrin to fit over the shaft, and provide a v-groove for the string to sit in. this avoids alignment issues pulling the string off the shaft. To fix the delrin onto the shaft I drilled a small hole into the side and screwed in a 3mm bolt. The delrin is soft enough that it didn't require tapping first, it just carved its own threads and holds strong.

upload.jpg

 

Then I made the idler v-wheels that just guide the string. These are standard skate bearing (608) which are 22mm diameter. I turned some delrin to have the external profile I wanted, another v-groove, then bored out the centre to fit the bearings. I checked frequently as I approached the internal diameter to ensure I did not overshoot. Ultimately I wanted a tight fit, tight enough that I needed a hammer to tap them into place.  

With those components made it is a question of mounting everything in place. I decided to base my platform off of a small section of wood. In my case this was recovered from door frame that I removed.

upload.jpg

I drilled 4 holes as even spacing down the length of it. The two centre holes are going to be mount points for the idler wheels, so need to be spaced far enough apart for those to fit, whilst close enough to feed the string through a fairly narrow channel to get a good wrap around the motor shaft.

The other two holes are just for stability so can be further out. I put a bolt through each hole with a pattern of nuts and bearings to act as wheels for the platform. So the holes you drill need to be close enough to the bottom of the wood that the fairly small bearing diameter will reach past the bottom. Alternately you could turn additional covers for the bearings to increase the diameter to make lager wheels. 

With the 'wheels' and the v-groove bearings mounted along the base piece, I could build up mounts for the motors that would drive the motion. For linear motion I mounted the motor above and beween the v-groove bearings so that the string could pass up and over the shaft. 

I found that the platform wanted to try and pull off course a little, probably because the motor shaft wasn't precisely alinged with all the wheels. So I made some guides to run along the other side of the track to keep things running straight.

upload.jpg

The the motor for the rotation could sit on the platform with its spindle pointing up. Initially I just had a single belt passing around the motor spindle and the platform for the go pro. This was fine, and straight forward. However in initial tests I had to move the motor so slowly to achive the degree of motion I wanted that the stepping was very visible in the video. This wasn't a problem for slwo timelapses, but for more real time video the steps made the video very jerky.

upload.jpg

So I decided to step down the ratio using an intermediate gear. This is just a chuk of wood with one large dimeter circle and one small diameter circle. The motor spindle is paired with the large diameter, then another belt comes off the small diameter and out to the gopro platform. This allows me to run the motor much faster for the same degree of motion whilst making things much smoother.

IMG_20151205_111028.jpg

 With the mecanical parts sorted, it just requires some electronics to drive the motors. I already had an arduino from a previous project, along with a pair of stepper motor controllers. These make life relatively easy. You connect the stepper drivers to power and the motors. And you use the aruidno to send step and direction pulses to the step and direction pins of the drivers.

I added a microswitch to each end of the track connecting to an input pin on the arduino so it can detect when the platform reaches each end and will reverse the direction signals. The code that runs the whole thing can be found below the video links. The third video below has me walking through the elctronics and the various parts of the program to descibe what they do. 


// set up the pin assignments
int dirpin = 2;
int steppin = 3;
int dir2pin = 4;
int step2pin = 5;
int pushButton = 8;
int mode1=9;
int mode2=10;
int mode3=11;

//start values
int dir=0;
int turn_counter=0;
int delay_speed=1;
int total_counter=0;
int last_switch_counter=0;
// the setup routine runs once when you press reset:
void setup() {

  // make the pushbutton's pin an input:
  pinMode(pushButton, INPUT_PULLUP);
  pinMode(mode1, INPUT_PULLUP);
  pinMode(mode2, INPUT_PULLUP);
  pinMode(mode3, INPUT_PULLUP);
  pinMode(dirpin, OUTPUT);
  pinMode(steppin, OUTPUT);
  pinMode(dir2pin, OUTPUT);
  pinMode(step2pin, OUTPUT);
  digitalWrite(dirpin, LOW);     // Set the direction.
  digitalWrite(dir2pin, LOW);     // Set the direction.
  delay(10);
  //start serial connection
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  
  // read the input pin:
  int buttonState = digitalRead(pushButton);
  //read mode options
  int one = digitalRead(mode1);
  int two = digitalRead(mode2);
  int four= digitalRead(mode3);
  
  //Serial.println(buttonState);
  delay(1);

  if (one==LOW && two==LOW && four==LOW){
    //case0
    delay_speed=1;
  }
  if (one==HIGH && two==LOW && four==LOW){
    //case1
     delay_speed=10;
  }
  if (one==LOW && two==HIGH && four==LOW){
    //case2
     delay_speed=100;
  }
  if (one==HIGH && two==HIGH && four==LOW){
    //case3
     delay_speed=500;
  }
  if (one==LOW && two==LOW && four==HIGH){
    //case4
     delay_speed=1000;
  }
  if (one==HIGH && two==LOW && four==HIGH){
    //case5
     delay_speed=2000;
  }
  if (one==LOW && two==HIGH && four==HIGH){
    //case6
     delay_speed=3000;
  }
  if (one==HIGH && two==HIGH && four==HIGH){
    //case7 
    delay_speed=4000;
  }
  
  //ignore limit switches if we haven't gone far since last flip
  if (buttonState ==0 && (total_counter-last_switch_counter>200)){
    //Serial.println("flipping  direction dir="+dir);
    digitalWrite(13, LOW);
    //swap direction
    if (dir==0){
   //   Serial.println("ChangeDirection RIGHT");
      digitalWrite(13, HIGH);
      digitalWrite(dirpin, HIGH);     // Set the direction.
      digitalWrite(dir2pin, HIGH);     // Set the direction.
      delay(10);
      last_switch_counter=total_counter;
      dir=1;
    }else{
      digitalWrite(13, LOW);
  //    Serial.println("ChangeDirection LEFT");
      digitalWrite(dirpin, LOW);     // Set the direction.
      digitalWrite(dir2pin, LOW);     // Set the direction.
      delay(10);
      last_switch_counter=total_counter;
      dir=0;
    }
  }
   
    digitalWrite(steppin, LOW);  // This LOW to HIGH change is what creates the
    digitalWrite(steppin, HIGH); // "Rising Edge" so the easydriver knows to when to step.
    //Serial.println("counter = ");
    //Serial.println(counter);
    //the pan is on 1/8 microstepping, so it take 8 beats to move it a full step.

    //complete two full steps for every 32 iterations of the linera motion steps (we're 1/8 stepping, so 16 microsteps)
    if (turn_counter%2==0){
      //switch on full micostepping but always move a whole step as 8 substeps
    // Serial.println("pan-step");
       digitalWrite(step2pin, LOW);  // This LOW to HIGH change is what creates the
       digitalWrite(step2pin, HIGH); // "Rising Edge" so the easydriver knows to when to step.
       
                               
       if (turn_counter==32){
           turn_counter=0;
       }
    }
    delayMicroseconds(500);      // This delay time is close to top speed for this
                                 // particular motor. Any faster the motor stalls.
    counter++;
    total_counter++;
    //delay(1);
    delay(delay_speed);
}