Sensor Interfacing

Connecting sensors to a microcontroller: analogue sensors through the ADC, digital sensors over I²C and SPI, pulse-timing sensors like ultrasonic rangers, and the scaling, filtering and calibration that turn raw values into physical units.

An MCU sees the world only through its pins. Every sensor must be connected electrically (levels, power, protection) and interpreted in software (scaling, filtering, calibration). The interface type decides both.

Modern designs mix analogue sensors, digital sensor ICs with registers read over I²C/SPI, and timing-based sensors — often dozens on one board.

An analogy

Interfacing a sensor is like hiring an interpreter: some speak in voltages (analogue), some send typed messages (digital buses), and some tap out timing codes (pulses) — the MCU must understand each dialect.

Three interface families

Different sensors need different handling.

Analogue front-end details

Scale the signal into 0–V_ref with dividers or amplifiers, add an RC anti-aliasing/ESD filter near the pin, and keep source impedance low enough for the ADC's sample-and-hold to settle. Use a stable reference and oversampling/averaging to improve resolution.

Digital sensors

Configure the sensor's registers (range, output data rate, filter), then read data registers in bursts. Combine bytes in the right order (big- or little-endian) and sign, then convert using the datasheet sensitivity. Data-ready interrupts or FIFOs avoid polling.

Calibration and fusion

Remove offset and gain errors with calibration (e.g. accelerometer 6-position calibration), compensate temperature, filter noise (moving average, IIR, median for spikes), and fuse sensors (gyro + accelerometer complementary/Kalman filter) for estimates better than any single sensor.

Formulas

Worked example: Ultrasonic distance

Given: Echo width = 5.8 ms; c = 343 m/s (20 °C)

Find: Distance.

Answer: ≈ 0.99 m

Worked example: Accelerometer reading

Given: ±2 g range, 16-bit → 16384 LSB/g; Raw value = 8192

Find: Acceleration.

Answer: 0.5 g

Ultrasonic ranging with an input-capture timer

// HC-SR04: 10 µs trigger pulse, echo width = round-trip time.
// Timer runs at 1 MHz, so captured ticks = microseconds.
float distance_m(uint32_t echo_us, float temp_c) {
    float c = 331.3f + 0.606f * temp_c;   // speed of sound, m/s
    return c * (echo_us * 1e-6f) / 2.0f;  // halve the round trip
}

// Reading a 16-bit accelerometer axis over I2C (±2 g, 16384 LSB/g)
float read_accel_x_g(void) {
    uint8_t buf[2];
    i2c_read_regs(0x68, 0x3B, buf, 2);            // device addr, first register, count
    int16_t raw = (int16_t)((buf[0] << 8) | buf[1]);
    return raw / 16384.0f;
}

Timing sensors use input-capture timers for precise pulse widths; digital sensors return raw register values that must be combined (MSB/LSB) and scaled.

Common mistakes

Applications

Key takeaways

Going further