PelcoD to control relays

tmack

Member
Hello, I am trying to make a relay board that would be activated by pelcoD. I found his link that sort of explains what the code is. I am wondering if anyone here could point me in the right direction on how to "decode" it using a picaxe to drive some relays.I have made a bunch of rs232 control circuits with help from the people here. Thanks for any help.

http://www.codeproject.com/KB/cs/PelcoPDinC.aspx\
 

Tom2000

Senior Member
The task seems fairly straightforward. The Pelco D protocol is very well defined in the document you've linked.

Set your program up to receive the 4800-N-8-1 serial link from the Pelco D controller.

Decide what commands will activate and release your relays.

Look for the STX character to begin your decoding. Capture the next four bytes. (You can probably ignore the ETX and cheksum bytes.)

Once you have those four bytes in hand, parse out the command and data to decide whether you need to enable or disable a relay.

The parse routine might be tricky to write. Depending upon the commands and data you need, it might be something as simple as a bunch of if..then..elseif statements, a select case statement, or an on.... gosub statement. Or it might be something more complex. Use your imagination. If you have control over the command structure sent by the Pelco D controller, try to bias those commands to make your parse routine as simple as possible.

Good luck!

Tom
 

tmack

Member
I guess Im dumber than I thought. Ive only been able to write simple rs232 code. What I have done so far is based on this receiver code:

Do
SerIn 3, N2400, b0
Select case b0
Case "0" : Low 0, 1, 2, 4
Case "1" : High 0
Case "2" : High 1
Case "3" : High 2
Case "4" : High 4
End Select
Loop

how would I change this to be able to "decode" the Pelco D. Im confused about what it would look like to recieve hexidecimal as well as what would I do with all of the characters.
I kinda get that the first byte is a sync byte, the second is an address byte,The next 2 i think are the commands that are listed in the site with the next 2 being data which I think is sending the items listed in that table on the sight. So I guess Im confused about alot right now. What would the code look like to read all of the hexidecimal recieved, What would I do with it next? What would be the bare minimum code to be abke to turn on 4 relays when the up,down,left,right are recieved? Thanks alot for any help I have been reading about rs232 but dont really seem to "get it"
 

Tom2000

Senior Member
Your first task is to study the protocol until you understand it thoroughly.

Next, you must decide how you plan to use the commands sent by the controller.

Until you've accomplished that, don't even think about writing any code.

Tom
 

Tom2000

Senior Member
how would I change this to be able to "decode" the Pelco D. Im confused about what it would look like to recieve hexidecimal as well as what would I do with all of the characters.
Here's one way to test bits within a hex or binary field.

Let's say that you've stored a received byte in b1, and you need to check the state of, say, the third bit from the right.

You'd mask that bit with an AND operation to determine its state, while ignoring all the other bits in that field.

b0 = b1 & %b00000100

if b0 > 0 then

...do what you need to do when that bit is set

else

...do what you need to do when that bit is cleared

Now... exactly what you do with this information depends upon the command or data you're processing, and how you've interpreted said data.

BTW... in addition to the stuff I mentioned in the message above, there's one more very important piece of information you need to glean and understand.

Once you've studied the protocol and become familiar with its command structure, you need to take a look at the system. What stimulus will cause the controller to send this command? What stimulus will cause the controller to send that command? What stimulus will cause the controler to send a different command?

Once you have a handle on that, you can finally answer the underlying question: what set of stimuli do I want to activate and release my relays?

Once you can answer that question, you can backtrack to the specific commands the controller will send to activate and release each individual relay. Conversely, if you can't answer that question, you can't design your program.

With that in hand, you can finally begin designing your program. But at the moment, it sounds as if you're way ahead of yourself.

Good luck!

Tom
 
Last edited:

tmack

Member
Thanks for trying to explain this to me. After looking over the C# example it would seem that for now all I am interested in is data 1 and data 2 .I would like to have a relay turn on when the Up Down Left and Right buttons are pushed on my Laptop running a pelco D program. I'm not really sure if I can just ignore the rest of the"words" Like the sync byte, address byte,or the 2 comms. I see that the up,down,left,right is put out in the data 2 portion of the code. Bit1 for right,bit2 for left,bit3 for up and bit4 for down.So say I pressed the softwares' up arrow, will my board that is attached be recieving 00001000 ? If so would code look like this?

