 # How to get this Serial Checksum

I want to controll a PTZ Camera. I listened to the serial communication and can already emulate the Controller with the Arduino. These are some example Commands:

Speed Command

``````000 **RL**11*00*80*80*80*80*80*80*CD
001 **RL**11*00*80*81*80*80*80*80*CC
002 **RL**11*00*80*82*80*80*80*80*CB
010 **RL**11*00*80*8A*80*80*80*80*BC
020 **RL**11*00*80*94*80*80*80*80*C8
100 **RL**11*00*80*E4*80*80*80*80*BC
127 **RL**11*00*80*FF*80*80*80*80*A9
``````

The Value that controls the Speed is the 4th Byte after the RL (80 to FF), the Checksum must be the latest Byte. I made out, that if the Command increases the Checksum decreases. But it seams, like it's not always the same steps. Eg. 001 to 002 increases by 1, the Checksum decreases by one, but 010 to 020 the speed increases by 10, the Checksum increases by 12.

Can anyone tell me, how I can calcualte the Checksum in this case?

Have you checked the camera user guide or data sheet?

To calculate the checksum, it is necessary to know the exact details of what is transmitted.

What you have posted appears to be a mixture of ASCII characters and hex values, so please edit your post to show all the byte values in hexadecimal notation. Note: ASCII "*" is 0x2A.

Unfortunately there is no Documentation or Manual, it's a Proprietary System.

Here is the Command in RAW Hex:

``````000 > 2A 2A 52 4C 2A 2A 31 31 2A 30 30 2A 38 30 2A 38 30 2A 38 30 2A 38 30 2A 38 30 2A 38 30 2A 43 44
001 > 2A 2A 52 4C 2A 2A 31 31 2A 30 30 2A 38 30 2A 38 31 2A 38 30 2A 38 30 2A 38 30 2A 38 30 2A 43 43
002 > 2A 2A 52 4C 2A 2A 31 31 2A 30 30 2A 38 30 2A 38 32 2A 38 30 2A 38 30 2A 38 30 2A 38 30 2A 43 42
010 > 2A 2A 52 4C 2A 2A 31 31 2A 30 30 2A 38 30 2A 38 41 2A 38 30 2A 38 30 2A 38 30 2A 38 30 2A 42 43
020 > 2A 2A 52 4C 2A 2A 31 31 2A 30 30 2A 38 30 2A 39 34 2A 38 30 2A 38 30 2A 38 30 2A 38 30 2A 43 38
100 > 2A 2A 52 4C 2A 2A 31 31 2A 30 30 2A 38 30 2A 45 34 2A 38 30 2A 38 30 2A 38 30 2A 38 30 2A 42 43
127 > 2A 2A 52 4C 2A 2A 31 31 2A 30 30 2A 38 30 2A 46 46 2A 38 30 2A 38 30 2A 38 30 2A 38 30 2A 41 39
``````

Then you need a LOT of data to reverse-engineer the checksum.

It's likely to be a CRC-16 or something like that but there are many different formulas to calculate a CRC-16.

It can't be a simple sum if the bits of the presumed "checksum" don't change linearly with changes in the data.

It might be a CRC calculation, so I tried using the program reveng (for "reverse engineer" CRCs), which is really good. However, reveng does not find a solution for an 8 bit CRC, assuming that all values in the record are checked. Assuming a 16 bit CRC doesn't work either. I also tried running just the "numeric values" (see last entry below).

http://reveng.sourceforge.net/

Typical searches are as follows.

Are you sure about the exact data that are sent? It does not make sense that an 8 bit CRC would be sent as two ASCII characters, like 4344 (CD). Lots of other possibilities for interpreting those data records exist.

C:\Users\Jim\Desktop\reveng-1.3.1>reveng -s -w 8 2A2A524C2A2A31312A30302A38302A3
8302A38302A38302A38302A38302A4344 2A2A524C2A2A31312A30302A38302A38322A38302A3830
2A38302A38302A4342 2A2A524C2A2A31312A30302A38302A38412A38302A38302A38302A38302A4
243
reveng: no models found

