Go Down

Topic: Pelco D PTZ Camera Control with Dual Axis Hall Joystick (Read 18833 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);


Cool project :)

What baud rate are you transmitting at, 2400?


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.


Hello, your article is good!

Could you help me by indicating how you could try a panTilt without a joystick?
I say this thinking that it moves only with code, in an automated way creating some simple sequences.

Thank you very much for your contribution!

Go Up