Introduction: Hacked Pan and Tilt Camera Mount
So my sister managed to break a pan and tilt camera mount and naturally thought daddy can fix this.
After sitting on my dads workshop bench for a while he had a go at it and couldn't work out how to fix it so it was passed on to me as broken.
So I decided to hang the current circuit board and lets make this thing arduino compatible and while I am at it lets make it wireless :-)
In preparation for this I had to work out which wires were for the motors and which were for the internal batteries.
I am working with one of these: http://www.bhphotovideo.com/c/product/64399-REG/Bescor_MP101_MP_101_Motorized_Pan_Head.html
After sitting on my dads workshop bench for a while he had a go at it and couldn't work out how to fix it so it was passed on to me as broken.
So I decided to hang the current circuit board and lets make this thing arduino compatible and while I am at it lets make it wireless :-)
In preparation for this I had to work out which wires were for the motors and which were for the internal batteries.
I am working with one of these: http://www.bhphotovideo.com/c/product/64399-REG/Bescor_MP101_MP_101_Motorized_Pan_Head.html
Step 1: Parts Required
For this you need some soldering experience and a bit of patience.
Things you'll need;
Solder
Soldering iron
Two Teensy development boards :- http://pjrc.com/teensy/index.html
An H-Bridge to control the motors :- http://www.ebay.co.uk/itm/SN754410NE-x1-SN754410-754410-Motor-driver-Stepper-Arduino-ATMEGA-PIC-/251042473622?pt=UK_Mobile_Phones_Communication_Radio_Parts_Accessories&hash=item3a734c2696
433 mhz transmitter and receiver :- http://http://www.ebay.co.uk/itm/KDQ6-NEW-1PCS-433MHZ-RF-TRANSMITTER-AND-RECEIVER-LINK-KIT-FOR-ARDUINO-SCA-1710-/360670375378?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item53f9a12dd2
On Off switch
Things you'll need;
Solder
Soldering iron
Two Teensy development boards :- http://pjrc.com/teensy/index.html
An H-Bridge to control the motors :- http://www.ebay.co.uk/itm/SN754410NE-x1-SN754410-754410-Motor-driver-Stepper-Arduino-ATMEGA-PIC-/251042473622?pt=UK_Mobile_Phones_Communication_Radio_Parts_Accessories&hash=item3a734c2696
433 mhz transmitter and receiver :- http://http://www.ebay.co.uk/itm/KDQ6-NEW-1PCS-433MHZ-RF-TRANSMITTER-AND-RECEIVER-LINK-KIT-FOR-ARDUINO-SCA-1710-/360670375378?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item53f9a12dd2
On Off switch
Step 2: Solder the H-Bridge
When you have the six wires you need from the pan and tilt camera mount you need to attach them to the H-Bridge in the attached format.
You can attach the power directly from the batteries to this allowing for you to power the teensy from the H-Bridge as well as powering the motors.
At this point you can add a switch to turn it on and off when you want.
I assigned the pins as follows
Pin 1, 8, 9, 16 power from the mount.
2,7 pan or tilt pwm respectively
15, 10 pan or tilt pwm respectively
3,6 motor 1
11, 14 motor 2
4, 5, 13, 12 ground
You can attach the power directly from the batteries to this allowing for you to power the teensy from the H-Bridge as well as powering the motors.
At this point you can add a switch to turn it on and off when you want.
I assigned the pins as follows
Pin 1, 8, 9, 16 power from the mount.
2,7 pan or tilt pwm respectively
15, 10 pan or tilt pwm respectively
3,6 motor 1
11, 14 motor 2
4, 5, 13, 12 ground
Step 3: Attach the Teensy
The Teensy will control the whole project.
You need to connect the power from the H-Bridge to the Teensy so it can opperate and you need to connect the PWM wires to four of the data IO's.
I used pins B5, B6, F7 and F6 as denoted on the board.
From here you can control the pan and tilt by using the teensy's arduino compatible com port.
To make the mount pan to the right you first need to setup the IO's. Below is a draft sketch that will make the pan and tilt mount turn constantly to the Right.
int pan[] = {14, 15};
void setup()
{
pinMode(pan[0], OUTPUT);
pinMode(pan[1], OUTPUT);
}
void loop()
{
digitalWrite(pan[0], LOW);//right
digitalWrite(pan[1], HIGH);//right
}
Below is a list of commands that will make the mount pan left, pan right, tilt up, tilt down and stop
int pan[] = {14, 15};
int tilt[] = {16, 17};
digitalWrite(tilt[0], LOW);//up
digitalWrite(tilt[1], HIGH);//up
digitalWrite(tilt[0], HIGH);//down
digitalWrite(tilt[1], LOW);//down
digitalWrite(pan[0], HIGH);//left
digitalWrite(pan[1], LOW);//left
digitalWrite(pan[0], LOW);//right
digitalWrite(pan[1], HIGH);//right
digitalWrite(pan[0], LOW);//stop
digitalWrite(pan[1], LOW);//stop
digitalWrite(tilt[0], LOW);//stop
digitalWrite(tilt[1], LOW);//stop
You need to connect the power from the H-Bridge to the Teensy so it can opperate and you need to connect the PWM wires to four of the data IO's.
I used pins B5, B6, F7 and F6 as denoted on the board.
From here you can control the pan and tilt by using the teensy's arduino compatible com port.
To make the mount pan to the right you first need to setup the IO's. Below is a draft sketch that will make the pan and tilt mount turn constantly to the Right.
int pan[] = {14, 15};
void setup()
{
pinMode(pan[0], OUTPUT);
pinMode(pan[1], OUTPUT);
}
void loop()
{
digitalWrite(pan[0], LOW);//right
digitalWrite(pan[1], HIGH);//right
}
Below is a list of commands that will make the mount pan left, pan right, tilt up, tilt down and stop
int pan[] = {14, 15};
int tilt[] = {16, 17};
digitalWrite(tilt[0], LOW);//up
digitalWrite(tilt[1], HIGH);//up
digitalWrite(tilt[0], HIGH);//down
digitalWrite(tilt[1], LOW);//down
digitalWrite(pan[0], HIGH);//left
digitalWrite(pan[1], LOW);//left
digitalWrite(pan[0], LOW);//right
digitalWrite(pan[1], HIGH);//right
digitalWrite(pan[0], LOW);//stop
digitalWrite(pan[1], LOW);//stop
digitalWrite(tilt[0], LOW);//stop
digitalWrite(tilt[1], LOW);//stop
Step 4: Make It Wireless
This is an optional addition but it is always cool.
For this you will need the second Teensy and the 433 MHz transmitter and receiver.
There are plenty of instructions out there for how to use a 433 MHz setup but here is some simple example code.
I attached the 433 MHz transmitter to pins 4, 5 and 6.
For this to work you will need to virtual wire library.
#include <VirtualWire.h>
const int transmit_pin = 4;
void setup()
{
digitalWrite(5, 1);
pinMode(6, OUTPUT);
digitalWrite(6, 0);
vw_set_tx_pin(transmit_pin);
vw_setup(2000);
}
void loop()
{
char msg[5] = {'H', 'e', 'l', 'l', 'o'};
vw_send((uint8_t *)msg, 5);
delay(1000);
}
this program will simply keep on sending hello, wait one second, rinse and repeat.
For the receiver I attached it to pins 4,5,6 and 7
Below is some sample code, you will also need the virtual wire library for this.
#include <VirtualWire.h>
const int receive_pin = 6;
void setup()
{
Serial.begin(9600);
pinMode(7, OUTPUT);
digitalWrite(7, 0);
pinMode(4, OUTPUT);
digitalWrite(4, 1);
vw_set_rx_pin(receive_pin);
vw_setup(2000);
vw_rx_start();
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)){
for(int i = 0; i < buflen; i++){
Serial.write(buf[i]);
}
}
}
This code will wait until it receives data from a transmitter then print it to the serial port.
For this you will need the second Teensy and the 433 MHz transmitter and receiver.
There are plenty of instructions out there for how to use a 433 MHz setup but here is some simple example code.
I attached the 433 MHz transmitter to pins 4, 5 and 6.
For this to work you will need to virtual wire library.
#include <VirtualWire.h>
const int transmit_pin = 4;
void setup()
{
digitalWrite(5, 1);
pinMode(6, OUTPUT);
digitalWrite(6, 0);
vw_set_tx_pin(transmit_pin);
vw_setup(2000);
}
void loop()
{
char msg[5] = {'H', 'e', 'l', 'l', 'o'};
vw_send((uint8_t *)msg, 5);
delay(1000);
}
this program will simply keep on sending hello, wait one second, rinse and repeat.
For the receiver I attached it to pins 4,5,6 and 7
Below is some sample code, you will also need the virtual wire library for this.
#include <VirtualWire.h>
const int receive_pin = 6;
void setup()
{
Serial.begin(9600);
pinMode(7, OUTPUT);
digitalWrite(7, 0);
pinMode(4, OUTPUT);
digitalWrite(4, 1);
vw_set_rx_pin(receive_pin);
vw_setup(2000);
vw_rx_start();
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)){
for(int i = 0; i < buflen; i++){
Serial.write(buf[i]);
}
}
}
This code will wait until it receives data from a transmitter then print it to the serial port.
Step 5: The Final Product
So after some tweaking and testing I came up with a version that would work by sending an ID and a character to the receiver which will check the ID and use the character to either pan, tilt or stop the mount.
Below is the transmitter code.
#include <VirtualWire.h>
const int transmit_pin = 4;
char id[4];
int i = 0;
void setup()
{
Serial.begin(9600);
pinMode(5, OUTPUT);
digitalWrite(5, 1);
pinMode(6, OUTPUT);
digitalWrite(6, 0);
vw_set_tx_pin(transmit_pin);
vw_setup(2000);
}
void loop()
{
if(Serial.available()){
char input = Serial.read();
if(input >= 48 && input <= 57){
id[i] = input;
i++;
}else{
i = 0;
}
if(i == 4){
input = Serial.read();
if(input == 'U'){
char msg[5] = {id[0],id[1],id[2],id[3],'U'};
vw_send((uint8_t *)msg, 5);
}
if(input == 'D'){
char msg[5] = {id[0],id[1],id[2],id[3],'D'};
vw_send((uint8_t *)msg, 5);
}
if(input == 'L'){
char msg[5] = {id[0],id[1],id[2],id[3],'L'};
vw_send((uint8_t *)msg, 5);
}
if(input == 'R'){
char msg[5] = {id[0],id[1],id[2],id[3],'R'};
vw_send((uint8_t *)msg, 5);
}
if(input == 'S'){
char msg[5] = {id[0],id[1],id[2],id[3],'S'};
vw_send((uint8_t *)msg, 5);
}
vw_wait_tx();
i = 0;
}
}
}
below is the receiver code.
#include <VirtualWire.h>
const int receive_pin = 6;
int pan[] = {14, 15};
int tilt[] = {16, 17};
void setup()
{
for(int i = 0; i < 2; i++){
pinMode(pan[i], OUTPUT);
pinMode(tilt[i], OUTPUT);
}
digitalWrite(11, HIGH);
pinMode(7, OUTPUT);
digitalWrite(7, 0);
pinMode(4, OUTPUT);
digitalWrite(4, 1);
vw_set_rx_pin(receive_pin);
vw_setup(2000);
vw_rx_start();
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)){
if(buf[0] == '1' && buf[1] == '0' && buf[2] == '2' && buf[3] == '4'){
if(buf[4] == 'U'){
digitalWrite(tilt[0], LOW);//up
digitalWrite(tilt[1], HIGH);//up
}
if(buf[4] == 'D'){
digitalWrite(tilt[0], HIGH);//down
digitalWrite(tilt[1], LOW);//down
}
if(buf[4] == 'L'){
digitalWrite(pan[0], HIGH);//left
digitalWrite(pan[1], LOW);//left
}
if(buf[4] == 'R'){
digitalWrite(pan[0], LOW);//right
digitalWrite(pan[1], HIGH);//right
}
if(buf[4] == 'S'){
digitalWrite(pan[0], LOW);//stop
digitalWrite(pan[1], LOW);//stop
digitalWrite(tilt[0], LOW);//stop
digitalWrite(tilt[1], LOW);//stop
}
}
}
}
this works like a treat and I am going to be working on creating an interface for it that uses visual basic to communicate and control the mount.
I hope you enjoyed this instructable, if you have any questions please feel free to ask
Below is the transmitter code.
#include <VirtualWire.h>
const int transmit_pin = 4;
char id[4];
int i = 0;
void setup()
{
Serial.begin(9600);
pinMode(5, OUTPUT);
digitalWrite(5, 1);
pinMode(6, OUTPUT);
digitalWrite(6, 0);
vw_set_tx_pin(transmit_pin);
vw_setup(2000);
}
void loop()
{
if(Serial.available()){
char input = Serial.read();
if(input >= 48 && input <= 57){
id[i] = input;
i++;
}else{
i = 0;
}
if(i == 4){
input = Serial.read();
if(input == 'U'){
char msg[5] = {id[0],id[1],id[2],id[3],'U'};
vw_send((uint8_t *)msg, 5);
}
if(input == 'D'){
char msg[5] = {id[0],id[1],id[2],id[3],'D'};
vw_send((uint8_t *)msg, 5);
}
if(input == 'L'){
char msg[5] = {id[0],id[1],id[2],id[3],'L'};
vw_send((uint8_t *)msg, 5);
}
if(input == 'R'){
char msg[5] = {id[0],id[1],id[2],id[3],'R'};
vw_send((uint8_t *)msg, 5);
}
if(input == 'S'){
char msg[5] = {id[0],id[1],id[2],id[3],'S'};
vw_send((uint8_t *)msg, 5);
}
vw_wait_tx();
i = 0;
}
}
}
below is the receiver code.
#include <VirtualWire.h>
const int receive_pin = 6;
int pan[] = {14, 15};
int tilt[] = {16, 17};
void setup()
{
for(int i = 0; i < 2; i++){
pinMode(pan[i], OUTPUT);
pinMode(tilt[i], OUTPUT);
}
digitalWrite(11, HIGH);
pinMode(7, OUTPUT);
digitalWrite(7, 0);
pinMode(4, OUTPUT);
digitalWrite(4, 1);
vw_set_rx_pin(receive_pin);
vw_setup(2000);
vw_rx_start();
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)){
if(buf[0] == '1' && buf[1] == '0' && buf[2] == '2' && buf[3] == '4'){
if(buf[4] == 'U'){
digitalWrite(tilt[0], LOW);//up
digitalWrite(tilt[1], HIGH);//up
}
if(buf[4] == 'D'){
digitalWrite(tilt[0], HIGH);//down
digitalWrite(tilt[1], LOW);//down
}
if(buf[4] == 'L'){
digitalWrite(pan[0], HIGH);//left
digitalWrite(pan[1], LOW);//left
}
if(buf[4] == 'R'){
digitalWrite(pan[0], LOW);//right
digitalWrite(pan[1], HIGH);//right
}
if(buf[4] == 'S'){
digitalWrite(pan[0], LOW);//stop
digitalWrite(pan[1], LOW);//stop
digitalWrite(tilt[0], LOW);//stop
digitalWrite(tilt[1], LOW);//stop
}
}
}
}
this works like a treat and I am going to be working on creating an interface for it that uses visual basic to communicate and control the mount.
I hope you enjoyed this instructable, if you have any questions please feel free to ask