Serial RS232 Communication Checksums?

不想你离开。 提交于 2019-12-20 07:15:13

问题


I am communicating with a servo via RS232 serial. The built-in functions that came with my servo are too slow (25 ms for a simple 54 byte message on a 57,600 baud port), so I am trying to write my own communication functions, however the built-in functions are not documented. I have used a port monitor to determine what information is being sent to the servo and I need help deciphering the results. I used the built-in functions to command the servo to "goto" incrementally increasing steps (1, 2, 3, etc.). This resulted 5 packets being sent to the servo for each "goto" command. The first 4 packets are identical for each "goto" command. I have attached about 50 hex packet below (1 per line). If you need more, post, and we can work something out.

10 13 04 20 00 01 B6 24 E9 68 10 13 04 20 00 00 AE 24 54 82 10 13 04 20 00 00 B5 24 8B 0B 10 13 04 20 00 01 43 01 71 9B

The 5th packet varies based on the step the motor is being commanded to move to. I have included 1 packet here as an example. I have attached a file with about 1000 of these packets (1 per line).

10 13 08 20 03 01 11 25 0A 00 00 00 81 CF

The first 8 bytes of this packet (10 13 08 20 03 01 11 25) appear to be the actual "goto" command. They remain the same no matter what step is specified. The last 6 bytes (0A 00 00 00 81 CF) change based upon the step that is requested. In the file I attached, I instructed the servo to initially goto step "0", then "1", "2", etc. The first 4 bytes appear to be a little-endian integer corresponding to the number of steps (i.e. the sample command I showed above instructs the servo to goto step 10 decimal). My question regards the last 2 bytes of the command. They appear to vary randomly, but whenever the specified step is the same they match. This leads me to believe that these 2 bytes are a checksum of some kind. My question to you is: how is the checksum calculated? I have already tried xor'ing all the bytes, both singly and in 2 byte pairs, and I tried Fletcher's checksum, and a simple checksum (sum of all bytes). I also checked the 2's complement of each of these methods (though I certainly wouldn't mind someone checking to make sure I didn't make a mistakes in the calculations). Does anyone have any ideas?

10 13 08 20 03 01 11 25 00 00 00 00 E9 64

10 13 08 20 03 01 11 25 01 00 00 00 9F D0

10 13 08 20 03 01 11 25 02 00 00 00 04 0C

10 13 08 20 03 01 11 25 04 00 00 00 23 95

10 13 08 20 03 01 11 25 05 00 00 00 55 21

10 13 08 20 03 01 11 25 06 00 00 00 CE FD

10 13 08 20 03 01 11 25 07 00 00 00 B8 49

10 13 08 20 03 01 11 25 08 00 00 00 6C A7

10 13 08 20 03 01 11 25 09 00 00 00 1A 13

10 13 08 20 03 01 11 25 0A 00 00 00 81 CF

10 13 08 20 03 01 11 25 0C 00 00 00 A6 56

10 13 08 20 03 01 11 25 0D 00 00 00 D0 E2

10 13 08 20 03 01 11 25 0F 00 00 00 3D 8A

10 13 08 20 03 01 11 25 10 10 00 00 00 17 FA

10 13 08 20 03 01 11 25 11 00 00 00 84 77

10 13 08 20 03 01 11 25 12 00 00 00 1F AB

10 13 08 20 03 01 11 25 13 00 00 00 69 1F

10 13 08 20 03 01 11 25 14 00 00 00 38 32

10 13 08 20 03 01 11 25 15 00 00 00 4E 86

10 13 08 20 03 01 11 25 16 00 00 00 D5 5A

10 13 08 20 03 01 11 25 17 00 00 00 A3 EE

10 13 08 20 03 01 11 25 18 00 00 00 77 00

10 13 08 20 03 01 11 25 19 00 00 00 01 B4

10 13 08 20 03 01 11 25 1A 00 00 00 9A 68

10 13 08 20 03 01 11 25 1B 00 00 00 EC DC

10 13 08 20 03 01 11 25 1C 00 00 00 BD F1

10 13 08 20 03 01 11 25 1D 00 00 00 CB 45

10 13 08 20 03 01 11 25 1E 00 00 00 50 99

10 13 08 20 03 01 11 25 1F 00 00 00 26 2D

10 13 08 20 03 01 11 25 20 00 00 00 DE 2A

10 13 08 20 03 01 11 25 21 00 00 00 A8 9E

10 13 08 20 03 01 11 25 22 00 00 00 33 42

10 13 08 20 03 01 11 25 24 00 00 00 14 DB

