Sensor drivers

BNO055 (IMU)

BNO055 — re-export of the native BNO055 C type.

The implementation lives in native/user_c_modules/openbricks/bno055.c so the drivebase tick can read imu.heading() every ms (when use_gyro=True) without a Python frame on the hot path. This module exists so existing user imports stay the same:

from openbricks.drivers.bno055 import BNO055

TCS34725 (color)

AMS TCS34725 RGB + clear light-to-digital sensor.

The TCS34725 returns four 16-bit channels (clear, red, green, blue) over I2C at address 0x29. There’s an onboard LED that we leave under user control — some breakout boards wire it to the LED pin on reset, others require GPIO control.

Reference: TCS34725 datasheet (AMS / ams-OSRAM), sections 2.4 and 3.

I2C command byte format (from datasheet):

bit 7 (CMD) = 1 (always for command byte) bits 6:5 (TYPE) = 01 (auto-increment) or 00 (single) bits 4:0 (ADDR) = register address

class openbricks.drivers.tcs34725.TCS34725(i2c, address=_ADDR, integration_ms=24, gain=4)[source]

Bases: ColorSensor

raw()[source]

Return the raw (clear, red, green, blue) 16-bit readings.

rgb()[source]

Return (r, g, b) scaled to 0..255 using the clear channel.

Dividing by the clear channel normalizes for ambient brightness, so a white object reports roughly (255, 255, 255) at any light level within the sensor’s range.

ambient()[source]

Return clear-channel brightness scaled to 0..100.

HC-SR04 (ultrasonic distance)

HC-SR04 ultrasonic distance sensor.

The HC-SR04 has two pins: trig (input — we drive it) and echo (output — it pulls high for as long as the round-trip echo took). Sequence:

  1. Drive trig high for ~10 µs.

  2. Read the duration of the resulting pulse on echo.

  3. distance_mm = pulse_us × speed_of_sound_mm_per_us / 2.

Speed of sound in air at room temperature is ~0.343 mm/µs, so a 60 cm target gives ~3.5 ms of echo pulse — well within the 30 ms default timeout.

This driver is pure Python — there’s no closed-loop control on a range sensor, so the 1 kHz hot-path concern doesn’t apply. The machine.time_pulse_us builtin does the actual measurement; typical call latency is ~1 ms (pulse round-trip) which is fine for the cold-path use cases (line-following, wall avoidance, mission “approach until N mm” loops at <100 Hz).

class openbricks.drivers.hcsr04.HCSR04(trig, echo, timeout_us=_DEFAULT_TIMEOUT_US)[source]

Bases: DistanceSensor

HC-SR04 ultrasonic distance sensor.

Parameters:
  • trig – GPIO pin number wired to the sensor’s TRIG pin.

  • echo – GPIO pin number wired to ECHO.

  • timeout_us – how long to wait for the echo. time_pulse_us returns -1 past this; we map that to -1 from distance_mm() to mean “no return”.

distance_mm()[source]

Return the round-trip distance to the nearest reflector ahead, in millimetres, or -1 if no echo arrived inside timeout_us.

VL53L0X (laser distance)

ST VL53L0X laser time-of-flight distance sensor.

The VL53L0X talks I2C at default address 0x29. A measurement cycle:

  1. Write 0x01 to SYSRANGE_START (register 0x00).

  2. Poll RESULT_INTERRUPT_STATUS (0x13) bit 0 until set (typical 33 ms at 33 Hz default rate).

  3. Read RESULT_RANGE_STATUS + 10 (0x14 + 10 = 0x1E) as a 16-bit big-endian integer — the raw distance in millimetres.

  4. Write 0x01 to SYSTEM_INTERRUPT_CLEAR (0x0B).

Out of range / blocked targets show as 8190 mm in the raw register; we surface that as -1 to match the DistanceSensor contract.

This driver implements the minimum register sequence to get usable single-shot readings on a power-on-default VL53L0X. ST’s reference API ships an extensive calibration / VHV / measurement-budget setup that improves accuracy on tuned hardware — that’s a follow-up patch when we have boards to validate against. The default-init ranging here is what most off-the-shelf MicroPython VL53L0X drivers use, and is good for the WRO use cases (line-of-sight, 30–1500 mm).

class openbricks.drivers.vl53l0x.VL53L0X(i2c, address=_DEFAULT_ADDR, timeout_ms=200)[source]

Bases: DistanceSensor

ST VL53L0X laser time-of-flight distance sensor.

Parameters:
  • i2c – a machine.I2C (or compatible) instance.

  • address – 7-bit I2C address (default 0x29). XSHUT-strapping multiple sensors onto one bus requires assigning each a unique address before constructing — outside this driver’s scope.

  • timeout_ms – how long to poll for a measurement to finish. Default 200 ms; the chip is typically done in 33–50 ms.

distance_mm()[source]

Distance ahead in millimetres; -1 if no echo / out of range.

VL53L1X (laser distance, long range)

ST VL53L1X laser time-of-flight distance sensor.

Successor to the VL53L0X with 4 m range (vs 2 m on the L0X) and a different register map. I2C default address 0x29 (same as L0X — XSHUT strapping needed if both share a bus).

The chip-ID lives at 16-bit register 0x010F and reads back 0xEACC for a VL53L1X (or 0xEBAA for VL53L4CD, an L1X-pin-compatible variant).

Like the L0X driver this module ships the minimum register sequence to get usable single-shot ranging on a power-on-default chip. ST’s reference API does an extensive calibration / VHV / SPAD-array selection pass for tuned operation; that lives behind a separate calibrate() method we’ll add when we have hardware to validate against.

Measurement cycle:

  1. Write 0x40 to SYSTEM_INTERRUPT_CLEAR (16-bit reg 0x0086).

  2. Write 0x40 to SYSTEM_MODE_START (16-bit reg 0x0087) — kicks a single-shot ranging.

  3. Poll GPIO_TIO_HV_STATUS (16-bit reg 0x0031) bit 0 until clear.

  4. Read RESULT_FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 (16-bit reg 0x0096) as a 16-bit big-endian value — distance in mm.

  5. Write 0x01 to SYSTEM_INTERRUPT_CLEAR (16-bit reg 0x0086).

VL53L1X registers are 16-bit (vs L0X’s 8-bit) — addresses go through two byte-swaps on the I2C wire. The driver wraps that in _read_u8_16 / _write_u8_16 helpers.

class openbricks.drivers.vl53l1x.VL53L1X(i2c, address=_DEFAULT_ADDR, timeout_ms=200)[source]

Bases: DistanceSensor

ST VL53L1X laser time-of-flight distance sensor (4 m range).

Parameters:
  • i2c – a machine.I2C (or compatible) instance.

  • address – 7-bit I2C address (default 0x29).

  • timeout_ms – how long to poll for a measurement to finish. Default 200 ms; the chip is typically done in ~50 ms.

distance_mm()[source]

Distance ahead in millimetres; -1 if no echo / out of range.