I bought some time ago a couple of motors from Dongbu: the Herkulex DRS-0101. These motors are ‘smart’ because they have inside a microprocessor that allow to manage many parameters and the behavior of the motors.
The Herkulex are an alternative to more famous motors like the Dynamixel. They have 4 wires and can be drove by a simple microprocessor with a UART (serial) port. My choice is to control them with an Arduino, so I wrote a simple library supporting all the most common Herkulex functionalities.
For the wiring of Herkulex to Arduino, it is important to consider that it is necessary to dedicate a serial port to the communication Arduino-Herkulex.It is not possible (or is not advisable) to use the standard Arduino port because it is dedicated to communication between PC and Arduino to see the values in the serial monitor. So it is important to use another serial port.
For the Arduino Mega it is easy, because the Mega has 4 serial ports, for the Arduino Uno/2009 that has only one serial port, it is mandatory to use a software serial port. So a library called SoftwareSerial has to be included if we want to use the Arduino Uno/2009.
To do this the last version of SoftwareSerial is not useful, so I included in the library also the right SoftwareSerial version in order to work well with Arduino Uno/2009.
For general knowledge about the Herkulex Dongbu motors, please see the manual: here
Download the library: Herkulex Library for Arduino
These are the commands supported by the library:
begin(long baud, int rx, int tx) | start the communication between Arduino Uno/2009 and Herkulex |
beginSerial1(long baud) | start the communication between Arduino Mega and Herkulex using the Serial Port 1 |
beginSerial2(long baud) | start the communication between Arduino Mega and Herkulex using the Serial Port 2 |
beginSerial3(long baud) | start the communication between Arduino Mega and Herkulex using the Serial Port 3 |
end() | stop the communication between Arduino and Herkulex |
initialize() | initialize all the motors |
stat(int servoID) | ask for the motor status to control the errors |
ACK(int valueACK) | set the answer of the motors to a request (verbose or not verbose) |
set_ID(int ID_Old, int ID_New) | change the ID of the motor |
clearError(int servoID) | clear the motor error |
torqueON(int servoID) | set the motor torque to ON |
torqueOFF(int servoID) | set the motor torque to OFF |
moveAll(int servoID, int Goal, int iLed) | prepare the motors to execute the movement in the same time to position (same start time – end time) – unison movement |
moveAllAngle(int servoID, float angle, int iLed) | prepare the motors to execute the movement in the same time to angle (same start time – end time) – unison movement |
moveSpeedAll(int servoID, int Goal, int iLed) | prepare the motors to execute the movement in continuous rotation with same start time and end time – unison movement |
actionAll(int pTime) | execute the unison movement |
moveSpeedOne(int servoID, int Goal, int pTime, int iLed) | motor continuous rotation with a specified speed |
moveOne(int servoID, int Goal, int pTime, int iLed) | move one motor to an absolute position |
moveOneAngle(int servoID, float angle, int pTime, int iLed) | move one motor to an angle |
getPosition(int servoID) | get the motor position |
getAngle(int servoID) | get the position in degrees |
getSpeed(int servoID) | get the motor speed (continuous rotation) |
reboot(int servoID) | reboot the motor |
setLed(int servoID, int valueLed) | set the led color |
writeRegistryRAM(int servoID, int address, int writeByte) | write a value in a register in the RAM memory |
writeRegistryEEP(int servoID, int address, int writeByte) | write a value in a register in the ROM memory |
I think the Herkulex are a good motors. My tests are not very deep and I don’t stressed the motors, but in general, compared to Dynamixel, I think they are good. The big difference is the possibility to set a large variety of parameters and the possibility to start and stop the movement for all the motors at the same time leaving to motors the definition of acceleration and speed needed to cover the distance assigned in the same time frame. Some time I experimented problems with the Serial port, receiving the data, I tried to limit them in the library, but sometimes these problems are present yet. This depends by the Herkulex motors, not by my library.
These are the details of each command.
begin
Command | void begin(long baud, int rx, int tx) |
Description | start the communication between Arduino Uno/2009 and Herkulex |
Arduino Type | Arduino Uno/2009 |
Input |
|
Output | None |
Example | begin(57600,10,11) |
beginSerial1
Command | void beginSerial1(long baud) |
Description | start the communication between Arduino Mega and Herkulex using the Serial Port 1 (pins Rx1 – 19 and Tx1 – 18) |
Arduino Type | Arduino Mega |
Input |
|
Output | None |
Example | beginSerial1(115200) |
beginSerial2
Command | void beginSerial2(long baud) |
Description | start the communication between Arduino Mega and Herkulex using the Serial Port 2 (pins Rx1 – 17 and Tx1 – 16) |
Arduino Type | Arduino Mega |
Input |
|
Output | None |
Example | beginSerial2(115200) |
beginSerial3
Command | void beginSerial3(long baud) |
Description | start the communication between Arduino Mega and Herkulex using the Serial Port 3 (pins Rx1 – 15 and Tx1 – 13) |
Arduino Type | Arduino Mega |
Input |
|
Output | None |
Example | beginSerial3(115200) |
End
Command | void end() |
Description | stop the communication between Arduino and Herkulex |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | None |
Output | None |
Example | end() |
Initialize
Command | void initialize () |
Description | initialize the motors. Correspond to commands: clearError(BROADCAST_ID) + ACK (1) + torqueON(BROADCAST_ID). Works for all the motors |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | None |
Output | None |
Example | initialize() |
Stat
Command | byte stat(int servoID) |
Description | return the status of the motor. Please note that the value of BROADCAST_ID (253) often doesn’t work well |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | servoID=servo ID value, value between 1-253 |
Output |
|
Example | int status = stat(1) |
ACK
Command | void ACK(int valueACK) |
Description | set the verbose answer from Herkulex. the value is valid for all the motors wired in the chain |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | valueACK
|
Output | None |
Example | ACK(1) |
set_ID
Command | void set_ID(int ID_Old, int ID_New) |
Description | Assign a new ID to a motor |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | Int ID_Old: the old ID motor. Values between 1-253Int ID_New: the new ID motor. Values between 1-253 |
Output | None |
Example | set_ID(253, 1) |
clearError
Command | void clearError(int servoID) |
Description | Clear the error code for a servo. Works also with BROADCAST_ID=253. Do not switch off the red led lightning |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | servoID: the servo ID. Values between 1-253 |
Output | None |
Example | clearError(BROADCAST_ID) |
torqueON
Command | void torqueON(int servoID) |
Description | Set the torque on for a motor. Works also with BROADCAST_ID=253 for all motors |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | Servo_ID: servo ID. Values between 1-253 |
Output | None |
Example | torqueON(BROADCAST_ID) |
torqueOFF
Command | void torqueOFF(int servoID) |
Description | Set the torque off for a motor. Works also with BROADCAST_ID=253 for all motors. The torque is Free, not Break |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | Servo_ID: servo ID. Values between 1-253 |
Output | None |
Example | torqueOFF(BROADCAST_ID) |
moveAll
Command | void moveAll(int servoID, int Goal, int iLed) |
Description | prepare the motors to execute the movement in the same time to position (same start time – end time) – unison movement. Start the movement with actionAll command |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input |
|
Output | None |
Example | moveAll(1, 300, LED_GREEN) |
moveAllAngle
Command | void moveAllAngle(int servoID, float angle, int iLed) |
Description | prepare the motors to execute the movement in the same time to angle (same start time – end time) – unison movement. Start the movement with actionAll command |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input |
|
Output | None |
Example | moveAllAngle(1,-120.5, LED_GREEN) |
moveSpeedAll
Command | void moveSpeedAll(int servoID, int Goal, int iLed) |
Description | prepare the motors to execute the movement in the same time in continuous rotation (same start time – end time) with different speeds – unison movement. Start the movement with actionAll command |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input |
|
Output | None |
Example | moveAll(1, 300, LED_GREEN) |
actionAll
Command | void actionAll(int pTime) |
Description | Start the unison movement prepared with moveAll, moveAllAngle, moveSpeedAll |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | pTime: execution time in milliseconds. Values between 0- 2856 ms. The execution time values are in step of 11.2 ms, so if your input is 1000, the real execution time is int(1000/11.2)*11,2=996,8 ms |
Output | None |
Example | actionAll(1000) |
moveSpeedOne
Command | void moveSpeedOne(int servoID, int Goal, int pTime, int iLed) |
Description | Move continuously a motor with a specific speed |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input |
|
Output | None |
Example | moveSpeedOne(1,-300, 1500, LED_GREEN) |
moveOne
Command | void moveOne(int servoID, int Goal, int pTime, int iLed) |
Description | Move one motor to an absolute position |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input |
|
Output | None |
Example | moveOne(1,-300, 1500, LED_GREEN) |
moveOneAngle
Command | void moveOneAngle(int servoID, floiat angle, int pTime, int iLed) |
Description | Move one motor to a position in degrees |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input |
|
Output | None |
Example | moveOneAngle(1,120, 1500, LED_GREEN) |
getPosition
Command | int getPosition(int servoID) |
Description | Get absolute position |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | servoID: servo ID, values between 1-253. BROADCAST_ID doesn’t work |
Output | Position. Values between 0-1024 |
Example | int pos=getPosition(253) |
getAngle
Command | float getAngle(int servoID) |
Description | Get position in degrees |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | servoID: servo ID, values between 1-253. BROADCAST_ID doesn’t work |
Output | angle. Values between -160.0 … 160.0 |
Example | float angleMotor=getAngle(253) |
getSpeed
Command | int getSpeed(int servoID) |
Description | Get speed in continuous rotation mode |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | servoID: servo ID, values between 1-253. BROADCAST_ID doesn’t work |
Output | Position. Values between 0-1024 |
Example | int pos=getSpeed(253) |
reboot
Command | void reboot(int servoID) |
Description | servo hardware reboot |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input | servoID: servo ID, values between 1-253. BROADCAST_ID doesn’t work |
Output | None |
Example | reboot(253) |
setLed
Command | void setLed(int servoID, int valueLed) |
Description | Set the led color |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input |
|
Output | None |
Example | setLed(253, LED_PINK) |
writeRegistryRAM
Command | void writeRegistryRAM(int servoID, int address, int writeByte) |
Description | Write a byte in the RAM registry |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input |
|
Output | None |
Example | writeRegistryRAM(BROADCAST_ID, 1,1) is equivalent to ACK(1) |
writeRegistryEEP
Command | void writeRegistryRAM(int servoID, int address, int writeByte) |
Description | Write a byte in the RAM registry |
Arduino Type | Arduino Mega- Arduino Uno/2009 |
Input |
|
Output | None |
Example | writeRegistryEEP(BROADCAST_ID, 1,1) is equivalent to ACK(1) in ROM memory |