Flaky [sensor](https://www.ampheo.com/c/sensors) readings almost always come from a handful of root causes. Here’s a concise, field-tested checklist to find and fix them fast.

**1) Usual suspects (by category)**
**Power & grounding**
* Noisy/weak supply: Ripple or droops during sampling.
* Fix: local 100 nF at sensor + 1–10 µF bulk nearby; separate analog LDO if needed.
* Grounding: Shared digital return currents pollute analog ground.
* Fix: star/low-impedance ground, short return for sensor/ADC, single-point AGND↔DGND tie.
* Reference noise: ADC Vref not decoupled.
* Fix: 100 nF + 1 µF at Vref pin, keep Vref trace short and quiet.
**Analog front-end / ADC setup**
* Source impedance too high: ADC sample cap can’t charge in time → saggy values.
Fix: keep source ≤ 5 kΩ (typical MCUs) or increase sample time/buffer with op-amp.
* Aliasing of mains/EMI: Sampling near 50/60 Hz (or harmonics) causes wobble.
Fix: RC anti-alias (cutoff < Fs/5), or sample synchronized to mains + average.
* Common-mode/amp limits: Instrumentation amp outside input range → clipping/offset.
Fix: check headroom vs rails; use proper gain and bias.
**Digital comms (I²C/SPI/UART)**
* I²C: Wrong pull-ups or long cable → edges rounded, bit errors.
Fix: pull-ups 2.2–10 kΩ, keep bus < 400 pF, slow the bus (100–400 kHz), solid GND; check address conflicts/clock stretching.
* SPI: CPOL/CPHA mismatch, CS not stable, MISO floating.
Fix: verify mode, add series [resistors](https://www.onzuu.com/category/resistors) (22–100 Ω) near master, ensure sensor drives MISO only when CS active.
* UART: Baud/format mismatch, noise.
Fix: confirm 8-N-1 (etc.), enable CRC/Checksum if available.
**Environment & sensor physics**
* Warm-up/time constant: Some sensors (gas/IMU/precision temp) need seconds to minutes to stabilize.
* Self-heating: Thermistors/RTDs or bridge sensors with too much current.
* Fix: duty-cycle excitation, lower current, four-wire/Kelvin for RTD.
* Cross-sensitivities: Humidity, airflow, vibration, magnetic fields, light leaks.
**Software & math**
* Naive averaging: Outliers skew means.
Fix: median, trimmed mean, or IIR with outlier rejection.
* Scaling/calibration: Wrong units, missing offset/scale.
Fix: 2-point (or multi-point) calibration stored in NVM.
* Race conditions: Reading multi-byte registers non-atomically; or reading while sensor updates.
Fix: use burst reads/locks, respect data-ready/status bits.
**2) 15-minute triage flow**
1. Power check: Scope Vcc at the sensor while sampling. Look for > 50–100 mV dips/ripple.
2. ADC sanity: Short ADC input to GND then to Vref/2 (via divider). Noise σ should be near a few LSBs.
3. Comms sanity: Read a fixed ID register 1000×; count errors/timeouts.
4. Static input: Feed a stable source (precision ref or fixed resistor); log 60 s → plot mean/σ.
5. Slow the system: Cut sample rate 10× and average 8–16 samples. If noise improves a lot, you’re aliasing or bandwidth-limited.
6. Isolation test: Power [sensor](https://www.ampheoelec.de/c/sensors) from lab supply; connect GND only to MCU → if readings calm down, your 5 V/3V3 rail is noisy.
**3) Solid fixes**
**Hardware**
* Decouple properly: sensor Vcc (100 nF + 1–10 µF), ADC Vref (100 nF + 1 µF).
* RC at ADC pin: e.g., R = 100–1kΩ, C = 1–10 nF right at the pin.
* Buffers & amps: Use rail-to-rail op-amp to drive ADC if source Z is high or signal is small.
* Cables & shielding: Twisted pair for analog, shield to ground one end; keep high-dv/dt lines away.
* I²C pull-ups: Start with 4.7 kΩ at 3.3 V; adjust for length/speed.
* Layout: Keep analog traces short, far from clocks/PWM; solid ground under analog.
**Firmware**
Median / outlier rejection:
```
// 5-sample median (tiny, robust)
int16_t median5(int16_t a[5]){ /* small sorting network */ ... }
// Simple outlier gate around running mean
if (abs(sample - mean) > K*std_est) drop_sample();
```
IIR low-pass (single-pole):
```
// y += alpha*(x - y); alpha in Q15: 0..32767
y = y + ((alpha * (x - y)) >> 15);
```
* Oversample & decimate: 4× samples → average → +1 bit effective resolution (ideal case).
* Synchronize reads: Wait for data-ready / use blocking transfer that reads all bytes in one go.
* Calibration template:
* Measure raw at two known points (x₁,y₁), (x₂,y₂); store slope/offset.
* Apply y = a*x + b each read; optionally temp-compensate with a lookup.
**4) Sensor-specific quick checks**
* [Thermistor](https://www.onzuu.com/category/thermistor-kits)/RTD: Is the divider reference stable? Use ratiometric with ADC Vref = divider Vref; limit current to avoid self-heating.
* Load cell/strain gauge: Shielded cable, INA with proper gain, low-noise supply; sample post-notch for mains.
* IMU (accel/gyro): Mounting vibration? Turn on LPF in the device, align ranges, run bias calibration at rest.
* Ultrasonic/ToF: Multipath & temperature; compensate speed of sound; average multiple pings.
* Gas/pressure: Warm-up time, humidity compensation tables.
**5) Quick “is it fixed?” checklist**
* σ/peak-to-peak noise within datasheet limits
* No CRC/timeout errors on bus
* Stable after warm-up (logged over expected temp range)
* Calibration stored & reapplied after reboot
* Power events (motors, radios) don’t disturb readings