mjbots power_dist r4.3b

I’d like to introduce the newest mjbots product, an updated revision of the power_dist, 4.3b available at mjbots.com today!

This version has a number of improvements over the previously released r3.1:

Voltage Range10-44V8-34V
Maximum load capacitance4,000 uF400 uF
Quiescent Current300uA5mA
Current (Continuous / Peak)45A / 80Aunrated / 100A
Energy MonitoringYESNO
Switch ModeHigh SideLow Side

The only real downsides are that is more expensive and slightly larger.

If you want to read up more on the motivation and design process for this board, you can see that in (part 1, part 2, part 3, part 4).

Failed power_dist r4 designs (part 4)

For context, see part 1, part 2, or part 3.


My first attempt at an r4 design was based on the TI LM5066 hot swap controller. It is one of the more full featured controllers, since it supports built in energy monitoring over a SPI bus with no additional components. This first iteration was actually surprisingly close to being workable. There were two factors that it performed poorly on, quiescent current and energy monitoring. The quiescent current was similar to the r3.1 version. Energy monitoring was present, but at the full scale range necessary for power_dist, it was almost unusably inaccurate. With a design set for a peak of 100A, and also the lower 25mV current sense range, the current noise was measured in multiple amps.

I definitely wanted usable energy monitoring, and wasn’t quite ready to sacrifice the quiescent current, so decided to try again.


This version was based on the Analog LTC4380, nominally a “surge stopper” rather than a hot swap controller. I was attracted to it because it seemed like it would offer a similar pre-charge function, but with a much reduced quiescent current. I implemented energy monitoring using a separate Analog LT1787 high side current sense monitor which was fed into the op-amps on the STM32G474.

This version had multiple new and different problems. For one, the “fault timer” on the LT4380 is active during the “pre-charge” window. It turned out to be impossible to select a pre-charge speed that would handle a reasonable capacitance while simultaneously not triggering the fault timer.

Secondly, I discovered that the LT1787 has a relatively high output impedance, such that significant error was introduced by feeding it directly into an inverting op-amp with gain on the STM32G4. The G4 is relatively configurable, but there was no way with the existing PCB to first run it through a buffer op-amp to improve the impedance before moving to a gain stage (and only then on to the onboard ADC).

Finally, this version had the first incarnation of a “latching” circuit that would allow the processor to shut off power to the entire 3.3V bus when desired, but flipping the primary power switch would turn it back on. Thus the processor could decide how long to run after the primary power switch was turned off. Unfortunately, this circuit had several problems in this iteration that needed resolving.


This version used the TI TPS2490 hot swap controller along with the same LTC1787 high side current sense amplifier. It re-arranged the current sense input so that the STM32G4 could first buffer, then amplify the signal before handing it off to the ADC. The biggest problem here was once again the circuit that attempted to let the STM32G4 shut itself off to lower quiescent current. It ended up being unworkable, and also rendered the TPS2490’s under-voltage protection non-functional.


This version is basically the one that went into production. It still uses the TPS2490 and LTC1787, but now has a simpler latching mechanism, and undervoltage protection that actually works.


The only changes here are silk-screen modifications!

Next up

In the next, and final post, I’ll introduce r4.3b and its specifications!

Hot swap controllers (next get power_dist part 3)

This is one of a series covering the new mjbots power_dist board. See part 1 and part 2 for more context.

As mentioned previously, hot swap controllers are primarily used to allow a card to be inserted live into a server backplane, while minimizing disruption to the primary power bus while doing so. Additionally, they often implement protection features like over-current and short-circuit protection, and some support energy monitoring.

Typical topology

A typical hot-swap topology looks like:

Here, the high side FET is used for two purposes. During the “pre-charge” phase, the FET is operated in the linear regime, with a large voltage across it until the load capacitance is fully charged, at which point the FET reaches its “fully on” state and operates with its stated Rds on resistance. Notably, this means that the entire pre-charging energy is dissipated in those FETs, as opposed to the r3.1 design where a power resistor serves that purpose.