Do
Serin 3,N4800,bo
bo=b1 & %boooo1ooo
if b0>0 then high 1
else low 1
Loop

Then when bit 4 is 0 the relay goes high
when bit 4 is 1 the relay goes low?
Or am I just still all confused?
Can I just ignore all of the rest of the stuff tha is being put out in the code?

Thanks ALOT for any help.
 

hippy

Technical Support
Staff member
Not exactly sure how the protocol works and I would suggest finding a description which doesn't confuse and mix Pelco P with Pelco B or bytes with word but here's how I'd start ...

Code:
Symbol MY_ADR  = $00	' Select Address for this PICAXE receiver

Symbol adr     = b0
Symbol cmd1    = b1
Symbol cmd2    = b2
Symbol dat1    = b3
Symbol dat2    = b4
Symbol chks    = b5

Symbol tmp     = b6

Symbol STX     = $FF

Symbol RX_PIN  = 3
Symbol RX_BAUD = N4800

Do
  Gosub GetPacket
  If adr = MY_ADR Then
    Gosub HandlePacket
  End If
Loop

GetPacket:
  Do
    SerIn RX_PIN,RX_BAUD,(STX),adr,cmd1,cmd2,dat1,dat2,chks
    tmp = STX ^ adr ^ cmd1 ^ cmd2 ^ dat1 ^ dat2 
  Loop Until tmp = chks
  Return
  
HandlePacket:
  b0 = cmd2
  If bit1 = 1 Then : Gosub MoveRight : End If
  If bit2 = 1 Then : Gosub MoveLeft  : End If
  If bit3 = 1 Then : Gosub MoveUp    : End If
  If bit4 = 1 Then : Gosub MoveDown  : End If
  Return
 

hippy

Technical Support
Staff member
The code should run on any PICAXE except the 08 and because you need 4800 baud an 08M will need to use N2400 baud and must be run at 8MHz ( SETFREQ M8 ).
 

tmack

Member
Connections?

I am going to try and build this over the next day or two using a 18X protoboard. I just have a couple of questions if someone doesn't mind. In the code it says "Symbol RX_PIN = 3" Does that mean I connect the transmit data pin from my rs232port (pin3) to the actual pin3 of my picaxe via the stereo jack that is usually for programming or should it be connected up to input pin3? If that is the way , How does it differentiate between when Im sending it rs232 and when I want to reprogram it ? I should just have to hook up pin 3 from my computers rs232 port and the ground because I am not looking for any data coming back from the 18X right? Thanks for any help. Im excited about this project.
 
Last edited:

hippy

Technical Support
Staff member
If you want run-time serial to an 18X you have to duplicate the download circuit ( the 10K/22K ) and take that to a digital input pin. On the X1's there's SERRXD but not on the 18X.
 

tmack

Member
Trouble shoot

I am having a little bit of difficulty getting this to work. All of the hardware is connected correctly I have tested it with a basic rs232 program which it works perfectly with. My sending side is pelcoD software that works fine for another product I have that is pelco D. I tried running it at 2400 and 4800 baud with no luck. Heres the actual code Im trying:

Symbol MY_ADR = $00 ' Select Address for this PICAXE receiver

Symbol adr = b0
Symbol cmd1 = b1
Symbol cmd2 = b2
Symbol dat1 = b3
Symbol dat2 = b4
Symbol chks = b5

Symbol tmp = b6

Symbol STX = $FF

Symbol RX_PIN = 2
Symbol RX_BAUD = N4800

Do
Gosub GetPacket
If adr = MY_ADR Then
Gosub HandlePacket
End If
Loop

GetPacket:
Do
SerIn RX_PIN,RX_BAUD,(STX),adr,cmd1,cmd2,dat1,dat2,chks
tmp = STX ^ adr ^ cmd1 ^ cmd2 ^ dat1 ^ dat2
Loop Until tmp = chks
Return

