Flexible I/O: Source configuration

In the last two posts (part 1, part 2), I started talking about the new, more flexible I/O subsystem for the open source moteus brushless motor controller. In this post, I’ll continue by describing what a “source” is, and how it is configured.

For reference, the block diagram showing how auxiliary ports, sources, and sinks are related is below:

Each “source” in the above diagram represents a single encoder. To the sinks it provides a position and velocity, along with various validity indications for that data. Each has three basic configuration components: where to get the raw data, how to transform that raw data, and the low-pass filter configuration. We’ll cover each in turn.

Source raw data location

The location where a source retrieves raw data is selected by picking the auxiliary port number to use (1 indexed, so 1 is auxiliary port 1) and which function within that auxiliary port the data should be retrieved from. For instance, if we want a quadrature encoder connected to auxiliary port 2 to feed into source 3, we would set:

motor_position.sources.2.aux_number = 2
motor_position.sources.2.type = 3

The full list of possible function identifiers can be found in the reference documentation, and tview presents a drop-down with names.

There are two other minor complications. The first, is that for I2C functions, a separate configurable value is used to select which I2C device should be used.


If an “incremental” raw source is used, like quadrature, then an index function can be used directly at the source level to allow the source itself to report a correct absolute reading. This is necessary if the source is to be used for commutation. It is configured by entering the 1 based auxiliary port number into:


Source transforms

The are a number of transforms applied in sequence, each of which may be configured:

  • Offset: This is an offset in count space to add to the raw value before any other transformation is performed.
  • Sign: This may be 1 or -1. If -1, then the value will be inverted.
  • CPR: This is the “counts per revolution” and must be configured. For auxiliary port functions which have a CPR configuration, this must match it.
  • Eccentricity Compensation: A table of 32 points that describe percentage offsets from a perfectly linear response. It can be generated through a separate calibration tool, and all 0’s performs no eccentricity compensation.

The nominal output after all transforms have been completed is an angular position value between 0.0 and 1.0.

Low pass filter

The PLL based low pass filter is the final stage in the source pipeline. It is configured through a single parameter to select the 3dB cutoff frequency:


If the encoder is intended to be used for either commutation or for output position control, this frequency should be at least as large as the mechanical bandwidth of the system and at least as large as the torque bandwidth for stable control. Higher values than that trade off audible noise versus control performance.

Reference frame

Each source can be configured to be in one of the “rotor” or the “output” reference frames. This controls whether the rotor to output ratio is applied when using the value for either commutation or output control.


Where 0 is used for rotor and 1 is used for output.

Nearly done with configuration

I’ll tackle the final part of configuration in the next post, the sinks that use this encoder data.