Parsing a response w/ no set terminator, varying length?
John Gonzales
Posts: 609
In the Pelco D protocol, the response string from the device contains no set termination character, the message can be of varying length (either 4,7,18 bytes), and the STX value ($FF) is sometimes used in the response string as data as well. What would be a good way to approach parsing this?
NDA prevents me from posting the whole protocol but here's an example of the 7 byte response messages. The 18 byte response is the same except it includes data 3..17:
So far the solution I'm going to use is to take the incoming message, throw it into a queue, test for the STX character ($FF), then keep looking at the 4th, 7th, and 18th characters to see if they add up to a checksum for the previous bytes. It just seems like a lot of testing overhead and a lot of room for errors. I'm wondering if there's a more efficient way of handling it.
Thanks!
--John
NDA prevents me from posting the whole protocol but here's an example of the 7 byte response messages. The 18 byte response is the same except it includes data 3..17:
EXTENDED RESPONSE
byte .....1..... |.....2.....|.....3.....|.....4..... |..... 5.....|.....6.....|.....7
........sync.....|... addr...|....resp1..|....resp2...|...data1....|...data2..|..chksm
........0xFF.....|...*var*...|....*var*..|....*var*..|...*var*....|...*var*...|..add bytes 2..6
So far the solution I'm going to use is to take the incoming message, throw it into a queue, test for the STX character ($FF), then keep looking at the 4th, 7th, and 18th characters to see if they add up to a checksum for the previous bytes. It just seems like a lot of testing overhead and a lot of room for errors. I'm wondering if there's a more efficient way of handling it.
Thanks!
--John
0
Comments
--John
http://www.232analyzer.com/RS232_Examples/CCTV/Pelco_D_Pelco_P_Examples_Tutorial.HTM
Might help others in helping you too - dunno!
If it is possible to make the assumption that each response will (in general) be received in a single data event, you could use create_multi_buffer and get_multi_buffer_string to retrieve each response and process it in turn until the buffer is emptied.
The general process would be:
while(len(buffer))
{
get_multi_buffer_string
if(valid and complete response)
{
do something...
}
}
On occasion responses from the device may be split across two data events, but it may be acceptible to discard these fragmented packets if you're polling the device.
Paul
That's originally what I was planning to do, but it just seems like there would be room for error as far as finding the end of the message.
The $FF can actually appear as data as well as the STX. For instance if the address of the camera responding is 255, the first two bytes of the response string would be $FF$FF (the message is formatted as "STX, Address, xx,xx,xx,..."). Plus, if there's only one response string and another one didn't come up for a while I could conceivably end up with the first $FF and not get another $FF for a while.
I think the fact that this device doesn't send unsolicited feedback helps out in this case. In the _comm module that I wrote for it, I actually parse commands from my UI module and each part of the parse builds the command string. The command string is STX, CamAddress, Cmd1, Cmd2, Data1, Data2, Checksum. Because of the way I build the command string I actually have the cmd1 byte, and the cmd2 byte stored . After reading more carefully it looks like I'll know what length the of the response should be based on the type of command I sent. Now I'm thinking that I can build a conditional or lookup table that parses the response string's expected length based on the value of cmd1 and cmd2.
This is an interesting situation though, having variable length messages with no ETX or delimiting character. I think this is the first time I've run across this, and it makes for an interesting exercise.
If anyone needs help with Pelco, I think I might be able to help out now
--John
Hello John,
yes, i think i need help with Pelco-D. I want to control a camera with a NI2100. The comport is set to 2400 baud,N,8,1 485 enable. Pin 1 is strapped to 9 (RS485 A) and pin 4 is strapped to 6 (RS485 . I only need to control the zoom, no feedback needed.
The string for zoom tele should be "$FF,$01,$00,$20,$00,$00,$21", zoom wide should be "$FF,$01,$00,$40,$00,$00,$41".
When i send this, nothing happens.
To find the error i got a cameracontroller wich supports pelco-D. All zoom functions work fine with this. I read the strings from the controller to the camera, for zoom tele i found this in my buffer: "$00,$7F,$7E,$FE,$FE,$7A,$00".
This is totally different to my string and to the Pelco-D protocol, but it works! When i send the same, nothing works.
Any Idea???
Thanks for your help.
I don't have my notes on the cabling with me but if I recall correctly the cabling was like this:
Your command string for zoom is correct, I'm not sure what the string was that you pulled into the buffer but it actually looks like a response string. I don't have time to confirm it right now though. I would change the port initialization string to:
I'm willing to share the module I wrote a little later if anyone would like it... but there may be no comments on my programming style .
--John