Using a Microcontroller as an Intermediary

You need the openCM microcontrolleropenCM microcontroller, a power supply, and two servos with separate IDs for this tutorial. You do not need the U2D2. Also, the example code is for Matlab 2021b or later and requires the Communications Toolbox. Python has similar serial communication capabilitiesarrow-up-right.

Why would I use the OpenCM9.04 instead of the U2D2?

So far we have sent serial signals from a laptop or desktop computer directly to a servo. There are some reasons why this may not be ideal:

  1. An operating system technically is not real-time (i.e., it cannot guarantee that tasks take place within a given amount of time), which may lead to delays in your control loop. Sufficiently long delays destabilize otherwise stable control loops.

  2. Control architecture may not require that the main computer get constant info from the servo, lengthing each control loop's duration.

  3. Serial messages may take a long time to send and decode.

  4. A high-power computer may rapidly deplete the robot's battery.

  5. Interfacing with sensors that are not Dynamixel servos would require extra serial ports, which might complicate and/or slow down communication between the computer and robot.

Thus, we may wish to distribute the robot's control system between a full computer (laptop, desktop, even a single-board like Raspberry Pi) and a microcontroller. The microcontroller has the following benefits:

  1. It can guarantee real-time operation (i.e., it can guarantee that tasks take place within a given amount of time), which should let you set things up without unpredictable delays in your control loop.

  2. It may be able to run a control loop very rapidly, as long as it requires only intermittently checking in with the main computer.

  3. Sending messages only intermittently will reduce the time spent sending and decoding serial messages.

  4. The microcontroller may run on its own for a long time because it only requires 5V and a tiny bit of current to operate. If the controller can operate without the main computer, this could significantly extend the battery life of your robot.

  5. The microcontroller may simplify serial communication by collecting all the sensory data from the robot, neatly packaging it up, then sending it to the main computer, all over one serial port.

Sending data from a PC to the OpenCM9.04, which runs a "passthrough" sketch that passes data along to the servos

By now you have learned to program servo motions with the DynamixelSDK and how to program servo motions with a personal computer. Both these methods ultimately do the same thing: construct a serial packet in a format that the servo can understand (e.g., protocol 1arrow-up-right, protocol 2arrow-up-right) and broadcast it to the servos over a serial port.

If you want to write to actuators or read from sensors that are not Dynamixel servos, then you will need some other way to distribute or collect that information from the rest of the robot.

Here's the basic plan:

  1. Formulate serial packets on your PC in Matlab (or whatever language you'd like)

  2. Send those packets to the OpenCM9.04 over a serial port

  3. Receive those packets on the OpenCM9.04, then immediately broadcast them to the servos

  4. OpenCM9.04 reads servo states

  5. OpenCM9.04 sends those packets to the PC

  6. Interpret packets in Matlab

In Matlab, we create a serial port with which to communicate with the OpenCM9.04. If you aren't sure which serial port this should be, you can use your Arduino IDE to figure it out. In Matlab, make a script to

This code will construct a packet for the servo and send it to the OpenCM9.04. Now, we must write a sketch for the OpenCM9.04 that will receive this message and relay it to the servos. In the Arduino IDE:

Running this program on your OpenCM9.04, then running the script in Matlab, should cause the servo to rotate to the position you command in Matlab. Note a couple things about this Arduino sketch:

  • The meat of the program, lines 72-82, simply read what has been sent to them and write it to the serial port to which the servos are connected. It is literally taking in bytes and handing them off.

  • We use the "portHandler" class to write data to the servos (line 79), but we do not need the "packetHandler" class, because the data received by the microcontroller is already formatted in packets that the servos understand.

    • This means we know what the packetHandler has been doing the whole time: it just takes in the parameters we provide (e.g., servo ID, memory address, values to write to memory), formats a packet that the servos can interpret, and sends it using the portHandler.

We can try a fancier example in which we generate a sinusoidal trajectory for the servo to follow, then send "breadcrumbs" (i.e., specific angles) spaced out over time. The OpenCM9.04's program should not need to change. However, the Matlab script should be updated:

Receiving data on a PC from the OpenCM9.04, which runs a "passthrough" sketch that passes data along from the servos

Let's expand our programs to ensure we can read information from the servo as it moves. This will require we change both the Matlab script and the Arduino sketch. Specifically:

  • Matlab must listen for bytes returning along the serial port and read them to clear the buffer

  • Matlab must interpret packets sent back from the OpenCM9.04 if they contain useful data

  • Arduino must tell the servos to report their states

  • Arduino must send the packets it receives back to Matlab

First, let's update the Matlab script. Two changes will need to be made:

  1. As discussed in reading servo motions with a personal computer, the servo returns a 6-byte status packet every time we send a command. Thus, our "setMXposition" function will need to read 6 bytes from the buffer before continuing, to prevent the buffer from accumulating garbage

  2. We will need to define and use a "getMXposition" function that will send the "read" instruction, listen for the response packet, and decode its contents

Here's a new script with each of these functions added/updated:

We must also update the sketch running on the OpenCM9.04, because in its current form, it does not request any info from the servos and does not send it back to the PC. Here is an updated sketch:

Now, the updated sketch will read from the servo in every loop and transmit what it reads back to the PC.

If our robot had other sensors (e.g., strain gauges, accelerometers, gyroscopes), we could read from those as well, then send their data to the PC.

Programs such as ROS are intended to help solve this problem of actuator and sensor integration. However,

  1. ROS 1 was not real-time, and while ROS 2 claims to be real-time, I don't know what the limitations are.

  2. Oftentimes tools that are designed to solve every problem are not great at solving any single problem. ROS makes it easier to connect actuators and sensors that don't normally talk to one another. However, our robots have MANY actuators and sensors. ROS's universality produces lots of overhead that slows down operation in a way that is not acceptable for us, because we already have trouble running programs quickly with so many actuators and sensors.

  3. If you understand how this stuff works at the low level, it sets you up to be a real robotics expert. You will have the ability to solve and troubleshoot many different problems and produce a specialized solution for your particular problem. I think that's legit.

Last updated

Was this helpful?