Archive for category Dynamixel

Dongbu Herkulex Arduino Library

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
  • Baud: speed of the Serial Port: it is mandatory to use this value: 57600. Other values supported are: 115200 but in my experience it doesn’t work well with the Arduino Uno/2009
  • rx, tx: receive and transmit pins. The receiving pin on Arduino has to be wired with the transmission pin on the Herkulex. The same for the receiving pin.
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
  • Baud: speed of the Serial Port: my experience is that using the Arduino Mega, the best speed is 115200. Other value supported is 57600
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
  • Baud: speed of the Serial Port: my experience is that using the Arduino Mega, the best speed is 115200. Other value supported is 57600
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
  • Baud: speed of the Serial Port: my experience is that using the Arduino Mega, the best speed is 115200. Other value supported is 57600
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
  • -1: error checksum 1
  • -2: error checksum 2
  • 0: OK
  • for other values please see the manual, page 39
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

  • 0: no reply
  • 1: only reply to CMD command
  • 2: reply always
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
  • Servo_ID: servo ID. Values between 1-253. Not working with BROADCAST_ID
  • Goal: values between  0 – 1023. Absolute position
  • iLed=Led color. Values are:
    • LED_GREEN
    • LED_BLUE
    • LED_CYAN
    • LED_RED
    • LED_GREEN2
    • LED_PINK
    • LED_WHITE
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
  • Servo_ID: servo ID. Values between 1-253. Not working with BROADCAST_ID
  • Angle: angle of the motor. Values between -160.0 degrees … 160.0 degrees
  • iLed=Led color. Values are:
    • LED_GREEN
    • LED_BLUE
    • LED_CYAN
    • LED_RED
    • LED_GREEN2
    • LED_PINK
    • LED_WHITE
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
  • Servo_ID: servo ID. Values between 1-253. Not working with BROADCAST_ID
  • Goal: values between  -1023…. 1023. Absolute speed
  • iLed=Led color. Values are:
    • LED_GREEN
    • LED_BLUE
    • LED_CYAN
    • LED_RED
    • LED_GREEN2
    • LED_PINK
    • LED_WHITE
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
  • servoID: servo ID. Values between 1-253. BROADCAST_ID doesn’t work
  • Goal: speed value between -1023, 1023
  • 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
  • iLed: =Led color. Values are:
    • LED_GREEN
    • LED_BLUE
    • LED_CYAN
    • LED_RED
    • LED_GREEN2
    • LED_PINK
    • LED_WHITE
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
  • servoID: servo ID. Values between 1-253. BROADCAST_ID doesn’t work
  • Goal: position between 0 – 1023
  • 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
  • iLed: =Led color. Values are:
    • LED_GREEN
    • LED_BLUE
    • LED_CYAN
    • LED_RED
    • LED_GREEN2
    • LED_PINK
    • LED_WHITE
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
  • servoID: servo ID. Values between 1-253. BROADCAST_ID doesn’t work
  • angle: target angle between -160°, 160°
  • 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
  • iLed: =Led color. Values are:
    • LED_GREEN
    • LED_BLUE
    • LED_CYAN
    • LED_RED
    • LED_GREEN2
    • LED_PINK
    • LED_WHITE
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
  • servoID: servo ID, values between 1-253. BROADCAST_ID doesn’t work
  • valueLed: Led color. Values are:
    • LED_GREEN
    • LED_BLUE
    • LED_CYAN
    • LED_RED
    • LED_GREEN2
    • LED_PINK
    • LED_WHITE
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
  • servoID: servo ID. Values between 1-253. BROADCAST_ID couldn’t work, depends on the registry value
  • address: the address value in memory. Please see manual pag.26
  • writeByte: byte value. Please see manual pag.26
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
  • servoID: servo ID. Values between 1-253. BROADCAST_ID couldn’t work, depends on the registry value
  • address: the address value in memory. Please see manual pag.26
  • writeByte: byte value. Please see manual pag.26
Output None
Example writeRegistryEEP(BROADCAST_ID, 1,1) is equivalent to ACK(1) in ROM memory

 

 

Tags: , ,

Dynamixel AX-12A and Arduino: how to use the Serial Port

I bought two servos Dynamixel, the AX-12A, which are the basic servos version of the Korean company Robotis inc.
Dynamixel servomotors are like Ferrari in the world of the  cars : the best servomotors on the market.
Some characteristics of these servos:

  •   Operational Torque: 144 oz-in (10.4 kg.cm)
  •   1 / 2 duplex multi-drop serial bus
  •   1M bps serial communication
  •   Reports position, speed, load, voltage, and temperature
  •   Full rotation mode
  •   300 ° angular position in 1024 increments
  •   Speed ​​and torque control in 1024 increments
  •   Built in LED status indicator / alarm
  •   Shutdown on max / min voltage, load or temperature
  •   Single cable network connection

They are not particularly expensive: about $ 45 U.S., in Europe about 45-50 euros.

These servomotors have difficulty connecting to the Arduino. In fact, the half-duplex communication to 1Mbps requires additional circuitry to make connections to Arduino if there are several servos to be connected. A single servo can be connected directly to the Arduino, in the case of several actuators it is necessary to use a tri-state buffer, which is placed between the Arduino and AX-12A. A simple tri-state buffer is the 74LS241N.

74LS241

The Dynamixel protocol is a serial protocol, so, Arduino side, the buffer 74LS241 must be connected to the serial port and then on pins 0 and 1. This is a problem: if the serial port is used byDynamixel, how to display information through the Arduino IDE Serial monitor?

We need another serial port. The Arduino library NewSoftSerial  can help us, but we also need a USB-serial converter. I chose the converter USB2Serial built from Arduino team.

This is a picture of all the components needed to use the Dynamixel Servos.

The 2 ‘strange’ components: the 74LS241 and the USB2Serial converter:

These are all the components wired:

This is the wiring schema (sorry for the manual drawing):

Dynamixel servos require a software library to work with Arduino. An awesome library, realized by Savage Electronics, can be found here. Instructions can be found here.

This is a short video showing the Dynamixel servos in action. It is possible also to see the values printed in the Serial monitor with the NewSoftSerial throw the Serial port between the pins 8 and 9.

This is the code used:

#include <Dynamixel_Serial.h>
#include <NewSoftSerial.h>

NewSoftSerial mySerial(9,8); //9=tx, 8=rx
int k=0;

void setup(){ // Configuration

Ax12.begin(1000000,2); //2=data control
mySerial.begin(9600);  //speed of serial port used by NewSoftSerial
}

void loop(){

// move servo 1 and 2 randomly
Ax12.move(1,random(200,600));
Ax12.move(2,random(200,600));
mySerial.print("Number:");
mySerial.println(k++);

delay(1000);

mySerial.print("Number2:");
mySerial.println(random(100));

}