Distance sensors#
A VL53L0X on any sensor port gives you range in millimetres.
Reading distance#
double mm = exp.getDistanceMm(1);
The board detects the sensor type by itself, so there is nothing to configure. Asking for a distance from a port holding a colour sensor throws rather than returning nonsense.
Invalid readings#
A distance sensor cannot always produce an answer. Nothing in range, a surface too dark to bounce enough light back, bright sunlight washing out the return — all of these give you a reading that means “I don’t know” rather than a distance.
Check validity before trusting a number:
BBRDigitalExpander.TelemetryBlock t = exp.readTelemetry();
if (t.isDistanceValid(1)) {
double mm = t.distanceMm[1];
}
Treating an invalid reading as a real distance is the single most common way distance-sensor code goes wrong. The failure looks like the robot confidently doing the wrong thing, because as far as your code is concerned it got a number.
The telemetry block also carries signalRate and ambientRate, which tell you why a reading is weak — low signal means not enough light coming back, high ambient means too much light overall.
Triggering on proximity#
The board can watch the distance for you and drive a digital output when something comes within range:
exp.triggerWhenNear(0, 1, 300); // output 0 high when port 1 sees something within 300 mm
Saved automatically. Your match code reads a DigitalChannel and does no I2C at all.
This helper sets a signal-rate floor for you, so weak edge-of-range returns don’t cause the output to chatter. That is exactly the kind of tuning value the everyday tier exists to hide.
triggerWhenNear() stores its range window in class slot 7 of that port. Keep any taught colours on that port in slots 1–6 so they can’t collide.
Full control#
If you need a two-sided window — “between 100 mm and 300 mm” rather than “closer than 300 mm” — use the advanced tier:
BBRDigitalExpander.DistanceClass cls = new BBRDigitalExpander.DistanceClass();
cls.distMin = 100;
cls.distMax = 300;
cls.hysteresisMm = 10; // stops chatter at the boundary
cls.minSignalRate = 100; // reject weak returns
exp.writeDistanceClass(1, 5, cls); // port 1, class slot 5
exp.saveConfigToFlash(); // advanced tier does NOT auto-save
hysteresisMm is what stops the output flickering when the robot sits exactly on the threshold. Leave it at the default unless you have a reason.
Advanced-tier calls do not save to flash. If you don’t call saveConfigToFlash(), your configuration is lost at power-off. exp.isConfigDirty() tells you whether there are unsaved changes.
Worked example#
BBRDistanceTriggerSetup is the canonical setup-once OpMode, and BBRDistanceTriggerRuntime is the match half that reads a plain digital input. See Example OpModes.