Archives: 2025

Representing torque constant as Kv in moteus

One of the characteristic metrics of brushless DC motors is the Kv value, which describes the relationship between the angular velocity of the motor and its back EMF. Somewhat unexpectedly, this constant also completely determines the torque constant of the motor, i.e. the relationship between phase current and mechanical torque output (see this Things In Motion post).

Since the very first release of moteus, this Kv constant has been stored in moteus using somewhat non-intuitive units as motor.v_per_hz. That makes a lot of sense internally, as nearly all math the controller has to do can be natively done with those dimensions. However, as a user visible motor constant, it is completely opaque. Further, as a result of my incremental discovery of the math behind BLDC motors, the constant used by moteus had some additional “fudge” factors baked in that were then backed out through other “fudge” factors in the firmware.

Current mode commutation calibration in moteus

Way back in 2019, I documented the approach moteus has used for encoder commutation calibration ever since. In principle, it commands a fixed voltage that is swept through a range of electrical angles. Assuming the voltage is large enough, this will drag the rotor around with it similar to if the motor was a stepper motor. While that is happening, the commutation encoder reading is recorded over time, so that a mapping can be made between commutation encoder and the electrical angle of the motor. When combined with the old dead time compensation technique, it resulted in relatively sinusoidal current waveforms and thus smooth motion of the rotor and a smooth mapping.

Rethinking dead time compensation in moteus

Way back in 2021, I wrote up a post detailing a method for improving the linearity of the relationship between applied voltage and current for moteus, particularly during the calibration phase. At the time, this did solve a real problem – during calibration, moteus applied a fixed voltage to the phase terminals, swept the electrical angle of that voltage, and hoped that the mechanical angle as sensed with the on-axis sense magnet matched well. However, as a result of some new work, I’ve found that the premise behind that approach was flawed and it needs some re-thinking. This describes what I found, and what’s being done to resolve it going forward.

Moaar power!

Exciting news! All the existing moteus controllers in the world now have an upgraded default maximum power and upgraded rated maximum power as of release 2025-03-27! Depending upon the input voltage and PWM rate, sometimes nearly twice the amount. First, check out the comparison table, then the rationale:

Old default max / rated New default & rated
moteus-r4 340W / 450W 900W <= 30V, 400W >= 38V
moteus-c1 75W / 100W 250W <= 28V, 150W >= 41V
moteus-n1 340W / 1200W 2kW <= 36V, 1kW >= 44V

Background, why a power limit?

moteus brushless motor controllers drive 3 phase PMSM motors, accepting a DC input voltage, and outputting current to each of the 3 phases of the motor. It does so using MOSFET based switching, which alternately connects each phase to either ground, or the DC positive input. As that switching progresses, charge is either drawn, or replenished into, the onboard bulk capacitors.

Configuring an off-axis MA600 encoder with moteus

This is the final post (hah! for now at least) in my series about implementing support for off-axis encoders in moteus (see previous iterations here: 1, 2, 3, 4, 5). In this one, I’ll share the recipe for how to set up an off-axis MA600 encoder using a ring magnet as the only encoder source.

Hardware

Parts list:

Magnet mounting: The ring magnet needs to be rigidly affixed to the rotor of the motor being driven. It may be necessary to construct a bracket to mount the magnet, or a fixture to position the magnet before using an adhesive.

Nonlinear encoder compensation with no reference

This post is part of series examining how low-cost off-axis encoders can be incorporated into a moteus controlled motor system. For the history, see the previous entries: part 1, part 2, part 3, and part 4. We left off after having tuned the bias current trimming of the MA600 in order provide output from the encoder itself. When compared against a reference AksIM-2, that left an error profile that looks like:

Position error with respect to AksIM-2 after BCT tuning

Position error with respect to AksIM-2 after BCT tuning

Characterizing the MA600 off axis performance and tuning BCT

In previous iterations of this series (see part 1, part 2, and part 3), I built a breakout board for the MA600 TMR encoder and mounted it in an off axis configuration with a diametrically magnetized 32mm OD ring magnet along with a reference AksIM-2 encoder to compare against. Now we can finally get to the part where we can start looking at what the reported values look like.

For my first experiments, I set up a moteus-n1 with the AksIM-2 as the primary encoder, and the MA600 in motor_position.sources.1 in a slot that was not used for anything. Having done that, I plotted the difference in reported angle between the MA600 and the AksIM-2 through a full revolution below, using the compensate_encoder.py script that is now in the moteus repo in reference mode.

Mounting the RLS 32mm ring magnet to a GL80 motor

I’ve been exploring how to add low cost off-axis encoder support into moteus, see part 1, and part 2. In this part, I’ll look at a magnet and how to get it installed on the test motor.

To start, this method of operation will require a diametrically magnetized ring magnet, i.e. one where the axis of magnetization is through the diameter rather than through its depth.

That is not a terribly common magnet configuration, but there are some vendors. For this experiment, I used a 32mm OD ring magnet from RLS that is intended for use with their Orbis line of encoders, part number BM220C320A1ABA00. The motor I am using for this test is a T-Motor GL80, which has a hollow shaft. To mate the magnet to the motor, I 3d printed a fixture (purple) which slipped over the bearing surfaces of the GL80 (pink), and captured the magnet (red).

MA600 / MA732 breakout board

In the previous post, I outlined a possible path to low cost off-axis encoders to be used with the moteus line of brushless controllers. The first step I took was to try and build a minimally sized breakout board that could be used with the MA732/MA702/MA600 line of hall effect angle sensors. You can get these off the shelf, for instance from tinymovr, but I wanted to see if I could make something a bit more compact, and that had the chip close to a board edge so that it could be used for off axis applications.