Dynamixel code


//JDN oct 10 2018


// SEE: http://emanual.robotis.com/docs/en/dxl/protocol2/

// NB it you make pkgs longert than 30 then change below

// PROGRAM USES txPkg as package
// you chould change code a little so you have
// #define ARDUINO

#define PLGT 30
uint8_t txPkg[PLGT];


// PUT AND GET OFR 8/16/32 INTs

void putInt8t(int8_t v, int16_t pos)
{
  txPkg[pos] = v;
}

int8_t getInt8t(int16_t pos)
{
  return txPkg[pos];
}

void putInt16t(int16_t val, int16_t pos)
{
  txPkg[pos] = ( uint8_t)(val & 0x00ff);
  txPkg[pos + 1] = ( uint8_t)(val >> 8 );
}

int16_t getInt16t(int16_t pos)
{
  int16_t v = 0;
  v = txPkg[pos + 1];
  v = v << 8;
  v = v | txPkg[pos];
  return v;
}

void putInt32t(int32_t val, int16_t pos)
{
  for (int16_t i = 0; i < 4 ; i++) {
    txPkg[pos + i] = ( uint8_t)(val & 0x000000ff);
    val = val >> 8;
  }
}

int32_t getInt32t(int16_t pos)
{
  int32_t v = 0;
  for (int16_t i = 0; i < 4 ; i++) {
    v = v | (int32_t)txPkg[pos + i];
    v = v << 8;
  }
  return v;
}

// CRC16 PART
// see http://emanual.robotis.com/docs/en/dxl/crc/