To accomplish the protection functionality, the current shunt (R1) is used to measure total current moving through the primary FET. Depending upon the particular chip, this could include over-current monitoring, where the FET is brought back into the linear operating region to limit the current, or short-circuit protection, where the FET is immediately turned off. Additionally, the resistor divider (R2/R3) can be used to program an undervoltage threshold.

Design constraints

The biggest challenge that a design faces with any hot swap controller is selection of the primary FET. Because it has to dissipate the entire pre-charge energy in a short time window, the device becomes very stressed. This limits the total capacitance that can be charged, the maximum voltage, and somewhat non-intuitively, the current that can be drawn during this startup window. For a design like the power_dist, where there is no “power good” signal distributed to downstream loads, they can draw what are effectively constant-power loads soon after the bus voltage reaches a valid intermediate state. Given that this can occur when there is still a large voltage across the high side FET, it can add a lot of energy dissipation.

To make this even harder, the design constraints are such that during the critical pre-charge window, FETs cannot be naively be placed in parallel. When operating in the linear regime, minute differences in device characteristics and temperature can cause drastic load imbalances. Thus controller design equations only allow parallel FETs for the purposes of increasing steady state on current, not increasing power or capacitance during the pre-charge window.

For a given FET, it will have a “safe operating area” plot like the below (this from the PSMN3R7-100BSE used in the soon-to-be-released power_dist r4):

This shows how much energy can be safety dissipated over different time windows. When designing the pre-charge system, it is then a balancing act of getting things to charge as quickly as possible, while not violating the SOA. Because of the details, going faster or slower can be problematic. Faster can be an issue because the energy may violate the short term peak energy, slower may be the culprit because the initial load current spends a longer time moving through the FET when it has a large voltage across it.

Next steps

In the next post, I’ll cover my various iterations, and where they fell short.

Next-gen power_dist (part 2)

Last time I covered the limitations of the power_dist r3.1, here I’ll cover some iterations of the design process.

My initial design goals for this version are based largely around improving the major limitations identified before:

  • Positive side switching: By switching the positive rail, a whole class of use failures is removed, as most people expect ground to be common throughout a system.
  • Increased voltage range: moteus r4.5 and the pi3hat both support 44V, so any new power_dist board should support at least that.
  • Lower quiescent current: Ideally, the quiescent current would be measured in microamps, or at least at a level that it does not confuse BMS systems.
  • Energy monitoring: Often in the development of the quad A1, I wanted to have a system level power and energy monitoring solution so as to identify the energy cost of various maneuvers and gaits. Tracking that at the power_dist level seems like a logical place.
  • Wider load envelope: The 3.1 version had a relatively limited maximum downstream capacitance and turn-on current draw. It was enough to power on 12 moteus controllers and a small computer, but not much else.

To achieve these goals, I decided to try using what is known as a “hot swap controller”. These are integrated circuits that are intended for use in cards that plug into server backplanes. Given that any given card could potentially have a large decoupling capacitance, inserting it live into a backplane could cause arcing, and high currents that cause the overall bus voltage to drop outside of tolerable limits.

While such controllers are intended to be used at the point of load, they are largely applicable in this centralized system too, where the “hot plugging” is of a battery instead of an individual load.

And here is where my design story becomes “complicated”. Because both I didn’t fully work through the consequences of each design approach, and because I was not familiar with the intrinsic limitations of hot swap controllers, I ended up taking a route that involved 4 different prototypes before I arrived at one that was mostly acceptable. Rather than go down that route linearly, in the next post I’ll instead distill what I learned about hot swap controllers and design before describing the final solution.

Development of next-gen power_dist (part 1)

The current iteration of the mjbots power_dist board released back in the summer of 2020 is pretty useful. It pre-charges the input, provides a soft switch, and gives you a bunch of output connectors to make wiring easier.

