Tag Archives: pcb


One of the necessary pieces for bringing up the moteus brushless controller and for ongoing development with it is being able to communicate with the device on the desk.  There aren’t many options for desktop FDCAN communication currently, and certainly none that are in the affordable range occupied by the CANUSB family of devices which I’ve used before and was very happy with.  Thus I created “fdcanusb”, a USB to FDCAN converter that allows one to communicate with FDCAN devices via a USB interface using a documented protocol, no drivers necessary.

The notable features:

  • USB 2.0 full speed host interface
  • ISO 11898-1: 2015 FDCAN interface on industry standard DB9 connector
  • Standards compliant bitrates up to 1/5Mbps supported
  • Software controllable termination
  • Frame sizes up to 64 bytes
  • Non-standards compliant bitrates allowed
  • Documented CDC ACM based host protocol (virtual COM port)
  • Apache 2.0 licensed firmware based on the STM32G474 controller

All for an expected sales prices of around $100.

This does come with some caveats: For one there is no galvanic or optoisolation, you get a common mode range of around +- 12V.  Another is that using just a USB 2.0 full speed interface means it may not be able to keep a FDCAN bus fully saturated at high bitrates.  Finally, the firmware will start out with just the bare bones capabilities, but can be extended to support features such as error injection, triggers, buffering, and more compact protocols in the future.

I’ve got the first functioning prototypes of these boards in hand now:

PCB render
Set up for test

Next up I’ll describe bringing up this board.

moteus controller r4.1

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).
moteus r4.1 rendering

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!

moteus r4.1 as built

Next up is actually porting the control software to the new controller and communications interface.

pre-charge circuit

Next up in Super Mega Microbot 2’s existence is being able to run untethered.  Before that can happen, I need to be able to plug in a battery, and hopefully not have everything explode.  As seen with the IMU junction board, even minor inductive links can result in chips getting toasted.  I had thought that just adding sufficient capacitance to each of the point-of-load converters would resolve the issue, but in fact that almost made it worse.

Thus, I built a simple pre-charge board that I could put in line with the main power.  It has two big FETs, one power resistor, an ATTiny44, and the random regulators and glue necessary to make it work.  The microcontroller has one job.  On power on, it waits a bit, energizes the “pre-charge” FET which has the power resistor in line.  Then, a short while later, it energizes the main FET through which all power will flow.

The pre-charge board as back from MacroFab
Wired up for testing

I did some minimal qualification testing first with a single motor which went fine.  Then I tested it against the whole quadruped, where I scoped the output ground line.  Here, you can see that the output ground line initially rises linearly with the ramp up rate of the lab supply I was using to test.  Then, about 80ms later after the ATTiny has powered on, it energizes the pre-charge FET and the output ground asymptotically approaches the resistance of the power resistor.  Then again, at 100ms after that, the main FET is engaged and the output ground voltage drops all the way to 0 (or close enough modulo the FET on-resistance).


After that, all that was left was to try it with a real battery:


Spoiler alert: It didn’t smoke.


gimbal control board revision

With the new gearbox based mech chassis for Super Mega Microbot 2, the old gimbal controller would need some updates.  It has these new features/capabilities:

  • Higher input voltage: The old system ran at 2S, so 7.2V nominal.  Now we’re running at 5S, so 18.5V nominal.
  • RS485 data: The HerkuleX based robot used TTL level data communications.  moteus uses RS485.
  • Daisy chained power: With the new raspberry pi based computer in the turret, I now need to have an additional power and data port up on the mobile part of the turret.
  • No camera passthrough: Similarly, since the camera is directly attached to the raspberry pi 3, I don’t need to mess with having a connector to pass it through anymore.
PCB rendering

As usual, I sent it off to MacroFab and waited.  A seemingly very short time later and poof, here it was!


Bringing this up was more annoying than it could have been, mostly from a software perspective.  The moteus and imu junction firmware were both based on the original gimbal software, but refactored to be usable across different projects.  At the same time, that was where I had developed the RS485 based multiplex transport library.  So, now was the time to bite the bullet and convert the gimbal software to use those common libraries.

Since the gimbal board has another unique processor compared to everything else, I broke it out into a separate git repository:

