Sensors
Accelerometer — MEMS sensing, axes, and g-force
An accelerometer measures proper acceleration — not velocity, and not quite what intuition suggests either. A sensor sitting motionless on a desk reads about 1g straight up, not zero, because it's measuring the force the desk applies to hold it against gravity, not gravity itself.
- What it is
- A MEMS sensor that measures proper acceleration (including gravity) by tracking the displacement of a microscopic suspended mass.
- Mental model
- A tiny mass on springs between two capacitor plates — inertia makes it lag under acceleration, and that shift changes capacitance in a measurable way.
- Key numbers
- 3 axes typical, selectable full-scale range (±2g to ±16g), read via I2C or SPI as 16-bit signed values.
- Reach for it when
- You need to sense tilt, shock, tap, freefall, or orientation relative to gravity.
Proper acceleration, not velocity
"Proper acceleration" is what an accelerometer physically measures: the acceleration relative to free-fall, felt as a mechanical force on the sensing element. A sensor in true free-fall (no air resistance) reads zero on every axis, even though it's clearly accelerating downward from an outside observer's point of view — and a sensor sitting still on a table reads +1g, because the table is actively pushing back against gravity. This distinction — measuring the force felt, not the "actual" acceleration in an inertial frame — is the single most common source of confusion for anyone using one for the first time.
How MEMS sensing actually works
Inside the chip is a microscopic proof mass suspended by flexible silicon beams (springs) between fixed capacitor plates. When the sensor accelerates, the mass's inertia makes it lag relative to the frame around it — the mass shifts slightly, changing the gap (and therefore the capacitance) between it and the fixed plates on each side. An on-chip ASIC measures that tiny capacitance change and converts it into a digital value.
Axes, sensitivity, and full-scale range
Most accelerometers report three axes (X, Y, Z) simultaneously, each with its own independent proof-mass/plate structure (or a shared mass sensed along multiple directions, depending on the design). Two configuration values matter for interpreting the output:
- Full-scale range
- The maximum acceleration the sensor can represent — commonly selectable, e.g. ±2g, ±4g, ±8g, ±16g. A wider range tolerates bigger shocks but loses resolution for small movements.
- Sensitivity
- How many raw LSBs correspond to 1g at the selected range — given directly in the datasheet (e.g. "16384 LSB/g at ±2g" for a 16-bit output).
From raw registers to g
The raw value read from the sensor's data registers is a signed integer (two's complement) that needs converting using the sensitivity for whatever full-scale range is currently configured:
int16_t raw_x = (int16_t)((high_byte << 8) | low_byte);
float g_x = raw_x / sensitivity_lsb_per_g; // e.g. / 16384.0f at ±2g
float ms2_x = g_x * 9.80665f; // if you want SI units
Getting the byte order and the signed-vs-unsigned cast wrong here is an extremely common first bug — a value that should read near zero while sitting flat instead reads a huge number, or flips sign at exactly the wrong moment.
Reading it: I2C or SPI
Most accelerometers support both I2C and SPI, selectable via a dedicated pin — I2C for fewer wires, SPI when higher output data rates are needed. Either way, reading a sample is the same shape: write the address of the first data register, then read six consecutive bytes (X low/high, Y low/high, Z low/high) in one transaction so all three axes represent the same instant, rather than three separate reads that could straddle a value changing mid-read.
Interrupt-driven detection
Constantly polling for events wastes power and CPU time, so most accelerometers can generate a hardware interrupt on a dedicated pin (serviced the way GPIO and interrupts describe) for conditions detected entirely on-chip:
- Tap / double-tap — a brief high-frequency spike on an axis, filtered from the slower gravity component.
- Freefall — magnitude across all three axes drops near zero, since a free-falling sensor (briefly) feels no proper acceleration at all.
- Activity / inactivity — magnitude staying above or below a threshold for a configurable duration — the basis of most "wake on motion" designs.
- Orientation change — which axis is currently closest to +1g, used for simple portrait/landscape detection.
Real-world applications
- Phone screen rotation — the classic example: comparing the gravity vector against each axis decides portrait vs. landscape.
- Fall detection — wearables and medical alert devices watch for the freefall-then-shock signature described above.
- Vibration/condition monitoring — industrial accelerometers mounted on motors and bearings detect abnormal vibration patterns that indicate developing mechanical faults.
- Pedometers and activity trackers — step counting is fundamentally peak-detection on the acceleration magnitude signal.
- Drone and robot stabilization — combined with a gyroscope (see Motion & IMU) as the core sensor feeding any flight or balance controller.
Gotchas
- Raw accelerometer data is noisy — a naive "angle from gravity" calculation jitters visibly even when the sensor is still; some smoothing (or, for orientation tracking, fusing with a gyroscope — see Motion & IMU) is usually needed.
- The magnitude of the gravity vector alone can't determine yaw (rotation around the vertical axis) — gravity points the same way regardless of which way the sensor is facing horizontally. A magnetometer or gyroscope is required for that.
- Mounting orientation on the PCB matters — a "level" reading assumes you know which physical axis the datasheet calls Z, and that assumption is a common source of "why is gravity showing up on the wrong axis" bugs.