Another step in my plan for the next revision of the moteus servo mk2, is an updated controller board. As mentioned in my roadmap, I wanted to revise this board to make improvements in a number of domains:
Communications: Now instead of RS485, the primary communications interface is FD-CAN. This supports data rates of up to 8 Mbit and packet lengths up to 64 bytes. The header is nominally at the original CAN bit rate, but I have no need to be standards compliant and am running very short busses so I may run everything at the higher rate.
Connectors: Now there exist power connectors, in the form of XT30 right angle connectors and they are also daisy chainable like the data connectors. Additionally, all the connectors exit from the bottom of the board to make routing easier in configurations like the full rotation leg.
Controller: This uses the relatively new STM32G4 controller series. It is lower power than the STM32F4, supports FD-CAN, and also supports closely coupled memory, which may allow me to improve the speed of the primary control loop execution by 3 times.
Voltage range: This board now has 40V main FETS, with all other components at 50V rating or higher. Thus it should be safe with inputs up to 8S (34V or so).
It still maintains a number of the capabilities of the moteus r3.1 controller:
Integrated FOC encoder: An AS5048 encoder is mounted in the center of the back, which allows direct mounting above the rotor for FOC control.
Form factor: The entire board is 45x54mm, with M2.5 mounting holes. It is smaller than a 60mm BLDC motor and much smaller than an 80mm one.
Integrated current sensing: It uses a DRV8323 to drive the FETS, which includes current sensing for closed loop current control.
My first attempt at this, “r4”, came back from fabrication in an nonredeemable state. I used the digikey supplied footprint for the STM32G4 UQFN part, which looked mostly correct on the surface. However, while the footprint was good, the pinout was for the TQFP variant! This resulted in me shorting out several power pins to ground right next to the exposed pad in a way I couldn’t easily rework.
r4.1 seems to be in better shape so far. It powers up, and I now have blinking lights!
Next up is actually porting the control software to the new controller and communications interface.
To verify that I could make FD-CAN work in the next revision of the moteus controller, I made a simple desk setup between two NUCLEO-G474RE boards. I started by soldering up some breakout boards for the TCAN334G CAN transceiver I’m planning on using:
And then wired those up with a lot of jumper wires:
After a fair amount of fiddling, bisecting against the ST CUBE example project, and fixing some problems with my STM32G4 support in rules_mbed, I ended up with some 16 byte CAN frames being sent and received with a data rate of ~4Mbit.
While working on the next revision of the moteus controller, I started by bringing up a software toolchain on a NUCLEO-G474RE board. Unfortunately, even the most recent mbed 5.14 doesn’t yet support that processor. Thus, I have a half-baked solution which pulls in the ST CUBE sources for that controller into the mbed tree as a patch.
The patch only implements wrappers for the things I care about, so it isn’t a complete solution. Since I am not really using any mbed libraries anymore in any project, that isn’t a whole lot. Right now I’m just using it for the one function that sets up the board, a linker script, and the pin mappings. I will probably eventually just make a rules_stm32 and ditch mbed entirely but for now that is more work than it is worth.
While bringing up an STM32G4 for the new revision of the moteus controller, I wanted to be able to flash and debug the system, and thus needed a working OpenOCD installation. The NUCLEO-G474RE board has an ST-LINK-V3 debug interface, which no released version of OpenOCD supports, although thankfully that is working just fine at HEAD in git. However, to make the STM32G4 work I had to pull some patches from the sysprogs/openocd tree.
When working on the firmware for Super Mega Microbot’s improved actuators, I decided to try using mbed-os from ARM for the STM32 libraries instead of the HAL libraries. I always found that the HAL libraries had a terrible API, and yet they still required that any non-trivial usage of the hardware devolve into register twiddling to be effective. mbed presents a pretty nice C++ API for the features they do support, which is only a little less capable than HAL, but still makes it trivial to drop down to register twiddling when necessary (and includes all of the HAL by reference).
Most people probably use mbed through their online IDE. While this is a remarkable convenience, I am a big fan of reproducibility of builds and also of host based testing. mbed provides mbed-cli which gets part of the way there by letting you build offline. Unfortunately, it still doesn’t provide great support for projects that both deploy to a target and have automated unit tests. It actually has zero support for unit tests that can run on the host.
As many have guessed, I’m a big fan of bazel https://bazel.build, for building software projects. Despite being raw around the edges, it does a lot of things right. Its philosophy is to be fast, correct, and reproducible. While it doesn’t support flagless multi-platform builds yet (#6519), it does provide some minimal multi-platform support. It also has robust capabilities for pulling in external projects, including entire toolchains and build environments. Finally, it has excellent support for host based unit tests.
To make it work, you do have to configure a toolchain though. That I’ve now done for at least STM32F4 based mbed targets. It is published under an Apache 2.0 license at: https://github.com/mjbots/rules_mbed
Seamless toolchain provisioning: It configures bazel to automatically download a recent GNU gcc toolchain from ARM (2018q2).
Processor support: Currently all STM32F4 processors are supported, although others could be added with minimal effort.
Host based testing: Common modules that rely only on the standard library can have unit tests run on the host using any C/C++ testing tools such as boost::test.
Simultaneous multi-target configuration: Multiple targets (currently limited to the same CPU family) can be built with a single bazel command. Multiple families can be configured within the same source tree.
Once you have it installed in a project, building all host based tests is as simple as:
tools/bazel test //...
and building all binary output files is as simple as: