Go Down

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


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
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);

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);


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?


Cool project :)

What baud rate are you transmitting at, 2400?


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


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.


I'd be eternally greatful to you :)

Regards, Rick.

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131