HandlePacket:
b0 = cmd2
If bit1 = 1 Then : Gosub MoveRight : End If
If bit2 = 1 Then : Gosub MoveLeft : End If
If bit3 = 1 Then : Gosub MoveUp : End If
If bit4 = 1 Then : Gosub MoveDown : End If
Return
moveright:
high 0
moveleft:
high 1
moveup:
high 2
movedown:
high 3


anhy ideas?
 
Last edited:

hippy

Technical Support
Staff member
First thing is to add some debugging code so you can use the Programming Editor Terminal to see what's going on ...

Code:
GetPacket:
Do
  SerTxd("Waiting for packet",CR,LF)
  SerIn RX_PIN,RX_BAUD,(STX),adr,cmd1,cmd2,dat1,dat2,chks
  SerTxd("Got Packet",CR,LF)
  tmp = STX ^ adr ^ cmd1 ^ cmd2 ^ dat1 ^ dat2
  if tmp <> chks Then
    SerTxd("Failed chacksum",CR,LF)
  End If
  Loop Until tmp = chks
  SerTxd("Passed checksum",CR,LF)
Return
This will give you a good idea of what is happening within the code, where it does or does not get to helps isolate what type of issue you may be having.
 

tmack

Member
What would I actually type in the "serin window" when Im debugging? Im a little confused (of course) on what the whole string or serial data looks like. Like for instance what would the line look like when my pelco D is sending out the up command? Would it look like this?
"FF 00 00 03 20 00 22"
 
Last edited:

hippy

Technical Support
Staff member
Easiest is to use two serial cables, the serial link from your Pelco D driver, and the download cable simply to monitor what comes back up via SERTXD.

If you only have one serial cable or serial port you'll need to send packet bytes to the SERIN Pin and monitor the download Serial Out pin. The Programming Editor Terminal doesn't allow sending of binary data, but my Terminal Emulator does ...

http://www.picaxeforum.co.uk/showthread.php?t=8961

Tick "Transmit->Send Whole Lines", tick "Transmit->Send Character Codes", enter "$FF $00 $00 $03 $20 $00 $AC" in the lowest text area, click the "#" button to the left of the Send button.

Note you'll have to hand calculate the checksums for each packet sent
 

tmack

Member
I seem to be getting more confused the further I go along. I found another link that seems to explain it a little more clearly.

http://www.commfront.com/RS232_Examples/CCTV/Pelco_D_Pelco_P_Examples_Tutorial.HTM#6

BUT for some reason Im missing something in my understanding of it. Is there any way you could show me an example of the most basic code that would work if I had the serial going into pin 2 of the board, an led on output pin0 and I think the pelcod software is putting out this:
FF 01 00 08 3F 00 48
---
Id like to just ignore everything right now other than the 4th Byte and just be able to make the led go on when input 2 somehow reads the 08 and everything else makes the led low. I guess I need to really move in small steps. Thanks so much for any help.
 

hippy

Technical Support
Staff member
Yes, it can get complicated quickly !

If you want to use a LED, first write a small program to check you can turn it on and off -

Do : Toggle 0 : Pause 500 : Loop

That will save any doubts about whether the LED is working later or not.

Instead of SERTXD, put a "HIGH 0" after the SERIN. That should light if you are receiving a packet. Then delete that and move HIGH 0 to outside the DO-LOOP, that will indicate you're getting a packet with a valid checksum. Only ever include a single HIGH 0 at a time.

This way you can determine where the program is getting to; if the LED comes on it got there, if it doesn't it didn't. By moving forward a step at a time you should be able to identify where there's an error. For example, if it lights at the end of GetPacket you know packets with valid checksums are getting through, if it doesn't light in Handle Packet then the logical analysis is that the address did not match. You can then go back and add an "If adr = $00 Then : High 0 : End If" to see if the address is being received as zero etc.

More complicated analysis favours SERTXD as it's obviously much easier to see what SERTXD("Address was ",#adr) reveals.
 

hippy

Technical Support
Staff member
From the link to the Pelco D page ...

"Byte 7 (Checksum) - sum of bytes (excluding the synchronization byte), then modulo 100 (Decimal code: 256)"

Different to what I'm sure the other site said. If tis is the case then the checksum calculation is wrong.

Change ...

tmp = STX ^ adr ^ cmd1 ^ cmd2 ^ dat1 ^ dat2

To ...

