Go Down

Topic: Pelco D PTZ Camera Control with Dual Axis Hall Joystick (Read 5 times) previous topic - next topic

UncleBone

Jul 26, 2011, 04:52 am Last Edit: Jul 26, 2011, 04:58 am by UncleBone Reason: 1
I've had a PTZ camera for a while and finally tried to control pan and tilt with a home made shield. It makes use of the Pelco D protocol on RS-485 and with a little patience it works pretty good. The check sum is calculated "on the fly" since I was expecting it to change with the variable speeds. While it works, I stopped short of finishing the speed control because my camera does not support it. Maybe if I get another camera.  

The only other additions I'm currently considering is controlling zoom/focus when the green button on the joystick is pressed and adding a couple of buttons to select which camera to operate.

Since the RS-485 is only transmitting, the wiring is very simple.
Code: [Select]
        /*
Pelco D pan/tilt camera control using a dual axis hall effect joystick and a SP485EE, RS-485 transceiver IC with software serial
Original intention was to have variable speeds but abandoned it when I found my camera didn't support it
Buttons and IR remote were also implemented satisfactorily
unclebone 2011
 
        SP485EE
         ____
nc --- 1|    |8 --- +5
+5 --- 2|    |7 --- RS-485 - black wire to cam
+5 --- 3|    |6 --- RS-485 + white wire to cam
pin8 - 4|____|5 --- GND
*/

#include <SoftwareSerial.h>
const byte recPin = 7; //not receiving anything back, any unused pin will do
const byte xMitPin = 8;
const int xAxis = A1;  //Up Down - Joystick output to analog pin 1
const int yAxis = A2;  //Left Right - Joystick output to analog pin 2
const byte tiltDown = 0x10;
const byte tiltUp = 0x08;
const byte panLeft = 0x04;
const byte panRight = 0x02;
int xVal = 0;
int yVal = 0;

SoftwareSerial mySerial =  SoftwareSerial(recPin, xMitPin);

void setup(){
 pinMode(recPin, INPUT);
 pinMode(xMitPin, OUTPUT);
 mySerial.begin(2400);
}

void loop(){
 yVal = analogRead(yAxis);
 xVal = analogRead(xAxis);
 if(xVal > 600){
   functionXmit(0x01, tiltUp, 0x00);
     while(xVal > 600){
       xVal = analogRead(xAxis);
     }
 }
 if(xVal < 450){
   functionXmit(0x01, tiltDown, 0x00);
     while(xVal < 450){
       xVal = analogRead(xAxis);
     }
 }
 if(yVal > 600){
   functionXmit(0x01, panLeft, 0x00);
     while(yVal > 600){
       yVal = analogRead(yAxis);
     }
 }
 if(yVal < 450){
   functionXmit(0x01, panRight, 0x00);
     while(yVal < 450){
       yVal = analogRead(yAxis);
     }
 }
 halt();
}


//Camera #, Speed 0x00 - 0x3F. SPEED NOT IMPLEMENTED. MY CAMERA DOES NOT SUPPORT!!!!!!


void functionXmit(byte camNum, byte funcVal, byte speedVal){
 int modSum = 0;
 byte dataVal[6] ={0xFF, camNum, 0x00, funcVal, speedVal, speedVal};
     for(int i=0; i<6; i++){
       mySerial.print(dataVal[i], BYTE);
       if(i > 0)      //dont add in the SYNC byte to calculate the check sum
         modSum += dataVal[i];
     }
     modSum %= 100;      //PelcoD calls for the check sum to to be the sum of bits 2 - 6 modulo 256. 256 decimal, or 100 hex
     mySerial.print(modSum, BYTE);
}

void halt(){
           //sync  cam#  Command1  Command2  Data1  Data2  CheckSum
 byte dataVal[7] ={0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01};   //This is the most basic instruction. Camera 1, four zeros and a check sum of one
     for(int i=0; i<7; i++){
       mySerial.print(dataVal[i], BYTE);
     }
}


Why do it right the first time, when building and rebuilding is  so much fun?

TonyD

Cool project :)

What baud rate are you transmitting at, 2400?

UncleBone

Why do it right the first time, when building and rebuilding is  so much fun?

rickpbush

Hi there, I'm trying to do this but thus far have had no success, please could you take a look at my project and offer me some advice.


http://forum.arduino.cc/index.php?topic=230959.0


I'd be eternally greatful to you :)

Regards, Rick.

Go Up