Posts Tagged Arduino

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: , ,

Microbo(t) – Advanced line follower

Although it is one of the classics of robotics for beginners, the line follower robot, made ​​at high level, is quite complex. On Youtube you can see line follower running at 3 m / s and more, with optimization and maximum performance research that achieves discrete levels.

Usually a line follower competition is based on pure speed and the path is quite linear and simple, with large curves and wide straights. In this case the hardware part is the most important, because the sw part is quite simple to build. it is important to find the right compromise between the mechanical parts and the engine, to make it running as fast as possible. Unfortunately requires a lot of money, because the engine performance search or the wheels with special tires can be very expensive.The alternative is based on paths that are rather difficult or very twisted, with right angles, intersecting lines, lines breaks, obstacles and so on. In this case the HW is much less important. More important is the algorithm and then the sw. The ability of the robot builder is to build a powerful algorithm that allows the robot to drive fast in every situation.

In this tutorial I would describe the robot that I have realized, that is able to face a tortuous path made ​​of curves at 180 ° rather than tight coils, trying to  have a good speed.
The robot ,according to tradition, was home built. It is also already equipped with an infrared sensor front in case you wish to use it in a path with obstacles.

Questo è Microbo(t) – line follower robot:

It ‘s built with the following elements:
– Chassis 5 mm PVC foam (few cents)
– Arduino Nano (about 40 euros)
– Drive Pololu 50:1 HP (about 30 euros both)
– Pololu motor bracket (both about 6 euros)
– Caster wheel  Pololu 3.8 “plastic (about 3 euros)
– Pololu Wheels 42×19 (both about 10 euros)
– Motor driver SparkFun TB6612FNG (about 9 euros)
– Sharp IR Distance sensor 4-30 cm (about 15 euros)
– Sensor line Pololu QT-8RC (about 12 euros)
– 7.4V 900mAh Battery Li-Po (about 9 euros)
– some screws and wires
As you can see the components expensive are Arduino Nano and the motors. Nothing forbids to use a traditional Arduino with an obvious saving of money. In my configuration it weighs about 160 grams. You can do much better, in fact on the internet there are line follower with Arduino that weigh 100 grams.

 

 

Some comments on hw components used. The driving system, formed by Pololu wheels and  motors is almost good. I think that even better is using HP 100:1 Pololu motors which provide even more traction and fluidity in the changes of direction, even if it has a lower number of revolutions/minute. I tested also the 30:1 motors, but they were too nervous. Absolutely bad is the plastic wheel caster form Pololu. Unfortunately I had no other small than this, so I kept it. Not recommend its use. Terrible.

The motor driver SparkFun TB6612FNG is a little undersized. In fact it provides 1.2A at full speed, when the Pololu HP motors  may require up to 1.6A. But I had no problem with these drivers and they still work, so I can only advise them. Unfortunately they have a lot of wires, 7 for driving, 2 for the Vcc voltage (+5 V), one (or two with the ground) for the motor voltage and 4 wires for motors. In total 14 wires that are several. They are simple to program and manage. The full brake function is not good. In fact, if you need to brake, however, takes a little bit to stop, victim of inertia. I think that the engines 100:1 can help on this.

The line sensor Pololu QT-8RC is good. It provides out-of-the-box a digital output and can be connected directly to the Arduino digital ports. After a stage of self-learning during the first few seconds (see the video), it is able to calibrate with the best values ​​taking into account the reflectivity of the surface and the ambient light conditions. It can follow the black lines on white background or white on black background. For this sensor there is an Arduino  library written by Pololu that provides a value between 0 and 8000 depending on the sensor (from left to right) which is above the black line. I modified the library to get a response that goes from -800 to +800 with zero when the line is well below the IR sensor in the middle. This from my point of view makes easier the control. The only real problem I had was in the presence of right angles. In this case the robot has not always stopped in time and managed to turn. Unfortunately I have no videos on this particular problem.

Once built the robot, the biggest difficulty is the control parameters determination, that allow the robot to come back to the line when goes away. In this case I have put in place the usual PID control, although in my version was reduced only in PD, proportional and derivative. The integral control, with the frequent changes of direction, is extremely difficult to detect.
I also wrote  some simple routines for the detection of right angles. In this case the robot tries to stop and turns 90°. This technique has worked quite, but you can sure do better.

For the  IR front sensor I didn’t have any important test for obstacle avoidance. The main problem is due to the need to rotate the robot for the obstacle avoidance operating in open-chain, ie, without feedback.  The robot should pass the obstacle, but that succeeded a few times because the motors battery voltage varies over time, with a variation of path. I did not do further tests, but there are two possibilities:

  • a dc-dc converter boost 4-25v ​​for example like in the Pololu 3pi robot that maintains a constant input voltage to the motors and that have a good precision even in the absence of encoder
  • the encoders in the wheels with angles measurement

The dc-dc converter costs less than 10 euros, while the cost for the Pololu encoder  is about 25 euros. Maybe in the next version of the Microbo(t) I will decide which solution to adopt. Clearly the solution encoder is more sophisticated but requires more programming effort (and verify that there are still pins available on the Arduino!).

This is the code for Arduino, commented but not very clean. Link

This is the Microbo(t) in action:

 

Tags: , ,

Delta robot with Arduino

Today I present my first Delta robot made with Arduino. The Delta robot structure was designed by a professor at the Technical University of Lausanne in 1985.  It is a parallel robot, and within two decades has become the star of pick and place industrial robots . The delta robot distinctive elements are two:

  • The robot geometry which simplifies the equations of motion (kinematics)
  • The great idea to anchor the robot upside down so that it has the motors connected to the base. This is very important because while the robot works, the motors remain attached at the base, allowing the robot to have arms very light. Lightness means low friction, low inertia, low power motors, precision, speed, fast acceleration and deceleration.

These are two examples of delta robot:

 

 

 

 

These aren’t laboratory prototypes, but commercial robots and they cost about 50-60.000 euros. I tried to build a simple delta robot with Arduino. My Delta robot works like the commercial Delta robot, ie, in inverse kinematics. Given a point x, y, z in space, in real time Arduino calculates the angles of the servomotors that allow  to reach that point in space.

The Delta robot has two triangular plates. A higher which is fixed and the lower is free. The servo motors are fixed to the top plate. The gripping tool (i.e. an electromagnet, a gripper, a vacuum suction cup), is fixed to the lower plate. The two plates are triangular equilateral, that is, equal sides and equal angles of 60 °.

The Delta  has 3 servo motors and two arms for each servo. One is integral with the servo. The other arm is free to rotate in all directions and it is connected to the lower small triangle. In order to ensure the free turning, the second arm is linked with ball joints. To find the ball joints has not been easy. I found something about the steering of the machine model. Just search on google “joint Uniball” and you can find little cheap joints.

A very good explanation about the the Delta robot geometry and a very effective explanation of inverse and direct kinematics formulas can be found here . You can find also the code that calculates the inverse kinematic.

These are some Delta robot pictures (with an ATtiny85 microcontroller).

 

The end effector can be used with different tools. I tried a vacuum syringe and  a drawing pen.

These below are some videos with different tools.

 

The first experiment with a simple trajectory (a circle).

 

 

The Delta robot drove by a mouse with Processing. The code is available here.

 

The Delta robot in  pick and place configuration. The code is available here.

 

 

 

 

The Delta robot drawing. This is a first draft. The code is available here.

 

Tags: , ,