dynamixel protocal by Liews Wuttipat.

Revision:
0:e4ba03a21caa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Dynamixel.cpp	Fri Dec 08 23:32:57 2017 +0000
@@ -0,0 +1,223 @@
+#include <mbed.h>
+#include <Dynamixel.h>
+
+uint8_t Instruction_Packet[15];     // Array to hold instruction packet data
+uint8_t Status_Packet[8];           // Array to hold returned status packet data
+uint8_t Status_Return_Value = READ; // Status package return states (NON, READ, ALL)
+
+Timer timer;
+//-------------------------------------------------------------------------------------------------------------------------------
+//            Private Methods
+//-------------------------------------------------------------------------------------------------------------------------------
+void Dynamixel::writePacket(void)
+{
+    if (dynamixelSerial->readable())
+        while (dynamixelSerial->readable())
+            dynamixelSerial->getc();
+    dynamixelDi->write(1);
+    dynamixelSerial->putc(HEADER);
+    dynamixelSerial->putc(HEADER);
+    dynamixelSerial->putc(Instruction_Packet[0]);
+    dynamixelSerial->putc(Instruction_Packet[1]);
+    for (uint8_t i = 0; i < Instruction_Packet[1]; i++)
+    {
+        dynamixelSerial->putc(Instruction_Packet[2 + i]);
+    }
+    wait_us((Instruction_Packet[1] + 4) * 5);
+    dynamixelDi->write(0);
+}
+
+unsigned int Dynamixel::readPacket(void)
+{
+    // wait_us(250);
+    // uint8_t Counter = 0;
+    // uint8_t InBuff[20];
+    // uint8_t i = 0, j = 0, RxState = 0;
+    // Status_Packet[0] = 0;
+    // Status_Packet[1] = 0;
+    // Status_Packet[2] = 0;
+    // Status_Packet[3] = 0;
+    // timer.start();
+    // int bytes = 2;
+    // int timeout = 0;
+    // int plen = 0;
+    // // while (timer.read_ms() < 3000)
+    // // {
+    // //     if (dynamixelSerial->readable())
+    // //     {
+    // //         InBuff[plen] = dynamixelSerial->getc();
+    // //         plen++;
+    // //     }
+    // // }
+    // while ((timeout < ((6 + bytes) * 10000)) && (plen < (6 + bytes)))
+    // {
+
+    //     if (dynamixelSerial->readable())
+    //     {
+    //         InBuff[plen] = dynamixelSerial->getc();
+    //         plen++;
+    //         timeout = 0;
+    //     }
+
+    //     // wait for the bit period
+    //     wait_us(1);
+    //     timeout++;
+    // }
+    // timer.stop();
+    // for (int i = 0; i < plen; i++)
+    // {
+    //     Status_Packet[i] = InBuff[i];
+    //     printf("0x%X,", Status_Packet[i]);
+    // }
+    // printf("\r\n");
+    return 0x01;
+}
+//-------------------------------------------------------------------------------------------------------------------------------
+// Public Methods
+//-------------------------------------------------------------------------------------------------------------------------------
+Dynamixel::Dynamixel(PinName tx, PinName rx, int baud, PinName di)
+{
+    dynamixelSerial = new Serial(tx, rx);
+    dynamixelSerial->baud(baud);
+    dynamixelDi = new DigitalOut(di);
+    dynamixelDi->write(0);
+}
+
+Dynamixel::~Dynamixel(void)
+{
+    if (dynamixelSerial != NULL)
+        delete dynamixelSerial;
+}
+
+void Dynamixel::setMode(uint8_t ID, uint8_t Mode, uint16_t CW_limit, uint16_t CCW_limit)
+{
+    uint8_t L_CW = (uint8_t)(CW_limit & 0xFF);
+    uint8_t H_CW = (uint8_t)(CW_limit >> 8);
+    uint8_t L_CCW = (uint8_t)(CCW_limit & 0xFF);
+    uint8_t H_CCW = (uint8_t)(CCW_limit >> 8);
+    Instruction_Packet[0] = ID;
+    Instruction_Packet[1] = SET_MODE_LENGTH;
+    Instruction_Packet[2] = COMMAND_WRITE_DATA;
+    Instruction_Packet[3] = EEPROM_CW_ANGLE_LIMIT_L;
+    Instruction_Packet[4] = L_CW;
+    Instruction_Packet[5] = H_CW;
+    Instruction_Packet[6] = L_CCW;
+    Instruction_Packet[7] = H_CCW;
+    Instruction_Packet[8] = ~(ID + SET_MODE_LENGTH + COMMAND_WRITE_DATA + EEPROM_CW_ANGLE_LIMIT_L + L_CW + H_CW + L_CCW + H_CCW);
+    writePacket();
+}
+
+void Dynamixel::setLed(uint8_t ID, bool State)
+{
+    Instruction_Packet[0] = ID;
+    Instruction_Packet[1] = LED_LENGTH;
+    Instruction_Packet[2] = COMMAND_WRITE_DATA;
+    Instruction_Packet[3] = RAM_LED;
+    Instruction_Packet[4] = State;
+    Instruction_Packet[5] = ~(ID + LED_LENGTH + COMMAND_WRITE_DATA + RAM_LED + State);
+    writePacket();
+}
+
+void Dynamixel::setPosition(uint8_t ID, uint16_t Position, uint16_t Speed = 0)
+{
+    uint8_t L_Position = (uint8_t)(Position & 0xFF);
+    uint8_t H_Position = (uint8_t)(Position >> 8);
+    uint8_t L_Speed = (uint8_t)(Speed & 0xFF);
+    uint8_t H_Speed = (uint8_t)(Speed >> 8);
+    Instruction_Packet[0] = ID;
+    Instruction_Packet[1] = SERVO_GOAL_LENGTH;
+    Instruction_Packet[2] = COMMAND_WRITE_DATA;
+    Instruction_Packet[3] = RAM_GOAL_POSITION_L;
+    Instruction_Packet[4] = L_Position;
+    Instruction_Packet[5] = H_Position;
+    Instruction_Packet[6] = L_Speed;
+    Instruction_Packet[7] = H_Speed;
+    Instruction_Packet[8] = ~(ID + SERVO_GOAL_LENGTH + COMMAND_WRITE_DATA + RAM_GOAL_POSITION_L + L_Position + H_Position + L_Speed + H_Speed);
+    writePacket();
+}
+
+void Dynamixel::setWheelSpeed(uint8_t ID, bool Direction, uint16_t Speed)
+{
+    uint8_t L_Speed = (uint8_t)(Speed & 0xFF);
+    uint8_t H_Speed = (uint8_t)(Direction ? (Speed >> 8) : (Speed >> 8) | 0x04);
+    Instruction_Packet[0] = ID;
+    Instruction_Packet[1] = WHEEL_LENGTH;
+    Instruction_Packet[2] = COMMAND_WRITE_DATA;
+    Instruction_Packet[3] = RAM_GOAL_SPEED_L;
+    Instruction_Packet[4] = L_Speed;
+    Instruction_Packet[5] = H_Speed;
+    Instruction_Packet[6] = ~(ID + WHEEL_LENGTH + COMMAND_WRITE_DATA + RAM_GOAL_POSITION_L + L_Speed + H_Speed);
+    writePacket();
+}
+
+void Dynamixel::setWheel3Speed(uint8_t ID[], bool Direction[], uint16_t Speed[])
+{
+    uint8_t L_Speed[3], H_Speed[3];
+    L_Speed[0] = (uint8_t)(Speed[0] & 0xFF);
+    H_Speed[0] = (uint8_t)(Direction[0] ? (Speed[0] >> 8) : (Speed[0] >> 8) | 0x04);
+    L_Speed[1] = (uint8_t)(Speed[1] & 0xFF);
+    H_Speed[1] = (uint8_t)(Direction[1] ? (Speed[1] >> 8) : (Speed[1] >> 8) | 0x04);
+    L_Speed[2] = (uint8_t)(Speed[2] & 0xFF);
+    H_Speed[2] = (uint8_t)(Direction[2] ? (Speed[2] >> 8) : (Speed[2] >> 8) | 0x04);
+
+    Instruction_Packet[0] = 0xFE;
+    Instruction_Packet[1] = SYNC_LOAD_LENGTH;
+    Instruction_Packet[2] = COMMAND_SYNC_WRITE;
+    Instruction_Packet[3] = RAM_GOAL_SPEED_L;
+    Instruction_Packet[4] = SYNC_DATA_LENGTH;
+    Instruction_Packet[5] = ID[0];
+    Instruction_Packet[6] = L_Speed[0];
+    Instruction_Packet[7] = H_Speed[0];
+    Instruction_Packet[8] = ID[1];
+    Instruction_Packet[9] = L_Speed[1];
+    Instruction_Packet[10] = H_Speed[1];
+    Instruction_Packet[11] = ID[2];
+    Instruction_Packet[12] = L_Speed[2];
+    Instruction_Packet[13] = H_Speed[2];
+    Instruction_Packet[14] = ~(0xFE + SYNC_LOAD_LENGTH + COMMAND_SYNC_WRITE + RAM_GOAL_SPEED_L + SYNC_DATA_LENGTH + ID[0] + L_Speed[0] + H_Speed[0] + ID[1] + L_Speed[1] + H_Speed[1] + ID[2] + L_Speed[2] + H_Speed[2]);
+    writePacket();
+}
+
+// unsigned int Dynamixel::ping(uint8_t ID)
+// {
+//     Instruction_Packet[0] = ID;
+//     Instruction_Packet[1] = PING_LENGTH;
+//     Instruction_Packet[2] = COMMAND_PING;
+//     Instruction_Packet[3] = ~(ID + PING_LENGTH + COMMAND_PING);
+//     transmitInstructionPacket();
+//     // if ((ID == 0xFE) || (Status_Return_Value != ALL))
+//     //     return 0x00;
+//     // else
+//     // {
+//     readStatusPacket();
+//     return 0x01;
+//     // if (Status_Packet[2] == 0)
+//     // return (Status_Packet[0]);
+//     // else
+//     // return (Status_Packet[2] | 0xF000);
+//     // }
+// }
+// unsigned int Dynamixel::getTemperature(uint8_t ID)
+// {
+//     Instruction_Packet[0] = ID;
+//     Instruction_Packet[1] = READ_TEMP_LENGTH;
+//     Instruction_Packet[2] = COMMAND_READ_DATA;
+//     Instruction_Packet[3] = RAM_PRESENT_TEMPERATURE;
+//     Instruction_Packet[4] = READ_ONE_BYTE_LENGTH;
+//     Instruction_Packet[5] = ~(ID + READ_TEMP_LENGTH + COMMAND_READ_DATA + RAM_PRESENT_TEMPERATURE + READ_ONE_BYTE_LENGTH);
+
+//     transmitInstructionPacket();
+//     return readStatusPacket();
+//     // return Instruction_Packet[5];
+//     /*
+//     if (Status_Packet[2] == 0)
+//     { // If there is no status packet error return value
+//         // return Status_Packet[3];
+//         return 0;
+//     }
+//     else
+//     {
+//         return 1;
+//         // return (Status_Packet[2] | 0xF000); // If there is a error Returns error value
+//     }*/
+// }