r3.1 Limitations

However, this version did have some limitations and potential problems. The first is that the pre-charge method it uses, a simple on/off pre-charge resistor, is unable to support a wide range of supply voltages. Either the resistor has a low value, in which case large input voltages will cause thermal failure, or for larger values, it isn’t able to actually pre-charge the bus sufficiently before engaging the primary MOSFET.

Secondly, it switches the negative rail. As pointed out in the documentation and by numerous YouTube commenters, if you are not careful, this can result in magic smoke being released if ground on the output and input is connected in any way.

Third, the protection afforded by the board is relatively limited. It merely performs the pre-charge function. It is still possible for short circuits or over-voltage events to result in damage to either downstream circuitry, or the upstream battery.

Fourth, the quiescent current is larger than I would like. At around 2-3 mA, it isn’t that large, but it means you can’t leave a battery connected for more than a day or so. Even worse, some BMS see that quiescent load as something they need to remain active for, which reduces standby battery life more substantially.

Looking forward

Given those shortcomings, I wanted to see if I could do better for the next revision. In the next several posts I’ll walk through my design process.

moteus position anti-windup

The moteus controller uses a somewhat unique integrated position / velocity / torque controller with per-command configurable proportional and derivative gains. Through various combinations of these settings, it can emulate many different types of controllers, but one that it has struggled with until now was a pure velocity controller.

It has been minimally possible to use moteus as a purely velocity controlled since wraparound support was implemented, but that came with a caveat. Either the proportional term needed to be set to 0, in which case velocity tracking performance was poor, or if the proportional term was non-zero, an external torque would cause the position to drift arbitrarily far from the target position. Then if the external torque were released, the controller would “catch up” for all the lost ground, moving very rapidly.

Now, however, as of release 2021-03-05, an optional configurable parameter has been added to the moteus firmware which enables the “config.max_position_slip” option. When this is finite, it acts as an anti-windup term on the position tracker, keeping it from getting far out of line. Tuning this lets you control how hard the controller tries to track velocity in the face of external disturbance, and how much catching up it will do when that external disturbance is relaxed.

This wasn’t conceptually hard to implement, but needed careful construction to interact properly with the existing stop position and position bounds that the firmware implements.

Here’s a video demonstrating the problem, and how the new configurable lets you resolve it:

pi3hat configurable CAN

To date, the pi3hat CAN channels only supported CAN properties suitable for use with moteus controllers. Given that’s what most people are using them for, that’s fine. However, there was no real constraint behind that, just laziness.

Thus, I’ve released new firmware for the pi3hat that supports configuring the bitrate, FD-ness, and other properties of all 5 CAN channels.

Currently only the C++ library exposes the configuration functionality, but it will be easy enough to add to python when someone needs it.

pi3hat r4.4

It seems like all the posts I’m writing these days are for new products! Here’s the pi3hat r4.4:

There are two changes from the previous r4.2. First, it now supports voltage inputs up to 44V. Second, in support of future upgrades, the 5th CAN-FD port has been upgraded to support 8Mbps, but downgraded to no longer have a wide common mode voltage range.


Also, it is in stock at mjbots.com!

That said, the worldwide electronic supply chain is still in shambles. That combined with the Chinese New Year means that stock may be intermittent, and slight alternate versions to adjust to different parts may be forthcoming.

qdd100 beta 2

I’d like to introduce the qdd100 beta 2!

This is the newest version of a quasi-direct-drive servo from mjbots. It has a sleek new look, and improved performance all around:

Beta 1Beta 2
Peak Torque12.5 Nm16 Nm
Backlash+- 0.2 degrees+- 0.1 degrees
Voltage Range10-34V10-44V
Comparison from beta 1 to the new beta 2

Additionally, the M3 mounting holes are now 3mm deep instead of the previous 2mm, which gives more flexibility when designing mounts.

It is in stock at mjbots.com now, with more production becoming available in the next weeks and months.