Sensors

One sensor class works with over 200 parts, on I2C or SPI. You don't install a library per sensor — you name the part and the bus, and the build handles the rest.

class

Sensor

A sensor driver instance. Make it from a part token and a bus device, then fetch() and get(): one measurement, many channel values.

Example first

sht3x.ts
import { I2C0, Sensor, SENSOR, CHAN, Time, UART0 } from '@typecad/hal';

// SHT3X temperature/humidity breakout at I2C address 0x44
const sht3x = new Sensor(SENSOR.sensirion_sht3xd, I2C0.device(0x44));

while (true) {
  sht3x.fetch();                               // take one measurement
  const temp = sht3x.get(CHAN.AMBIENT_TEMP);   // read a channel from it
  const rh = sht3x.get(CHAN.HUMIDITY);         // ...same measurement

  UART0.writeLine(temp + ' C, ' + rh + ' %RH');
  Time.sleep(2000);
}

fetch fetch(): void → measurement taken

Takes the measurement.

get get(channel): number

ParameterTypeUnits / valuesDescription
channelCHAN.*driver unitsOne channel of the last fetch — e.g. CHAN.AMBIENT_TEMP. The sensor's type narrows to the part: a wrong channel is a build error naming the channels the driver serves.

Reads one channel from the last fetch().

SPI sensors

The same class takes an SPI bus device — the chip-select pin is part of the device. SPI sensors run at 1 MHz by default, which every part in the catalog tolerates; pass options as a third argument to run faster or change the mode. The bus argument is checked against the part: hand an SPI-only part an I2C0.device(...) and the editor rejects it before you build.

bme280-spi.ts
import { SPI0, PA4, Sensor, SENSOR, CHAN } from '@typecad/hal';

// BME280 on SPI, chip select wired to PA4
const bme = new Sensor(SENSOR.bosch_bme280, SPI0.device(PA4));

bme.fetch();
const pressure = bme.get(CHAN.PRESS);   // hectopascals
bme280-fast.ts
// 10 MHz, SPI mode 3 (CPOL=1, CPHA=1)
const bme = new Sensor(SENSOR.bosch_bme280, SPI0.device(PA4), { spiHz: 10000000, mode: 3 });

Picking a part

SENSOR. lists every supported part, with a short description and its buses on hover. The name is the part's compatible string with commas and dashes replaced by underscores: the SHT3XD's compatible is sensirion,sht3xd, so the token is SENSOR.sensirion_sht3xd. Channels use the same names minus the SENSOR_CHAN_ prefix — SENSOR_CHAN_AMBIENT_TEMP in a datasheet means CHAN.AMBIENT_TEMP here.

Typed channels

typed-channels.ts
const t = sht3x.get(CHAN.AMBIENT_TEMP);  // fine
const p = sht3x.get(CHAN.PRESS);         // build error — the SHT3XD has no pressure channel

The error names the channels the driver actually serves, so the fix is on the screen.

All methods

MemberDescription
new Sensor(part, busDevice, opts?)Part token + I2C/SPI device; spiHz, mode, alert for SPI parts
fetch()Take one measurement
get(channel)Read one channel from the last fetch

Limits

AspectBehavior
BusesOnly I2C and SPI attachments — a part that binds on another bus is rejected with an error naming its real buses
Alert pinsParts whose binding declares an alert-gpios (the SHT3XD, for example) take an alert option wired to a pin
Unscanned partsA handful of parts have no scanned channel list; those accept any channel name and let the driver answer at runtime
© 2026 typeCAD — code-defined electronics github