BBR Digital Expander Documentation

Encoders#

Four extra quadrature encoder inputs, numbered 0 to 3.

Reading counts and velocity#

int counts = exp.getEncoderCount(0);      // signed, accumulates
int rate   = exp.getEncoderVelocity(0);   // signed counts per second

Velocity is computed on the board, over a proper time window. This is worth more than it looks: differentiating counts in your OpMode loop gives you a noisy number that depends on how fast your loop happens to be running that iteration. The board’s answer doesn’t.

Zeroing#

exp.resetEncoder(0);       // one channel
exp.resetAllEncoders();    // all four

Resets are idempotent. Every command carries a token, so if the I2C layer retries a transfer, the reset cannot happen twice. You will not get a double-zero from a retry.

Absolute (pulse-width) encoders#

Any channel can be switched from quadrature to reading a PWM absolute encoder — the kind that reports its position as a pulse width, typically 1 to 1024 µs per revolution.

exp.setChannelMode(2, BBRDigitalExpander.ChannelMode.PULSE_WIDTH);
int us = exp.getPulseWidthUs(2);    // measured pulse width in microseconds

For multi-turn tracking, tell the board the pulse-width range of your specific encoder so it can tell a wrap from a jump:

exp.setPwmChannelParams(2, 1, 1024);   // minUs, maxUs
exp.setPwmWrapEnabled(2, true);

With wrap tracking on, the channel accumulates across revolutions instead of snapping back to zero at the top of each turn.

getPulseWidthUs() only works on a channel in PULSE_WIDTH mode, and getEncoderCount() is the reading you want in QUADRATURE mode. Asking for the wrong one throws rather than returning a plausible-looking wrong number.

Triggering on an encoder position#

The board can watch an encoder for you and drive a digital output when it passes a threshold — no I2C, no loop code:

exp.triggerWhenEncoderPast(2, 0, 1000);   // output 2 high once channel 0 reads >= 1000
exp.saveConfigToFlash();

The comparison is signed, and on a pulse-width channel the threshold is in microseconds rather than counts. See Digital outputs and triggers.

Worked example#

BBREncoderExample shows counts, firmware velocities, and idempotent resets together. BBRPwmEncoderExample covers the absolute-encoder path. See Example OpModes.