tmp = adr + cmd1 + cmd2 + dat1 + dat2
 

tmack

Member
Hippy, with that line changed as you said it is giving me some results.The code I am using now is(you were right that first site was "hinkey")

Symbol MY_ADR = $00 ' Select Address for this PICAXE receiver

Symbol adr = b0
Symbol cmd1 = b1
Symbol cmd2 = b2
Symbol dat1 = b3
Symbol dat2 = b4
Symbol chks = b5

Symbol tmp = b6

Symbol STX = $FF

Symbol RX_PIN = 2
Symbol RX_BAUD = N4800

Do
Gosub GetPacket
If adr = MY_ADR Then
Gosub HandlePacket
End If
Loop
GetPacket:
Do
SerTxd("Waiting for packet",CR,LF)
SerIn RX_PIN,RX_BAUD,(STX),adr,cmd1,cmd2,dat1,dat2,chks
SerTxd("Got Packet",CR,LF)
tmp = adr + cmd1 + cmd2 + dat1 + dat2
if tmp <> chks Then
high 7
SerTxd("Failed chacksum",CR,LF)
End If
Loop Until tmp = chks
high 0
SerTxd("Passed checksum",CR,LF)
Return

HandlePacket:
b0 = cmd2
If bit1 = 1 Then : Gosub MoveRight : End If
If bit2 = 1 Then : Gosub MoveLeft : End If
If bit3 = 1 Then : Gosub MoveUp : End If
If bit4 = 1 Then : Gosub MoveDown : End If
Return
moveright:
high 0
moveleft:
high 1
moveup:
high 2
movedown:
high 3


When I push "up" pins 2,3 go high
When I push "down" pin 3 only goes high
When I push "right" pins 1,2,3,4 go high
When I push "left" pins 1,2,3 go high
Now that we have it goign Hopefully I can tweek it from there . Thank you SO much for your guidance.
 
Last edited:

hippy

Technical Support
Staff member
You need some RETURNS after the HIGH's.

Also the lines will go high and stay high. You could try this ...

HandlePacket:
b0 = cmd2
outpin0 = bit1
outpin1 = bit2
outpin2 = bit3
outpin3 = bit4
Return
 

tmack

Member
Symbol MY_ADR = $00 ' Select Address for this PICAXE receiver

Symbol adr = b0
Symbol cmd1 = b1
Symbol cmd2 = b2
Symbol dat1 = b3
Symbol dat2 = b4
Symbol chks = b5

Symbol tmp = b6

Symbol STX = $FF

Symbol RX_PIN = 2
Symbol RX_BAUD = N4800
Low 3,4,5
Pause 50

Main:
Do
Gosub GetPacket
If adr = MY_ADR Then
Gosub HandlePacket
End If
Loop
GetPacket:
Do

SerTxd("Waiting for packet",CR,LF)
SerIn RX_PIN,RX_BAUD,(STX),adr,cmd1,cmd2,dat1,dat2,chks
SerTxd("Got Packet",CR,LF)
tmp = adr + cmd1 + cmd2 + dat1 + dat2
if tmp <> chks Then
high 7
SerTxd("Failed chacksum",CR,LF)
End If
Loop Until tmp = chks
SerTxd("Passed checksum",CR,LF)
Return

HandlePacket:
b0 = cmd2
outpin0 = bit1
outpin1 = bit2
outpin2 = bit3
outpin3 = bit4
outpin4 = bit5
outpin5 = bit6
outpin6 = bit7
pause 500
low 0,1,2,3
Goto Main


Thats what I have so far. But I have a couple of questions if you get the chance. When I start my pelco software it makes my 5th led go on(output4) until I select a different one (or reset)then it will go off. I tried putting a "low 4 " in different areas of my code but it either didn't do anything or it did, but also had other unwanted consequences. I may note that if I start the software and then plug in the picaxe it does not make the pin go high, However in my application I cant do it that way. My other question is :if I want to add the bits from cmd1 (to make my 8th output)sort of like this:
b1 = cmd1
and then
outpin7 = bit1

But I cant figure out how/where to add that to keep the above working and just add the 1 setting from cmd1.
Thanks again for any help.
 

hippy