10 13 08 20 03 01 11 25 25 00 00 00 62 6F

10 13 08 20 03 01 11 25 26 00 00 00 F9 B3

10 13 08 20 03 01 11 25 27 00 00 00 8F 07

10 13 08 20 03 01 11 25 28 00 00 00 5B E9

10 13 08 20 03 01 11 25 29 00 00 00 2D 5D

10 13 08 20 03 01 11 25 2A 00 00 00 B6 81

10 13 08 20 03 01 11 25 2B 00 00 00 C0 35

10 13 08 20 03 01 11 25 2C 00 00 00 91 18

10 13 08 20 03 01 11 25 2D 00 00 00 E7 AC

10 13 08 20 03 01 11 25 2E 00 00 00 7C 70

10 13 08 20 03 01 11 25 2F 00 00 00 0A C4

10 13 08 20 03 01 11 25 30 00 00 00 C5 8D

10 13 08 20 03 01 11 25 31 00 00 00 B3 39

10 13 08 20 03 01 11 25 32 00 00 00 28 E5

10 13 08 20 03 01 11 25 33 00 00 00 5E 51

10 13 08 20 03 01 11 25 34 00 00 00 0F 7C

10 13 08 20 03 01 11 25 35 00 00 00 79 C8

10 13 08 20 03 01 11 25 36 00 00 00 E2 14

10 13 08 20 03 01 11 25 37 00 00 00 94 A0

10 13 08 20 03 01 11 25 38 00 00 00 40 4E

10 13 08 20 03 01 11 25 39 00 00 00 36 FA

10 13 08 20 03 01 11 25 3A 00 00 00 AD 26

10 13 08 20 03 01 11 25 3B 00 00 00 DB 92

10 13 08 20 03 01 11 25 3C 00 00 00 8A BF

10 13 08 20 03 01 11 25 3D 00 00 00 FC 0B

10 13 08 20 03 01 11 25 3E 00 00 00 67 D7

10 13 08 20 03 01 11 25 3F 00 00 00 11 63


回答1:


this is a late answer, but hopefully this can help for other CRC re-engineering tasks:

Your CRC is a derivation of the so-called "16 bit width CRC as designated by CCITT", but with "init value zero".

The CRC is calculated from byte position 3 to byte position 12 of your example data. e.g.

08 20 03 01 11 25 00 00 00 00

The full CRC specification according to our CRC specification overview is:

CRC:16,1021,0000,0000,No,No

The problem was not only to find the right CRC polynomial, but finding the following answers:

  • Which part of the data is included in the CRC calculation, and which is not.
  • Which init value to use? Apply final xor value?
  • Does this algorithm expect reflected input or output values?

Again, see our manual description or the Boost CRC library on what this means.

What I did is running a brute-force script that simply tries out several popular 16 bit CRC polynomials with all kinds of combinations of start/end positions, initial values, reflected versions. Here is how the processing output looked:

 Finding CRC for test message (HEX): 10 13 08 20 03 01 11 25 00 00 00 00 E9 64
 Trying CRC spec : CRC:16,1021,FFFF,0000,No,No
 Trying CRC spec : CRC:16,8005,0000,0000,No,No
 Trying CRC spec : CRC:16,8005,FFFF,0000,No,No
 Trying CRC spec : CRC:16,1021,FFFF,FFFF,No,No
 Trying CRC spec : CRC:16,1021,0000,FFFF,No,No
 Trying CRC spec : CRC:16,1021,0000,0000,No,No
 Found it!
 Relevant sequence for checksum from startpos=3 to endpos=12
 08 20 03 01 11 25 00 00 00 00
 CRC spec:   CRC:16,1021,0000,0000,No,No
 CRC result: E9 64 (Integer = 59748)

With the result I could re-calculate the checksum of your example telegrams correctly

19.09.2016 12:18:12.764 [TX] - 10 13 08 20 03 01 11 25 00 00 00 00 E9 64 
19.09.2016 12:18:14.606 [TX] - 10 13 08 20 03 01 11 25 01 00 00 00 9F D0 
19.09.2016 12:18:16.030 [TX] - 10 13 08 20 03 01 11 25 02 00 00 00 04 0C 

I uploaded the documented CRC finder example script which works with the free Docklight Scripting V2.2 evaluation. I assume this can be very useful for other CRC re-engineering puzzles, too.

The example also helped to solve Stackoverflow question 22219796



来源:https://stackoverflow.com/questions/29850992/serial-rs232-communication-checksums

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!