Saturday, October 10, 2009

Dragon Stop Motion moves your camera

At my Canon HF100 blog I show a DIY camera motion control rig that is also useful for time lapse or stop motion.

The best stop motion software I know is Dragon Stop Motion. Since version 2.0 it supports the Arduino controller that I used for the rig mentioned above. I can now control my DIY slider directly from Dragon Stop Motion for slowly panning across a stop motion scene or for camera movement between time lapse shots.

Here's my skinny Arduino sketch:

/*
Arduino sketch that moves an unipolar stepper motor 
every time Dragon Stop Motion sends a "PF" (Position Frame) command.
A linear slider solution and a simple stepper motor interface capable of moving a DSLR is shown at 
http://canon-hf100.blogspot.com/2009/07/diy-camera-motion-control_09.html 
2009, Martin Koch
----------------------------------------
Function:
move(steps, direction, hold_load)
steps: 200 steps = 360° 
clockwise: true = cw, false = ccw
hold_load: true = leave motor current on
----------------------------------------
*/
//Arduino digital output numbers
#define D0 13
#define D1 12
#define D2 11
#define D3 10
byte inbyte = 0;

void setup() { 
pinMode(D0, OUTPUT);
pinMode(D1, OUTPUT);
pinMode(D2, OUTPUT);
pinMode(D3, OUTPUT);
pinMode(D12, OUTPUT);
Serial.begin(56000); //open the serial port
}

void loop() {
/*
Read one byte (one character) from serial port.
If Dragon Stop Motion sends the character "P"
it must be the  "PF" (Position Frame) command.
Lets move the camera to the next position.
*/
inbyte = Serial.read(); 
if (inbyte == 'P') move(20, false, false); //Move 20 steps, clockwise?, hold_load? 
}

void move(int number_of_steps, boolean clockwise, boolean hold_load) {
int output_pattern = 0;
int steps_so_far = 0;
do {
switch (output_pattern) { // Full steps
case 0:     //1100
digitalWrite(D0, HIGH);
digitalWrite(D1, HIGH);
digitalWrite(D2, LOW);
digitalWrite(D3, LOW);
break;
case 1:    //0110
digitalWrite(D0, LOW);
digitalWrite(D1, HIGH);
digitalWrite(D2, HIGH);
digitalWrite(D3, LOW);
break;
case 2:    //0011
digitalWrite(D0, LOW);
digitalWrite(D1, LOW);
digitalWrite(D2, HIGH);
digitalWrite(D3, HIGH);
break;
case 3:    //1001
digitalWrite(D0, HIGH);
digitalWrite(D1, LOW);
digitalWrite(D2, LOW);
digitalWrite(D3, HIGH);
break;
} 
delay(15); //15 ms give 10 revolutions per minute
steps_so_far += 1;
if (clockwise) output_pattern -= 1; else output_pattern += 1;
if ( output_pattern > 3 ) output_pattern = 0;
if ( output_pattern < 0 ) output_pattern = 3;
} while (steps_so_far < number_of_steps);
if (!hold_load) {
//If the stepper motor doesn't have to hold the load when it stands still 
//turn off any motor current to keep it cool
digitalWrite(D0, LOW);
digitalWrite(D1, LOW);
digitalWrite(D2, LOW);
digitalWrite(D3, LOW);
}
return;
}