Technical Support
Staff member
Note that Pelco D puts its bits into both cmd1 and cmd2 bytes and we're only using bits from cmd1 here.

Bit4 of cmd1 is "Auto/Manual Scan" so it is posisble it's meant to always be high or low depending on how the Pelco D PC software is configured. This is where it's necessary to understand what the semantics of the protocol are and I don't know any of that. Likewise when any bit is set or cleared, what has to be done is a mystery to me.

Once you're into the "HandlePacket" routine it's up to you to decide how the PICAXE reacts to what it receives and how it achieves that. At the moment it's really only a 'Pelco D packet sniffer' which shows what packet data bits were received, what they mean and what needs to be done is the next level of the protocol.
 

tmack

Member
How can I add this to what I have so far without messing it up? Any Idears? It will add one more function. It works on its own in the preceding code but when I try and put them both together under the "HandlePacket" it doesnt work correctly.

HandlePacket:
b0 = cmd1
outpin7 = bit0


return
I guess I need a way to keep the
b0 = cmd2
but also have it be able to check cmd1 bit 0 for its status and then turn output 7 high. I can use 2 18xs (set the 2nd one to the same code only use this second handle packet that monitors cmd1 and sets the other led high.) but it seems like I should be able to do both with one 18.

Im trying to get what your saying hippy but Im kinda thick..lol The way Im using this, am I getting the bit in both cmd1 and cmd2 when they are sent because I am using it as a "sniffer" ? So the basic way Im using it will make it impossible for the one 18X to differentiate if I try and have it look at both cmd1 and cmd2? Because all that it sees is data coming in or not. If that is the case then I wonder if I set one 18x to look at cmd1 and the another to look at cmd2 with the rs232 going to both,will that work to be able to "decode" the signal in its basic way and use all functions under the cmd1 and cmd2 bytes?
 
Last edited:

hippy

Technical Support
Staff member
I think you're going to have describe what the high level requirements are in more detail. Exactly what you need to happen and what the circumstances are which cause that to happen.
 

tmack

Member
Im just trying to get leds to turn on when I press the pelco rs232 "joystick". Then I can hook up whatever I want to control in place of the leds using transistors relays etc. Right now With the first seven I have so far, I can get seven leds to light when I connect to my computer running a pelcoD rs232 and press up,down,left,right, focus far,zoom out and zoom in. I would like to have an eighth led light when I press the focus near but that is found under command one and not command 2 like the rest of them.
 

hippy

Technical Support
Staff member
Okay, we're on the same page now. If you do the following ...

b0 = cmd1
b1 = cmd2

The following bit variables will be ...

bit0 - Focus near
bit1 - Iris Open
bit2 - Iris Close
bit3 - Camera On / Off
bit4 - Auto / Manual Scan
bit5 - Not used
bit6 - Not used
bit7 - Sense

bit8 - Zero
bit9 - Pan Right
bit10 - Pan Left
bit11 - Tilt Up
bit12 - Tilt Down
bit13 - Zoom Tele
bit14 - Zoom Wide
bit15 - Focus Far

Then it should just be a case of 'outpinX = bitY' for the bits you're interested in.
 

Hooter

Senior Member
Mccormack - Have you - or any other listeners - tried sending the Pelco-D packets from a picaxe to a PTZ. I have a PTZ connected to the DVR software which operates the PTZ correctly - so all connections etc are correct. I have connected the RS232 Analyser software to the RS232 to RS422/485 converter and sent the appropriate commands to pan left/pan right but to no avail.
What I envisage doing is sending packets to the PTZ on activation from my alarm/access control panel via a set of relay contacts connected to the picaxe input.
Any ideas folks?
Hooter
 

tmack

Member
Pelco D sender?

Id like to make a hand controller for my pelcod protocall device. Any ideas how I would go about actually building a sender that would use an 18x to send out the data to a pelco device to make it. Where to start with the code is the question. I can buy one pretty cheap if need be but wheres the fun in that? Any help is appreciated.
 

hippy

Technical Support
Staff member
That should be pretty straight forward. Just put what you need to send in a few byte variables, add those up to ceate a valid checksum and send ithose variables using SEROUT at the right baud rate.

If you need further help I can come back to this if you want ( bit busy at the present time ).
 
Top