#define ARDUINOMEMUSE
#ifdef ARDUINOMEMUSE
const uint16_t  crc_table[] PROGMEM = {
#else
const uint16_t  crc_table[] = {
#endif

  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
};


uint16_t calc_crc(uint16_t crc_accum,  uint8_t *data_blk_ptr, uint16_t data_blk_size)
{
  uint16_t i, j;

  for (j = 0; j < data_blk_size; j++)
  {
    i = ((uint16_t)(crc_accum >> 8) ^ data_blk_ptr[j]) & 0xFF;
#ifdef ARDUINOMEMUSE
    crc_accum = (crc_accum << 8) ^  pgm_read_word_near(crc_table + i);
#else
    crc_accum = (crc_accum << 8) ^ crc_table[i];
#endif
  }
  return crc_accum;
}

void add_crc( uint8_t *p, int16_t l)
{
  uint16_t crc;
  crc = calc_crc(0, p, l);
  putInt16t(crc, l);
}

boolean chk_crc(int16_t l)
{
  uint16_t calc, inPkg;

  inPkg = getInt16t(l - 2);

  calc = calc_crc(0, txPkg, l - 2);
  if (calc == inPkg)
    return true;
  else
    return false;
}

void setHdrAndID( uint8_t id)
{
  txPkg[0] = 0xff;
  txPkg[1] = 0xff;
  txPkg[2] = 0xfd;
  txPkg[3] = 0x00;
  txPkg[4] = id;
}


void dmpPkg( uint8_t *p,  int16_t l)
{
  for (int i = 0; i < l; i++) {
    Serial.print((int)p[i], HEX); Serial.print(" ");
  }
  Serial.println("");
}


void transmitPkg(int16_t l)
{
  for (int16_t i = 0; i < l; i++) {
    // Serial.write(txPkg[i]);  Serial/Serial1 or whatever
  }
}


void test1()
{
  uint16_t crc;
  uint8_t cc;
  /*
       Ping Instruction Packet
    0     1     2     3     4     5     6     7     8     9
    H1    H2    H3    RSRV  ID    LEN1  LEN2  INST  CRC1  CRC2
    0xFF  0xFF  0xFD  0x00  0x01  0x03  0x00  0x01  0x19  0x4E
  */
  setHdrAndID(0x01);
  putInt16t(3,5); // lgt is at pos 5,6
  putInt8t(0x01,7); // ping cmd at pos 7
  add_crc(txPkg, 8); // add crc to pkg
  // now we have a pkg og length 10 bytes (0..9)

  //testing
  Serial.println(calc_crc(0, txPkg, 8), HEX);
  Serial.println("should be 0x4e19");
  Serial.print("chksum in pkg added by add_crc is : ");
  Serial.println( getInt16t(8), HEX); // crc is at pos 8,9

  Serial.println("Lets see the raw pkg");
  dmpPkg(txPkg, 10);
  
  if ( chk_crc(10))
    Serial.println("chk sum is ok in pkg");
  else
    Serial.println("chksum is  bad");

  putInt16t(4, 5);
  Serial.println(getInt16t(5));
}

void setup() {
  Serial.begin(9600);

  test1();
}
void loop() {
  // put your main code here, to run repeatedly:

}
#include 

#define PLGT 30
unsigned char txPkg[PLGT];

void setL(unsigned char l)
{
  txPkg[5] = l;  // lsb int
  txPkg[6] = 0;  // msb int
}

void setHdr(unsigned char id)
{
  txPkg[0] = 0xff;
  txPkg[1] = 0xff;
  txPkg[2] = 0xfd;
  txPkg[3] = 0x00;
  txPkg[4] = id;
}

void doPing(char motorID)
{
  setHdr(motorID);
  setL(3);
  txPkg[7] = 0x01; // ping
  add_crc16(txPkg,10); // will place crc16 @ loc 8,9
}

void dmpPkg(unsigned char *p,  int l)
{
  for (int i = 0; i < l; i++) {
    Serial.print((int)p[i],HEX); Serial.print(" ");
  }
  Serial.println(" ende");
}
void setup() {
  Serial.begin(9600);
  doPing(0x01);
  Serial.print((int)txPkg[8],HEX); Serial.print(" "); Serial.println((int)txPkg[9],HEX);
  dmpPkg(txPkg,10);

}

void loop() {
  // put your main code here, to run repeatedly:

}

//JDN oct 10 2018


// SEE: http://emanual.robotis.com/docs/en/dxl/protocol2/

// NB it you make pkgs longert than 30 then change below

// PROGRAM USES txPkg as package
// you chould change code a little so you have
// #define ARDUINO

#define PLGT 30
uint8_t txPkg[PLGT];


// PUT AND GET OFR 8/16/32 INTs

void putInt8t(int8_t v, int16_t pos)
{
  txPkg[pos] = v;
}

int8_t getInt8t(int16_t pos)
{
  return txPkg[pos];
}

void putInt16t(int16_t val, int16_t pos)
{
  txPkg[pos] = ( uint8_t)(val & 0x00ff);
  txPkg[pos + 1] = ( uint8_t)(val >> 8 );
}

int16_t getInt16t(int16_t pos)
{
  int16_t v = 0;
  v = txPkg[pos + 1];
  v = v << 8;
  v = v | txPkg[pos];
  return v;
}

void putInt32t(int32_t val, int16_t pos)
{
  for (int16_t i = 0; i < 4 ; i++) {
    txPkg[pos + i] = ( uint8_t)(val & 0x000000ff);
    val = val >> 8;
  }
}

int32_t getInt32t(int16_t pos)
{
  int32_t v = 0;
  for (int16_t i = 0; i < 4 ; i++) {
    v = v | (int32_t)txPkg[pos + i];
    v = v << 8;
  }
  return v;
}

// CRC16 PART
// see http://emanual.robotis.com/docs/en/dxl/crc/

#define ARDUINOMEMUSE
#ifdef ARDUINOMEMUSE
const uint16_t  crc_table[] PROGMEM = {
#else
const uint16_t  crc_table[] = {
#endif

  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
};


uint16_t calc_crc(uint16_t crc_accum,  uint8_t *data_blk_ptr, uint16_t data_blk_size)
{
  uint16_t i, j;

  for (j = 0; j < data_blk_size; j++)
  {
    i = ((uint16_t)(crc_accum >> 8) ^ data_blk_ptr[j]) & 0xFF;
#ifdef ARDUINOMEMUSE
    crc_accum = (crc_accum << 8) ^  pgm_read_word_near(crc_table + i);
#else
    crc_accum = (crc_accum << 8) ^ crc_table[i];
#endif
  }
  return crc_accum;
}

void add_crc( uint8_t *p, int16_t l)
{
  uint16_t crc;
  crc = calc_crc(0, p, l);
  putInt16t(crc, l);
}

boolean chk_crc(int16_t l)
{
  uint16_t calc, inPkg;

  inPkg = getInt16t(l - 2);

  calc = calc_crc(0, txPkg, l - 2);
  if (calc == inPkg)
    return true;
  else
    return false;
}

void setHdrAndID( uint8_t id)
{
  txPkg[0] = 0xff;
  txPkg[1] = 0xff;
  txPkg[2] = 0xfd;
  txPkg[3] = 0x00;
  txPkg[4] = id;
}


void dmpPkg( uint8_t *p,  int16_t l)
{
  for (int i = 0; i < l; i++) {
    Serial.print((int)p[i], HEX); Serial.print(" ");
  }
  Serial.println("");
}


void transmitPkg(int16_t l)
{
  for (int16_t i = 0; i < l; i++) {
    // Serial.write(txPkg[i]);  Serial/Serial1 or whatever
  }
}


void test1()
{
  uint16_t crc;
  uint8_t cc;
  /*
       Ping Instruction Packet
    0     1     2     3     4     5     6     7     8     9
    H1    H2    H3    RSRV  ID    LEN1  LEN2  INST  CRC1  CRC2
    0xFF  0xFF  0xFD  0x00  0x01  0x03  0x00  0x01  0x19  0x4E
  */
  setHdrAndID(0x01);
  putInt16t(3,5); // lgt is at pos 5,6
  putInt8t(0x01,7); // ping cmd at pos 7
  add_crc(txPkg, 8); // add crc to pkg
  // now we have a pkg og length 10 bytes (0..9)

  //testing
  Serial.println(calc_crc(0, txPkg, 8), HEX);
  Serial.println("should be 0x4e19");
  Serial.print("chksum in pkg added by add_crc is : ");
  Serial.println( getInt16t(8), HEX); // crc is at pos 8,9

  Serial.println("Lets see the raw pkg");
  dmpPkg(txPkg, 10);
  
  if ( chk_crc(10))
    Serial.println("chk sum is ok in pkg");
  else
    Serial.println("chksum is  bad");

  putInt16t(4, 5);
  Serial.println(getInt16t(5));
}

void setup() {
  Serial.begin(9600);

  test1();
}
void loop() {
  // put your main code here, to run repeatedly:

}


/*
 * 
 * 
 * 
 */