adding hex bytes to calc checksum
samos
Posts: 106
What is the easiest way to add a group of bytes together. The NEC projectors want you to add the command bytes together then append the lower byte of the total to the command. I did this long ago and forgot how. Any help or code sample would be great.
0
Comments
I use the addition operator (+). Is there an easier way I don't know about?
Paul
INTEGER nSum = byte1 + byte2 + byte3 etc.
Next step would be to get the lower 8 bit of the sum
CHAR cChk = TYPE_CAST(nSum % 256) // get checksum byte
TYPE_CAST is required to prevent a compiler warning because an INTEGER is tried to write in a CHAR.
Thanks Marc Scheibein I had everything right but the TYPE_CAST()
define_function char fChecksum(char cCommand[])
{
stack_var char nChkSum
stack_var integer i
for(i=1;i<=length_array(cCommand);i++)
{
nChkSum = nChkSum + cCommand
if (nChkSum > 255) // if the checksum goes over 1 byte subtract by 255
{
nChkSum = nChkSum - 255 // don't know if I need this but it works
}
}
return nChkSum
}
so I can do something like:
send_string dvproj,"cProjCmd,fChecksum(cProjCmd)"
When I want to send a command that needs a checksum calculated, what is the proper syntax? I was trying it like this: But when trying to debug, I don't see the stack_var i, to indicate that the for loop ever ran. Is it simply running too fast for me to see, since the stack_var resets itself to 0 when it's done? I found it to be odd that when I dragged the stack_vars into the debug window, the value and display types never populated. Can I not debug these?
I defined a constant above as: In the hope that I could simply refer to the constant when doing the SEND_STRING. I understand that the function is returning an integer, which is what I want, since the idea here is to simply add the hex values together to come up with the checksum. What am I doing wrong?
You also should change your return data type of the function from INTEGER to CHAR and like the previous post or Marc's post do something in case your checksum total is over 1 byte.
i gets set to 1 every time in your for loop initialization, however ckSum will already be holding its previous value every time the function is entered. If you're going to keep ckSum as a local so that you can monitor it you will need to reset it back to 0 before you start using it:
As TurnipTruck said it might be nice to use a binary and to just get the lower 8 bits: note: ckSum has been changed to an integer to prevent any wrap around issues.
Yes, it’s incorrect. You’ve created a 19 character array which means i will equal 20 when the FOR loop ends.
You’ll want to lose the double quotes and do this instead:
Now you’ve got a 5 character array.
The rest of your code looks fine but like PhreaK said you’ll need to do a reset of your local_var (ckSum=0) every time you enter the function.
Personally I would just leave ckSum as a CHAR (as you have it) and just RETURN it as is when it exits the FOR loop.
Have fun.
Thanks everyone for your posts. I've got just about everything together to make this work, but there is one more piece I'm unsure of - the protocol guide states that when the projector sends a reply, it also calculates its own checksum, which is different than the checksum I am sending. Awesome. It is calculated the same way, but with different starting hex bytes. I am trying to use the same checksum function as before, since it calcs the same, but I'm getting stuck on a few parts.
In my data event, I am looking for the response string(s) from the projector: I can copy the last bit from the return string, so that I can calculate that against what the checksum SHOULD be, by using Right_String. Since Right_String is not destructive, I needed a way to remove the checksum hex from the rest of the response, so I was trying something with the garbage = line, but it isn't working at all. As I try to debug it, nothing happens to the garbage variable. My thought was to use remove_string, looking for the value inserted into locatedCkSum previously, and starting at the end of the string, using a length_string minus 1 calculation. Can someone shed some light on this for me? Thanks.
Update - I've been able to get the checksum function running in both the send_string and data_event portions of my code, so Happy Day! I do have a preference question on the data event, though. What would be my best option for updating my panel's button and variable text feedback, now that I have checksum values to compare? Something like this? My IF statement will not compile because ckSum is a return value from the function call, and the compiler says it is not defined otherwise. Is the return value from a function like a local variable, where it can only be referenced inside that event? I tried getting around it by creating another global CHAR to copy the return value into, but that doesn't work. Is there another way to compare the two checksum values?
I am hung up on the same issue. I've tried moving things around with no luck. Any hints?
STRING:
{
STACK_VAR CHAR cProjData [100]
STACK_VAR CHAR cReplyCks [1]
SELECT
{
ACTIVE(FIND_STRING(sProjBuf,"$22,$00,$00,$D0,$00",1)):
{
cProjData=calcChkSum(LEFT_STRING(sProjBuf, LENGTH_STRING(sProjBuf-1)))
//set_length_string (sCmd, length_string (sCmd) - 1)
//(LENGTH_STRING(STRING) > 0)
cReplyCks=(RIGHT_STRING(sProjBuf,1)
IF(cProjData == cReplyCks)
{
ON[nProjPwr]
}
}
}
}
}
BUTTON_EVENT[dvTP_Proj,255]
{
PUSH:
{
IF(!nProjPwr)
{
SEND_STRING dvProjector, "POWER_ON,calcChkSum(POWER_ON)"
}
ELSE
{
SEND_STRING dvProjector, "POWER_OFF,calcChkSum(POWER_OFF)"
}
}
}
I agree entirely. About the only time I consider a checksum to be necessary is when you are using a less-than-perfect communications path. Examples would be PLC lighting controls, radio modems, etc.
There is no reason why a device five feet from a controller with a hardwired connection would require a checksum.
Why wouldn't you just always implement it so that it doesn't matter how good of a connection you have or any other issue at hand? At least then you know it will always work regardless of the installation.
Paul
Simple answer... extra work.
The only time I could think of that we would decide whether or not to implement a checksum would be in M2M communication. In that case, the AMX system handles message delivery accuarcy.