How to Calculate an E1.20 RDM Checksum

A 0xCC checksum miss prints expected versus received and stays FAIL. Sum Start Code through Parameter Data, modulo 0x10000, excluding checksum slots. DUB sums twelve EUID bytes only.

Load Example and the DUB sample use these windows. The original TypeScript parser is covered by 23 Vitest cases. Paste a dump in the RDM Packet Decoder Online.

GET IDENTIFY 0xCC checksum window: body bytes 0-23 in the sum, slots 24-25 excluded, result 0x0530
Load Example GET IDENTIFY. Blue cells are in the sum. Red slots are compared only. Inclusive wrong total is 0x0565.

How is the E1.20 checksum calculated?

The 0xCC checksum is the unsigned 16-bit sum of Start Code through Parameter Data, modulo 0x10000, excluding checksum slots. A miss prints expected versus received and stays FAIL.

This site's adder is additiveChecksum16 in lib/rdm/checksum.ts. Each body byte is added, then masked with & 0xffff. That mask is modulo 0x10000. It is not a CRC. It is not a two's-complement subtract.

The stored value is two big-endian bytes. Their offset is Message Length. On a 26-byte IDENTIFY that offset is 24. Byte 24 is the high byte. Byte 25 is the low byte.

Fields can still be named after a miss. parseRdmFrame still fills UID, command class, and PID. ok stays false. The checksum field shows FAIL, not a corrected value.

Which bytes go into a 0xCC checksum?

Bytes 0 through Message Length minus one. Message Length sits at offset 2 and does not count the two checksum slots.

The body starts at Start Code 0xCC. It ends at the last parameter data byte. PDL 0 means the body is exactly 24 bytes. Manufacturer PID payloads still sit in that window. Unknown command class bytes still sit in that window. The adder does not skip a field it cannot name.

WindowBytesThis parser
0xCC bodyslice(0, messageLength)Unsigned 16-bit additive sum
Checksum slots2 bytes BE at messageLengthCompared. Not added.
DUB12 EUID bytes after 0xAASame adder. No 0xFE preamble.
ENTTEC wrap0x7E ... 0xE7Detect and refuse. No checksum.

How does Message Length set the checksum window?

Message Length is the byte at offset 2. It counts Start Code through parameter data. Frame size is that value plus two.

PDL must equal Message Length minus 24. Those two rules run before a checksum is trusted. A truncated UART line that still starts CC 01 will not get a fake PASS from a short sum.

If captured size is not Message Length plus two, this parser emits a length error. It does not shrink the window to the bytes you happened to paste. It does not pad zeros to force 26 slots.

How do I calculate a checksum for GET IDENTIFY?

Load Example is a 26-byte GET IDENTIFY_DEVICE from the same encoder the tests use. Sum the first 24 bytes. Compare with the last two as big-endian.

cc 01 18 09 c8 a0 10 00 00 09 c8 01 00 cd f9 01 01 00 00 00 20 10 00 00 05 30

Walk those 24 body bytes in order. Keep a 16-bit running total. After offset 23 the total on this sample is 0x0530. Then read the stored slots.

OffsetByteRunning sum after this byte
00xcc0x00cc
10x010x00cd
20x180x00e5
30x090x00ee
40xc80x01b6
50xa00x0256
60x100x0266
70x000x0266
80x000x0266
90x090x026f
100xc80x0337
110x010x0338
120x000x0338
130xcd0x0405
140xf90x04fe
150x010x04ff
160x010x0500
170x000x0500
180x000x0500
190x000x0500
200x200x0520
210x100x0530
220x000x0530
230x000x0530
SlotValue from this encoder
Message Length24
Expected sum0x0530
Stored checksum0x0530
ResultPASS
RDM checksum PASS 0x0530 versus FAIL 0x05cf after flipping the last stored byte
Flip the last byte. This parser emits CHECKSUM_MISMATCH. Expected 0x0530, received 0x05cf.

UID, PID, and command class can still render on that FAIL. The decode is not rewritten to PASS. Do not edit destination UID to chase a match until expected versus received is understood.

What if I include the checksum bytes in the sum?

You get a number that is not stored in the PDU. On this GET IDENTIFY that inclusive total is 0x0565. The slots still hold 0x0530.

Handheld calculators that "sum the whole paste" hit this trap. 0x0565 is 0x0530 plus 0x05 plus 0x30, then masked to 16 bits. This parser never compares against that wider sum.

The same trap exists on a longer frame. Adding the two checksum slots always moves the total. It never produces the value those slots were written to hold.

How does a GET_RESPONSE change the checksum window?

IDENTIFY GET_RESPONSE adds one flag byte. Message Length becomes 25. The extra 0x01 is inside the sum. Checksum slots move to the end of that longer body.

cc 01 19 09 c8 01 00 cd f9 09 c8 a0 10 00 00 01 00 00 00 00 21 10 00 01 01 05 33

