Checksum calculation help.

I will do my best to explain what I am doing, but if I miss something please let me know.

I am using:
Arduino Mega
RS485 Shield.
ROBOTIS Dynamixel 'X' Series ( XM430-W210-R) Smart servos.

The library I am using does not support the 'Acceleration' feature I want to use.
I was able to generate this line of hex that worked,

byte M7[] =  {0xff, 0xff, 0xfd, 0x00, 0x03, 0x09, 0x00, 0x03, 0x70, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xff, 0x21};
Serial.write(M7, sizeof(M7));

FF,FF,FD,00 : this is the header with a reserved bit of '0'
03 : This is the address of the Dynamixel In this case ID#:3
09, 00 : This is how many remaing bytes to expect. not including these 2.
03 : This is the command to write data to the servo.
70 : This is the hex value of '112' Or the position in the control table of the servo, in this case it is Velocity.

00 : blank
AA : This is the hex value of '170' the Acceleration I want.
00, 00, 00 : Blank space.
FF, 21 : This is the CRC Checksum.

I am using protocol 2.0

Now with all of that said,

I want to generate the same above command, but instead of ID#3, I want to use the broadcast ID of 254 (0xFE).

The problem I am running into is the checksum (CRC) calculation,

They supply this example code,

Lets just say I am a bit confused on the implementation.

I am asking for pointers on how best to go about this calculation?

I only ever need to generate this once. so not sure if it is worth create the code to do so.


This looks like it may do it.

const unsigned short crc_table[256] = {0x0000,
                                0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
                                0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027,
                                0x0022, 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D,
                                0x8077, 0x0072, 0x0050, 0x8055, 0x805F, 0x005A, 0x804B,
                                0x004E, 0x0044, 0x8041, 0x80C3, 0x00C6, 0x00CC, 0x80C9,
                                0x00D8, 0x80DD, 0x80D7, 0x00D2, 0x00F0, 0x80F5, 0x80FF,
                                0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1, 0x00A0, 0x80A5,
                                0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1, 0x8093,
                                0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
                                0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197,
                                0x0192, 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE,
                                0x01A4, 0x81A1, 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB,
                                0x01FE, 0x01F4, 0x81F1, 0x81D3, 0x01D6, 0x01DC, 0x81D9,
                                0x01C8, 0x81CD, 0x81C7, 0x01C2, 0x0140, 0x8145, 0x814F,
                                0x014A, 0x815B, 0x015E, 0x0154, 0x8151, 0x8173, 0x0176,
                                0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162, 0x8123,
                                0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
                                0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104,
                                0x8101, 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D,
                                0x8317, 0x0312, 0x0330, 0x8335, 0x833F, 0x033A, 0x832B,
                                0x032E, 0x0324, 0x8321, 0x0360, 0x8365, 0x836F, 0x036A,
                                0x837B, 0x037E, 0x0374, 0x8371, 0x8353, 0x0356, 0x035C,
                                0x8359, 0x0348, 0x834D, 0x8347, 0x0342, 0x03C0, 0x83C5,
                                0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1, 0x83F3,
                                0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
                                0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7,
                                0x03B2, 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E,
                                0x0384, 0x8381, 0x0280, 0x8285, 0x828F, 0x028A, 0x829B,
                                0x029E, 0x0294, 0x8291, 0x82B3, 0x02B6, 0x02BC, 0x82B9,
                                0x02A8, 0x82AD, 0x82A7, 0x02A2, 0x82E3, 0x02E6, 0x02EC,
                                0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2, 0x02D0, 0x82D5,
                                0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1, 0x8243,
                                0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
                                0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264,
                                0x8261, 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E,
                                0x0234, 0x8231, 0x8213, 0x0216, 0x021C, 0x8219, 0x0208,
                                0x820D, 0x8207, 0x0202 };

void dxlUpdateCrc(uint16_t *p_crc_cur, uint8_t data_in)
  uint16_t crc;
  uint16_t i;

  crc = *p_crc_cur;

  i = ((unsigned short)(crc >> 8) ^ data_in) & 0xFF;
  *p_crc_cur = (crc << 8) ^ crc_table[i];

And I think I got it,

What I need = {0xff, 0xff, 0xfd, 0x00, 0xFE, 0x09, 0x00, 0x03, 0x70, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x1b, 0xcd};

For anyone with the same problem in the future,

I used this,

The section CRC-16/BUYPASS was what I used, I had to swap the numbers.
Example if it shows AABB you will switch it to 0xBB 0xAA

So my final header code is this,

Serial.begin(1000000); // serial for the USB port monitor / debug //57600 is stock speed.

byte M2[] =  {0xff, 0xff, 0xfd, 0x00, 0xFE, 0x03, 0x00, 0x01, 0x31, 0x42};
byte M3[] =  {0xff, 0xff, 0xfd, 0x00, 0xFE, 0x06, 0x00, 0x03, 0x40, 0x00, 0x00, 0x2e, 0x16};
byte M4[] =  {0xff, 0xff, 0xfd, 0x00, 0xFE, 0x06, 0x00, 0x03, 0x0b, 0x00, 0x03, 0xb8, 0x13};
byte M5[] =  {0xff, 0xff, 0xfd, 0x00, 0xFE, 0x06, 0x00, 0x03, 0x40, 0x00, 0x01, 0x2b, 0x96};
byte M6[] =  {0xff, 0xff, 0xfd, 0x00, 0xFE, 0x09, 0x00, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x65};
byte M7[] =  {0xff, 0xff, 0xfd, 0x00, 0xFE, 0x09, 0x00, 0x03, 0x70, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x1b, 0xcd};

Serial.write(M3, sizeof(M3));
Serial.write(M4, sizeof(M4));
Serial.write(M5, sizeof(M5));
Serial.write(M6, sizeof(M6));
Serial.write(M7, sizeof(M7));

Put that before the dxl.begin.

This will send the velocity of 170 to all servos on the chain, and ping them to start.

I know there is better ways to do this, but like I said, I only needed this once per power cycle.