Dynamixel Pro Modbus RTU Notes

I didn’t see any guides or discussion here, so I thought I would put together some quick items form my experience attempting to use modbus rtu with a dynamixel pro actuator.
All tests were preformed with the following:
OS: Ubuntu 18.04 (Linux)/ROS 2 (Dashing)
Actuator: PM42-010-S260-R
Serial-USB devices: Robotis U2D2, and FTDI USB-RS485-WE-1800-BT

For simplicity I used a copy of the libmodbus open source modbus library: GitHub - stephane/libmodbus: A Modbus library for Linux, Mac OS, FreeBSD and Windows
with very slight modifications to add to 2Mbps buad rate.

For the test setup, the input connection used the left connector on the PM42-010 motor with data being read between the D+ and D- connection on the right connector (assuming you are using the connection diagram at PM42-010-S260-R)
A 120ohm resistor was also connected between the D+ and D- leads at the measurement side to prevent issues with signal reflection.

The first note that I discovered from the emanual document is that the registers listed at PM42-010-S260-R indicate that the addresses are between 40001 and 40304. This simply indicates that we are dealing with holding registers, however this doe not indicate the the starting address to send. Instead we send the offset based on the function code.

Example: I want to read the model number and only the model number (address 40001) from a dynamixel pro actuator with id set to 1. Then I would construct my message to be
0x01 0x03 0x0000 0x0001 crc16

So, 0x01 (the id of the dynamixel), 0x03 (read holding registers), 0x0000 (first register which is 40001), 0x0001 (read only one register).

So a simple way to ready the determine the starting register to send is to subtract 40001 from the Modbus Address section of the emanual.

The second note is to remember your Endianness as it holds across some of the registers which have multiple functions.
Example. to send Torque Enable (40457 LO) with no LED Red color (40257 HI) to the same device as before. Then we would send
0x01 0x06 0x0100 0x0001 crc16

0x01 (actuator id), 0x06 (write single holding register), 0x0100 (offset of 256 or 40257th register), 0x0001 (0x00 hi bit, 0x01 low bit). Which will result in torque on.

Another note is to remember to set the latency of the linux usb-serial interface. For this I use the setserial command (setserial(8): get/set serial port info - Linux man page). Specifically, if the device registers on ttyUS0, then we use the command
sudo setserial /dev/ttyUSB0 low_latency

What this does is reduce the time that Linux holds the serial line preventing reuse. As an example, running an io code at 4Mbps, I see the following request-response from a read request:

If low latency is not set, then Linux will hold the serial device for 10ms, meaning calling 2 consecutive serial commands looks like:

But, but setting low latency, then we reduce that from 10ms to 1ms. So the same consecutive 2 requests instead will look like:

The main thin I find missing with modbus is if the device enters a hardware error state (e.g. due to something like it not being able to reach a commanded position) then there does not appear to be any software based recourse as with the SDK.

Some sample code that I used for testing is available here: Files · feature/libmodbus_copy · Frank Mathis / robotis_modbus_interface · GitLab

Although it does use ROS2 (ament) to build the c++ package.

I am curious if anyone else has tested/worked with the modbus rtu interface on the dynamixel pro actuators, and would love to hear more

1 Like

Hello @fbMathis, thank you very much for this detailed post sharing your observations and experiences using the modbus-RTU communication resources with your unit of DYNAMIXEL P-series!

Your observations regarding the setserial command for low latency are very informative- and are similar to the recommendations for optimizing graph responses for DYNAMIXEL Wizard 2.0 software here. The setserial command seems to be more convenient in my opinion.

It is a very interesting point that the modbus-RTU protocol does not seem to include a method for the DYNAMIXEL to perform a soft-reboot as is normally allowed by the Protocol 2.0 packet instructions.

I’d like to tag @willson , @Yogurt_Man, for any additional discussion and recommendations for your use of the DYNAMIXEL P-series with modbus-RTU resouces.

@fbMathis

Hi Mathis,

That’s interesting test result,

Did you notice that the U2D2 itself has termination resister (120 ohm) switch inside the box? You can simply switch the dip to enable this resister, so that you can prevent some noise reflection at the end of DYNAMIXEL data line.

The DYNAMIXEL itself can be switched to the Modbus protocol at Protocol Type(13).

Is there any reason you are using the open source library for P series rather than performing provided solution ?

So you could capture how the packet would be sent on Modbus via Packet tool in DYNAMIXEL Wizard 2.0, so that it would be great to verify the starting address…? (I am afraid that I actually well understand your post. And I really wish that I had better understanding to the Modbus RTU).

Regarding the latency and delay time,

Here is what I normally suggest to people,

  1. USB Latency Setting

  2. Reducing Return Delay Time (9) to ‘0’

Yogurt_Man,

For some clarification, I was able to communicate and have the P series motor using the information specified in the post. I did use the DYNAMIXEL Wizard 2.0 and a signal analyzer to help discern packets being sent.

For the usb system settings, it is actually recommended against directly modifying /sys/bus for low latency. Technically the seterial command does the same thing in the background, but in a more controlled fashion. I will note that the latency configuration will be reset every time the USB device is remounted on by the kernel. To get around this you can set up a udev rule to set the device to low latency every time it mounts, or you could modify the ioctl options the driver program to set the interaction to low latency. The issue with setting the ioctl setting is that it requires the program be run as root so it can actually modify that setting.

Another note, the Return Delay Time option is not supported when the device is set to Protocol Type(13).

As for choosing an open source solution: I wanted to use Modbus RTU, and reading through the Dynamixel SDK, it does not appear to support Modbus RTU. I chose the open source library to reduce the time and errors from writing it myself during debugging with the motor.