Handling Strings with no delimiter
Andrew G Welker
Posts: 124
I'm working with a Pioneer PDP-614MX. This display doesn't have a set delimiter, instead it has a check sum which is calculated by adding up the bytes in the command and taking the lower 8 bits of the sum. I've included the code that I'm using to do this. Unfortunatley, I don't have a master or the display available to test the code out on, so I'm hoping and praying this works. If anyone sees anything that might stop this from working, let me know. Thanks.
Data_Event
CheckSum Function
Data_Event
data_event[dvDisplay] { online: { send_command dvDisplay,"'SET BAUD 9600,N,8,1 485 DISABLE'" send_command dvDisplay,"'HSOFF'" send_command dvDisplay,"'RXON'" } string: { stack_var char cCMD[255] stack_var char cMSG[255] stack_var integer i stack_var integer iDataLength stack_var integer iCheckSum stack_var integer iCalcCheckSum while(length_string(cDisplaybuffer)>0) { iDataLength = type_cast(mid_string(cDisplaybuffer,5,1)) iChecksum = type_cast(mid_string(cDisplayBuffer,6 + iDataLength,1)) cCMD = left_string(cDisplaybuffer,5+iDataLength) iCalcCheckSum = CheckSum(cCMd) if(iCalcCheckSum = iCheckSum) { cMsg = remove_string(cDisplaybuffer,"iCheckSum",1) ParseSocket(cMsg) } } } }
CheckSum Function
DEFINE_FUNCTION char CheckSum(char cMsg[]) { stack_var integer i stack_var integer iChkSum for(i=1;i<=length_array(cMsg);i++) { iChkSum = iChkSum + type_cast(cMsg[i]) } iChkSum = iChkSum % 256 return type_cast(iChkSum) }
0
Comments
One thing that bothers me is that if the checksum verification fails that the buffer cDisplaybuffer never gets emptied and your while loop runs a real long time -- almost forever. It appears to me that the only reason to do the checksum verification is to catch those occasions when there is a problem with the return string and then you need some sort of logic to sort out what's wrong and to get your parsing back in sync with the ack messages. A brief look at the protocol indicates to me that all ack messages start with $3F. Before you go extracting the checksum from the ack and comparing it to your calculated checksum, you might want to verify that the first character in the buffer is $3F. But, $3F may appear in other places besides the first character of the ack, so, depending on how bullet proof you want to make your code, you might want to make sure that the $3F at the start of the buffer is actually the start of the return message. That's probably overkill.
But, if there is a possibility that the checksum verification might fail, you need to have some code to empty out the buffer and prevent an infinite while loop and get synced back up.
Agree that there's not much reason to do the checksum verification. The only time I have ever bothered to verify the checksum of a device return string was when I was doing our recent "experience evaluation."
"% 256" (or $100) works, but for some reason I would prefer "BAND $FF". Don't know if there's a good reason to prefer one method over the other or not.
How do you feel about stuff like:
I would have thought it would throw an error because "mid_string()" returns a character array and I don't understand how a character array can get cast to an integer scalar. It appears to work, though. Rather than using "mid_string()" to extract an array of length 1, something like this looks better to me:
and the type_cast may be unnecessary.
Hedberg wrote: I might agree if I really had an understanding of how it works. The practical was the first I really ever dealt with this and I was happy to come up with the above solution. If nothing else the practical did force me to do figure that much out and the <<< >>> stuff.
I would prefer this method also: