dynamixel:dynamixel_protocol

All Seed Robotics products can be controlled using the Seed Robotics STP Protocol and they also have full support for the Dynamixel Protocol (versions 1 and 2), developed by Robotis.

This means Seed Robotics hands can be connected directly to any existing Dynamixel system.

If you are not using a Dynamixel system, using the Dynamixel protocol still brings a large number of advantages: it is a mature protocol, it has wide support and adoption (for example in ROS where you can find several libraries and code sample available) and it is based on Serial (UART) communication which makes compatible with virtually any host either PC or embedded MCU.

The protocol follows a strict set of principles to regulate communication on the bus:

  • Each device connected to the bus, has a unique ID and behaves as a “slave”
  • Slaves are always silent and will only respond when queried by the master (host)
  • The slaves expose a Control Table, a kind of memory map, where the master can read status variables or write data to trigger actions.
  • The master addresses the slaves by their unique ID and they are addressed using READ or WRITE commands. Extended commands are available to improve bus efficiency such as SYNC_WRITE and BULK_READ but those are beyond the scope of this introduction. Once you master READ and WRITE it should be a breeze to start using the other commands.
  • Every time the master sends a READ or WRITE command to a slave, the slave acknowledges the command by sending a reply packet. (unless you change the setting on Status Return Level; let's leave that for now).

The description of the Control Table memory positions is available for each device:

Seed Robotics designed the Control tables to resemble those of an Robotis MX series servo; this enables compatibility with Robotis products as well as a large code base built for Dynamixel devices.

Other Protocol features to ensure reliability

  • All commands start with a header of 0xFF 0xFF. No sequence read or written to any device should cause these two bytes to appear on the bus. This offers a way to re sync with the bus at any moment in time.
  • Protection against data corruption is assured, with the addition of CHECKSUM appended to end of each command and each reply.

As an example, in pseudo code, to move an Actuator with ID 2 to position 256, you would send to the bus:

WRITE ID=2, MEMORY POSITION 24, VALUE=1

WRITE ID=2, MEMORY POSITION 30, VALUE=256

Explanation:
First we write to memory position 24, which is the Memory Position to turn TORQUE ON. (you only need to turn Torque ON once; after that it will stay ON until you write the position to 0, to disable or power down the device)
Next we write to the memory position 30, which is the Memory Position for GOAL POSITION.
For information about which memory positions to use, please see the Control Tables, listed above.

After each WRITE, and assuming Status Return Level is configured to 2, the slave replies with a Status packet. This status packet includes valuable information such as the Error bitmask that reports any errors on the servo.

To build an actual WRITE command you need to follow the Dynamixel protocol syntax. Depending on your protocol version:

Please note: by default, Seed Robotics products come preconfigured to operate on the Dynamixel 1 protocol, which is the most widely used at present.

For example, in pseudo code, to read the current Temperature of an Actuator with ID 7, you would send to the bus:

READ ID=7, MEMORY POSITION 43, LENGTH=1

Explanation:
Memory Position 43 corresponds to the Present Temperature in the Control Table. It is represented by only 1 byte.
For information about which memory positions to use, please see the Control Tables, listed above.

You would have noticed that READ has the ability to read a sequence of bytes from the Control table: you specify the start address on the Control Table and length of data to read. This is especially efficient when you need to query multiple status variables at once.

When the slave receives the command it will return a Status packet that will include the Requested Information and a Status byte with the error bitmask.

To build an actual READ command you need to follow the Dynamixel protocol syntax. Depending on your protocol version:

Please note: by default, Seed Robotics products come preconfigured to operate on the Dynamixel 1 protocol, which is the most widely used at present.

A return packet is normally always sent by the slave to acknowledge the receipt of a command (WRITE) or to return the information requested by a READ. You may change this behavior if you modify the setting of Status Return Level (memory position 16).

By default this is set to 2, which means “Always Return”. Setting it to 1 will send a return packet for READ commands only and setting it to 0 will never Return any data (not even for Read).

The Return packet is composed of the Slave ID, the read data (if applicable), the error bitmask and the checksum.

The error bitmask is especially useful as it can report failures such as overheating, overload or invalid parameters sent in a command.

For more information on the Status (Return) Packet, depending on your protocol version:

Please note: by default, Seed Robotics products come preconfigured to operate on the Dynamixel 1 protocol, which is the most widely used at present.

As far as we know, the protocol specification does not specify a maximum time between sending a command and receiving a reply. However one can deduce proper timeout values considering the following:

  • Most Dynamixel slave devices have a setting called “Return Delay Time”. This is a virtually introduced delay that was meant to allow time for slower peripherals to switch from TX to RX mode. By default this is set at 500 microseconds. On modern setups users actively disable this, by setting this parameter to 0. Otherwise, if set at 500microsecs, you add unnecessary latency to the communication. The Eros series of firmware no longer supports this setting and will always reply as fast as possible (the equivalent behavior of setting the parameter to 0).
  • The Dynamixel documentation refers (buried deep in the documentation) that a command is considered interrupted if no byte is sent after a period of 100 milliseconds.

While we can't immediately draw a conclusion from this data, real world experience shows the following:

  • Robotis Dynamixel Wizard seems to use a timeout of 5 milliseconds when scanning the bus: when it PINGs an I D, if no reply is received within 5 milliseconds it assumes a timeout
  • Other users in more complex setups, or performing very long READs or WRITES may use timeouts of 10~20 milliseconds.
  • The typical measured turn around time for a command in the EROS architecture can be 2.5ms maximum or up to 6ms if the board is unable to verify a reply from the actuators, and needs to re-query them.

Our recommendation, based on our measurements and experience, is to use 5 milliseconds if you're performing short READs and writes (reading/writing up 10 sequential memory positions) or bring it up to 10ms if you are doing longer READs/WRITEs. If you experience communication issues, you can try increasing the timeout even more.
Typically if after 10~20ms you did not get a reply, you should re-send the command as there was likely some communication issue (data corruption for example).
Increasing the timeout over 100 milliseconds, which is already a pretty high timeout value, you'd be operating outside the Robotis own maximum timeout recommendation for Dynamixel communications.

Note: it is important to clarify the “timeout” concept depicted in this section: “timeout” is the time that is counted between sending the last byte of a command and receiving the first byte of a reply.
Because the protocol can operate at different baud rates, timeout should always be counted as above and never be counted as the time it takes between sending the last byte of the command and receiving the last byte of a reply. This would be wrong and would produce inconsistent results operating at different baud rates.

Furthermore, for BULK_* commands, where the units will reply in sequence, they will take up to 5ms for each device to send the reply. Therefore, if you are doing a BULK_* query on 5 devices, for example, it may take a maximum of 5 devices * 5ms = 25ms to get the replies for all the servos queried.

To improve bus efficiency and for added functionality, the Dynamixel Protocol offers enhanced forms of the READ and WRITE commands

  • PING - used to query for a presence of a servo (by detecting a timeout) or to quickly request a Status packet to check the error flags.
  • REG_WRITE and ACTION - these are deprecated commands (there is now the new, more efficient SYNC_WRITE). They were used to cache a WRITE command on several slave devices. When all was done, you send an ACTION command to the bus which triggers the slaves to execute the cached WRITE. The purpose is to synchronize operations such as the beginning of a movement.
  • BULK_READ - used to request data from multiple slaves in one go. In this mode, you send the sequence of IDs to read and requested memory positions. The slaves will reply in sequence, one after the other, in the order that you specified in the command. Please note that not all Dynamixel devices support this command.
  • SYNC_WRITE - writes data to multiple slaves in one go. Please note that not all Dynamixel devices support this command.
  • SYNC_READ and BULK_WRITE are only supported in Protocol version 2 and have similar behavior as above.
  • Another feature for improved efficiency is the BROADCAST ID (0xFE). When the master sends a packet to this ID, all slaves will treat the command as addressed to themselves. There are a few particularities with the Broadcast ID, the main one is that the slaves NEVER reply to a broadcast command. Broadcast is used, for example, to support the BULK_* and SYNC_* commands and to perform WRITES to all devices in one go (for example to set Torque ON). (Note: Because the BROADCAST ID never returns a reply, it is pointless to use it with READ commands; if you need to read multiple IDs at once, consider using BULK_READ instead.)

For more information, depending on your protocol version:

If you search the web you will find numerous tutorials, samples and libraries to use the Dynamixel Protocol. This document intends to be a high level presentation of the protocol and how it works.

Once you've grasped the high level concepts, it should be pretty straightforward to start building your own commands.

You can also opt to use a library or framework which takes care of all the low level details.

Copyright © 2015-2023 Seed Robotics Ltd

  • dynamixel/dynamixel_protocol.txt
  • Last modified: 2017/08/23 16:03
  • by Pedro Ramilo