Archives: Python

Device fault text decoding

Here’s a short followup tview feature in the same vein as the recently announced fault monitoring. For various not-too-important technical reasons, the diagnostic method moteus uses to report faults in servo_stats.fault does not include a text shorthand like most other enumerations do. That means that users are constantly confronted with things like fault=33, or fault=39. Unless they are lucky and know to look in the relevant section of the reference, this doesn’t do a whole lot of good.

Device fault monitoring in tview

When using tview to monitor and control moteus controllers, there have been a fair number of limitations and “gotchas”. One of the biggest for newcomers is the distinction between error checking in the d pos command, and faults that can occur during position mode itself. When using the diagnostic protocol and issuing a command, for those commands which direct moteus to perform some control action, the controller will respond with an “OK” as long as the command itself is syntactically correct. Only then is it submitted to the online control loop, after which faults resulting from the command will manifest as the controller reporting a mode of kFault or 1, with a corresponding fault code. In the diagnostic tree view, those are shown as servo_stats.mode and servo_stats.fault.

So, what many newcomers do is take a moteus board fresh from the factory, which starts with servopos.position_min=-0.01 and servopos.position_max=0.01, and do the following in order:

  1. Issue a totally reasonable command like d pos nan 0 nan to command the motor to hold position
  2. Observe an OK come back
  3. Don’t see the motor do anything

What those users don’t realize is that in order to see why moteus doesn’t move, you need to look at the current reported mode and fault, not at the response over the diagnostic channel.

Here I’d like to describe a solution to this problem that hopefully makes tview much easier in general with fewer instances of confusion resulting.

UUID based addressing and python multiple device support

I’m excited to announce a significant usability improvement for all moteus controllers, command line tools and the python library! If your moteus controllers are on firmware version 2025-09-20 or newer and your moteus client tools are at 0.3.91 or newer, (and if you are using a pi3hat, it is on firmware 2025-09-20 or newer) there are some big improvements that you transparently get:

  1. You no longer need to assign unique CAN IDs before daisy chaining controllers
  2. The python transport lets client programs transparently operate across multiple CAN-FD interfaces simultaneously
  3. tview will automatically open all controllers attached to all CAN-FD interfaces on the computer

Let’s dig into what this looks like from the command line, tview and what the practical constraints are.

Optimizing moteus command rate

Probably one of the most frequently asked questions in the mjbots Discord is “how fast can I send new commands to moteus”, or “how fast can I read the status from moteus”. That may be because you want to perform torque based control in your application and require high bandwidth, or just because you have a high torque to inertia ratio system that reacts on very short time-scales. No matter the reason, the principles that control the maximum rate you can send updates are the same.

Python trajectory waiting

In simple motion control applications with moteus, a common request for the python library is “run a position command until it is complete”. moteus does track when the target position reaches the desired one and reports it in the “trajectory complete flag” (register 0x00b), however until now the application needed to poll that flag on a regular basis to see when the motion is done.

As of pypi moteus 0.3.59, there is now a new method on Controller which can be used to accomplish this, along with an example script. Basic usage is about as simple as one would expect:

moteus external connector pin selection

moteus r4.11 has two external connectors, the ABS connector (AUX2) and the ENC/AUX1 connector. The ABS connector was designed initially just to have 2 I2C pins. The ENC connector just has the random pins that were used for the onboard encoder SPI plus one more. Thus the range of external accessories that can be connected is somewhat haphazard and not necessarily all that useful.

When working on a more ground up revision of the controller, I wanted to improve that situation to expose more connectivity options on still a relatively limited connector set. The idea was to use 2 connectors, one which has 5 I/O pins and the other with 4 I/O pins. The onboard encoder SPI would still be accessible on the larger connector to use for at least one external SPI encoder, but how much other functionality could be crammed into the remaining pins? To start, lets see what possible options there are in the current firmware and supported by the STM32G4 microcontroller that moteus uses:

UART tunneling with moteus

With the release of more flexible I/O support, the moteus controller auxiliary port can be used to monitor encoders using an onboard UART. Now, with firmware release 2023-02-01, those UART pins can be used as an arbitrary logic level serial port controlled by the application! Let’s see how to use it below.

First, you will need to look at the pin configuration table to find pins that support UART functionality, and configure them as UART in the “aux?.pins” configuration tree. Next, “aux?.uart.mode” should be set to “kTunnel”, along with the desired baud rate. That’s it on the configuration front.

Debugging bare-metal STM32 from the seventh level of hell

Here’s a not-so-brief story about troubleshooting a problem that was at times vexing, impossible, incredibly challenging, frustrating, and all around just a terrible time with the bare-metal STM32G4 firmware for the moteus brushless motor controller.

Background

First, some things for context:

moteus has a variety of testing done on every firmware release. There are unit tests that run with pieces of the firmware compiled to run in a host environment. There is a hardware-in-the-loop dynamometer test fixture that is used to run a separate battery of tests. There is also an end-of-line test fixture that is used to run tests on every board and some other firmware level performance tests.

Improved mjbots labels

For most of mjbots’ existence, all of our products were labeled with a dependable, if lackluster, Brother P-Touch label maker. In line with other packaging improvements, I recently upgraded that labeling setup to bigger, higher resolution, and full color!

This is using an Epson TM-C3500, which I had expected to operate directly from my Linux based test fixtures. However, upon receiving it, discovered that alas only Windows drivers were available. Thankfully, it wasn’t too bad to print from python in a simple way as long as you manually select the media type from the Windows dialogs. Thus I made up a simple Flask app to receive label images over HTTP and print them. That runs on a Windows computer, and the test fixture applications just POST their label images to it.