The old project was initially CubeMX based.  When porting to rules_mbed and moteus/mjlib, I was in a hurry, so just copy and pasted much of the CubeMX initialization into the new tree and didn’t use any mbed APIs at all.  It took me a while to remember how all the CubeMX initialization was glued together and which pieces of it were relevant before all the peripherals started working properly.

I then proceeded to mechanically integrate it together into the unused turret.

Mounted in bottom of turret
Fully assembled turret

I once again had to remember how to calibrate and operate the thing.  Doing this once every 9 months is kind of painful!  However, I did manage to get it all working again, and ready to be integrated onto the mech.



rpi3 interface board

Now that I have a chassis that can walk a little bit, I need to get the onboard computer working.  To do that, I needed to update the raspberry pi 3 daughterboard I built for the previous turret for the new bus voltage and communication format.

The rpi3’s UART is incapable of controlling the direction line on the RS485 transceiver, so I added a small STM32 micro in line to control the transmit / receive direction.  It adds a little bit of latency, but testing the firmware I was able to get it down to only a byte’s worth or so.

Here’s a quick render:


And a shot of the actual board:


Unfortunately, I managed to omit a necessary pullup on the enable line of the primary buck converter.  To get things moving along, I blue-wired it under the microscope:


And here’s a shot of it installed on the rpi3 b+:



Populating r3.1 moteus controller boards

I am a big fan of MacroFab.  They’ve built a PCB + assembly + more service that is transparent, high quality, and nearly completely self service.  They appear to be making money, so hopefully they will stay in business for some time.

On top of that, they offer a “quick turn” option which gives you populated boards shipped 10 business days after you order them (and I’ve even had them ship out a few days early from time to time)!  The only annoyance is that the quick turn option is limited, as I’ve mentioned before, to boards that meet certain criteria, among them having 20 or fewer items on the bill of materials.  To try and get this first quadruped prototype up and running quickly, I’ve been exclusively relying on quick turn boards, which means making some compromises.  Even after some moderate design sacrifices, I haven’t been able to get the servo controller board to 20 parts.  At the moment it is 23.  Thus, when I received the first big-ish PCB order I’ve made (qty 28), I got to spend a morning populating the remaining 3 components on all 28 boards.

Unfortunately, as painful as that was, it was still worth it as opposed to waiting an additional 3 weeks for the non “quick turn” service.

For posterity’s sake, the only difference between the r3 and r3.1 board is some silk screen changes, and one or two equivalent part substitutions.


All parts received!

I’ve now managed to get all the custom and long lead time parts in house for the first version of a quadruped based on the new actuators I’ve been designing.

All The Parts!
All The Parts!

That includes all the motors, custom brackets, and at least moderately working versions of all the custom PCBs.  Now I just have to get the local rework done, get the software into a semi-reasonable state, and put it all together!

Quadruped Junction Board

The full quadruped robot needs to both distribute power from the primary battery and RS485 serial network to all 12 servos.  To make the wiring of that easier, I’ve made up a junction board to provide power connectors, distribute the data network, and act as the IMU for when that is necessary.


The RS485 network is bridged between two halves of the robot.  One connection comes in from the controlling PC and two separate links go out, one for the left side and one for the right side.  This could eventually allow the controller on the junction board to take intelligent actions itself, such as querying the force applied on all 12 servos.  It could then return the result in a single RS485 transaction to the host computer.  I am expecting that will be necessary to achieve closed loop control approaching 1kHz.

It also includes a Bosch MEMS IMU.  The junction board will be rigidly mounted to the quadruped chassis, which means it is an ideal location for an attitude reference.  I haven’t integrated the IMU software from the gimbal yet, but have verified that the IMU is operational.

Finally, it has a 3.3V regulator on board to power all the logic level chips from the primary 18V supply.  I managed to toast two of these by not having sufficient input capacitance, and hot-plugging a lab supply to the power lead.  The inductive transient caused the regulators to over-voltage, resulting in a short from power to ground.  This is apparently a relatively common design mistake with this part according to TI’s E2E.  I attempted to rework replacement parts on the board, but due to a cascade of failures from USPS to my soldering, I gave up and just spun another revision.

In the meantime, I took one board and manually powered its 3.3v supply to bring up the firmware, and I’ve converted the other to a “dumb” mode, where it has no 3.3v supply and all the RS485 ports are just hard-wired together.  (Note the very tidy blue-wiring and hot glue.)