C:\Users\Jim\Desktop\reveng-1.3.1>reveng -s -w 16 2A2A524C2A2A31312A30302A38302A
38302A38302A38302A38302A38302A4344 2A2A524C2A2A31312A30302A38302A38302A38302A383
02A38302A38302A4344 2A2A524C2A2A31312A30302A38302A38322A38302A38302A38302A38302A
4342
reveng: no models found

C:\Users\Jim\Desktop\reveng-1.3.1>reveng -s -w 16 2A2A524C2A2A31312A30302A38302A
38302A38302A38302A38302A38302A4443 2A2A524C2A2A31312A30302A38302A38302A38302A383
02A38302A38302A4443 2A2A524C2A2A31312A30302A38302A38322A38302A38302A38302A38302A
4243
width=16 poly=0xdc73 init=0xcb6b refin=false refout=false xorout=0x0000 ch
eck=0x14fe name=(none)

(try again with four records):

C:\Users\Jim\Desktop\reveng-1.3.1>reveng -s -w 16 2A2A524C2A2A31312A30302A38302A
38302A38302A38302A38302A38302A4443 2A2A524C2A2A31312A30302A38302A38302A38302A383
02A38302A38302A4443 2A2A524C2A2A31312A30302A38302A38322A38302A38302A38302A38302A
4243 2A2A524C2A2A31312A30302A38302A39342A38302A38302A38302A38302A3843
reveng: no models found

(try with just the "numeric" entries)
C:\Users\Jim\Desktop\reveng-1.3.1>reveng -s -w 8 1100808080808080CD 110080818080
8080CC 1100808280808080CB
reveng: no models found

Thanks for your Help, I got it!

It seams to be very simple. I just have to Add all the RAW Bytes as DEC, then Substract them from DEC 1685 to get the Checksum Value in DEC, confert it into HEX et voila!

That works at least for all the example Commands I sniffed.

What do you think?

Inchestin'.

But I don't understand your method. It would be good if you could post the code that does this calculation - what does "add as DEC" mean, and why is a conversions "confert into HEX" necessary?

The actual code would give the clearest answer.

Also… I am unfamiliar with reveng, but wouldn't the OP's method qualify and be detected as a degenerate CRC?

alto777

If it works with the camera, it works.

wouldn't the OP's method qualify and be detected as a degenerate CRC?

No, CRC is a type of multiply operation.

Thanks very much, also had a post in the german mikrocontroller.net FOrum, there I got the hint, to continue, what I was thinking about first.

It defenitely seams, like it is that easy :o . Here’s the code (tested in processing.org, since the Hardware is not available yet).

``````void sendString(int ADR, int PAN, int TILT, int ZOOM, int FOCUS, int IRIS) {

//Putting together the Commands
String cmdstr = "**RL**";
cmdstr = cmdstr + hex(ADR,1) + "1" + "*";
cmdstr = cmdstr + hex(00,2) + "*";
cmdstr = cmdstr + hex(PAN,2) + "*";
cmdstr = cmdstr + hex(TILT,2) + "*";
cmdstr = cmdstr + hex(ZOOM,2) + "*";
cmdstr = cmdstr + hex(FOCUS,2) + "*";
cmdstr = cmdstr + hex(IRIS,2) + "*";
cmdstr = cmdstr + hex(128,2) + "*";

//Calculating the Sum of the ASCII Characters
int SUM = 0;
for (int x = 0; x < cmdstr.length(); x++)
{
SUM = SUM + (byte(cmdstr.charAt(x)));
}

//Calculating the Checksumme (with the given calculated unique value of 1685)
int CHK = 1685 - SUM;

//Putting the Serial command together
cmdstr = cmdstr+hex(CHK,2);

//Print Debug
println(cmdstr);

//Print Serialcommand on myPort
myPort.write(cmdstr);
}
``````

The CRC calculation is a division.

Pete

Multiply is 1/division. In any case, the actual operation is XOR and shift.

Try inverting the 16-bit CRC polynomial 0x1021 and then multiplying it by a 256 bit message.
The division is implemented as XOR and shift because the arithmetic is done modulo-2. In effect, the XOR/shift is just a long division done with modulo-2 arithmetic.

Pete