This response is 27 bytes. Expected sum is 0x0533. Stored checksum is 0x0533. Command class 0x21 does not change the adder. Only the window length changes.

DEVICE_LABEL GET_RESPONSE is the same rule with a larger PDL. ASCII in the dump column is still body bytes. Checksum still stops before the last two slots. A pretty label with a FAIL checksum is a truncated paste or a typed nybble, not a decoder bug.

Why does my RDM packet checksum fail?

Common misses are checksum slots, leftover bytes, ENTTEC headers, or DUB 0xFE preambles. This parser names fields anyway. The decode stays FAIL.

  1. Confirm the dump starts CC 01, or is a DUB 0xFE/0xAA body, not 0x7E ... 0xE7.
  2. Read Message Length at offset 2. Frame size must be that value plus two.
  3. Confirm PDL equals Message Length minus 24.
  4. Sum only the body. Stop before the checksum slots.
  5. Compare expected versus received. Do not rewrite UID bytes to force a match.

A checksum miss is not a length miss. CHECKSUM_MISMATCH prints both 16-bit values. INVALID_MESSAGE_LENGTH and INVALID_PDL fire when those rules break. Fix length first.

How is a Discovery Unique Branch checksum calculated?

It is the additive 16-bit sum of the twelve encoded UID bytes after 0xAA. Preamble 0xFE bytes are not in the sum.

Discovery Unique Branch checksum window: 0xFE preamble excluded, twelve EUID bytes sum to 0x077b
Grey 0xFE cells are excluded. Teal EUID cells sum to 0x077b. Red cells are the encoded checksum.
fe fe fe fe fe fe fe aa ab 5d ea dd aa f5 ba 55 aa 55 aa 55 af 57 fb 7f

This sample has 7 preamble bytes, then 0xAA, then EUID ab 5d ea dd aa f5 ba 55 aa 55 aa 55. The 12-byte sum is 0x077b.

Flip the last encoded checksum byte and the code is DUB_CHECKSUM_MISMATCH. Expected 0x077b, received 0x0780. One dump cannot prove two responders versus a bad paste.

How are DUB checksum bytes encoded?

Each UID byte is stored as value OR 0xAA and value OR 0x55. Decode AND-merges the pair. The 16-bit checksum is encoded the same way into four bytes.

Sum the twelve encoded bytes, not the six decoded UID bytes. Summing 09c8:a0100000 as raw UID will not match 0x077b. Including the 0xFE preamble will not match either.

Mute and un-mute still travel as 0xCC PDUs with command class 0x10 or 0x11. Those use the 0xCC body window, not this DUB window. Do not feed a mute into the 12-EUID adder.

What happens if I sum an ENTTEC 0x7E-0xE7 wrapper?

This tool detects that envelope and refuses to unwrap it. A checksum is never run across widget headers.

Wrapping Load Example as 0x7E plus the PDU plus 0xE7 makes enttec with code ENTTEC_WRAPPED. Inner RDM may be fine. This page will not pretend it already stripped the widget.

Strip the wrap in capture software, then paste the 0xCC or DUB body. See the hex dump guide for dump shapes.

Can leftover bytes after 26 slots still PASS?

No. Extra bytes after a complete frame are reported. A passing sum on the first 26 slots is not enough.

Two Load Example pastes concatenated still checksum the first PDU. This parser then emits LEFTOVER_BYTES (). First-frame checksum pass is true. The overall decode is not PASS.

Concatenated GET plus GET_RESPONSE is the usual leftover paste. Decode one PDU at a time. Transaction numbers then tell you they belong together.

What should I paste next?

Paste the PDU in the RDM Packet Decoder Online. Read expected versus received on FAIL. Bytes stay in this browser.

If checksum is the only error, compare the two 16-bit values before rewriting UID. If length or PDL also fail, fix those first. Dialect questions belong on the hex dump guide, not in a wider checksum window.

Frequently asked questions

How is the E1.20 checksum calculated?

The 0xCC checksum is the unsigned 16-bit sum of Start Code through Parameter Data, modulo 0x10000, excluding checksum slots. A miss prints expected versus received and stays FAIL.

Does the 0xCC sum include checksum bytes?

No. Sum bytes 0 through Message Length minus one. Compare that total to the two big-endian bytes at offset Message Length.

What if I add the checksum slots into the total?

You get a number that is not stored in the PDU. On this GET IDENTIFY Load Example that wrong total is 0x0565. The slots still hold 0x0530.

How is a Discovery Unique Branch checksum calculated?

Sum the twelve encoded UID bytes after the 0xAA separator. Do not add preamble 0xFE bytes. The four checksum slots are nibble-encoded, then compared.

Why does my RDM packet checksum fail?

Common misses are checksum slots, leftover bytes, ENTTEC 0x7E-0xE7 headers, and DUB 0xFE preambles. This parser still names fields. The decode stays FAIL.

Can leftover bytes after 26 slots still PASS?

No. Extra bytes after a complete frame are reported. A passing sum on the first 26 slots is not enough.