"Dumb" IMU Junction Board
“Dumb” IMU Junction Board

That should be enough to make progress with getting the full mech working, even if the control frequency is limited.

My simplest ever PCB

While wiring up the first 3 degree of freedom mammal actuator, I knew I was going to have a need to distribute power to each of the three motor controllers.  Thus, enter my simplest ever PCB.  It is just 4 holes for each of power and ground with traces connecting them.

moteus busbar PCB
moteus busbar PCB

It took an annoying amount of time to actually solder in all the necessary wires, but it was still better than the alternative of a bunch of ring terminals bolted together.

busbar installed in actuator
busbar installed in actuator

Controller r3 and endurance testing

After my self-education on MLCC derating I spun yet another low-volume prototype run of the servo controller.  This one has more than double the effective capacitance by doubling the number of capacitors and by selecting capacitors that have less derating.  I also fixed an incorrect pad geometry for the 6 pin ZH connector, optimized the BOM count a bit and reselected parts that were no longer available.

controller r3
2x fully assembled controller r3

Endurance Testing

To validate that this controller revision was robust enough to get a full mech’s worth of them made, I wrote up a simple test tool which ran the leg through a continuous jump cycle.  The goal was to validate the thermal design of the controller and motor, and while I’m at it, test the robustness of the 3d printed mechanical leg parts.

I knew endurance testing would be a process.  That said, this was a pretty interesting one.

First up: The RS485 cable joined into a screw terminal in part of the cable that moved up and down during a jump.  This had been coming loose on and off for me previously, and now was a limiting factor.  The fix was simple, move the terminal block further down the cable harness so that it didn’t move during a jump.

RS485 USB adapter
Inline RS485 USB adapter

Next, an even simpler problem.  The leg wore through some gaffer tape I had on my sheet of jumping foam and it became stuck to the adhesive.  I just moved the leg so that it didn’t jump on tape.

Now, an exercise in thermal management.  I gradually decreased the current used during the jump and landing phase until the steady state temperature of the controllers didn’t exceed my somewhat arbitrary 60C.  At that point, the 3d printed parts were starting to outgas a bit, so I figured that was a decent upper limit.

With those changes, I was able to get it pogo-sticking pretty reliably for 6 or 7 minutes at a time.  Here’s a video of the end of one of those runs, at which point you can see the next problem.

A more vexing problem

As seen above, after jumping for approximately 6 or 7 minutes, eventually the yaw axis would fail in a way that resulted in the electrical phase detection becoming offset.  The offset appeared to grow over time.  Eventually, this resulted in a loss of control in the lateral axis servo, when the D and Q currents became swapped.

This problem was most mysterious.  The lateral motor is basically doing nothing in these tests, the overall torque applied is maybe 1/50th of that which the upper and lower leg motors are generating.  My first thought was that perhaps the magnet which was attached to the shaft was faulty or had become demagnetized.  So I swapped it out, and while I was at it, added a spacer so that the magnet was closer to the magnetic encoder.

BLDC motor with magnet on axle
New magnet installed on axle

No dice.  Same failure, although this time I got 15 minutes of jumping in before it failed.

Another thought was that the rotor was somehow slipping on the axle.  However, the set screw was definitely still firmly in place, and this seemed pretty unlikely anyhow, since there was almost no torque on it.  The upper and lower leg motor with 100x the torque were not slipping.

Finally, I concluded that the bracket itself was deforming, resulting in the magnet changing alignment with the magnetic sensor.  In this configuration, the entire leg is cantilevered out.  Additionally, the linear rail fixture results in a large amount of torque being applied to the yaw bracket.


I already had beefier brackets coming in for other reasons.  I swapped them in, along with some new leg hardware to be described later.  Now with some forced air cooling I was able to even jump a reasonable height without stopping.  Here’s an endurance run showing the most aggressive jumping it could do indefinitely.

And here’s another video showing the max height I could get on this jumping fixture, which it could do for about 2 minutes before exceeding my safe temperature limit.

And for fun, a snapshot of my desk while recording one of the endurance videos.  It is quite tedious to let the leg jump for hours at a time while hoping nothing goes wrong!