← How-Tos
electronics Aug 26, 2026 ◑ 3 views ◯ 4 min read

Environmental Sensor Calibration and Long-Term Drift: BME280, SCD40, and Getting Accurate Readings Over Time

BME280SCD40sensor calibrationCO2 sensorhumidity sensordrift compensationESP32environmental monitoring

Wiring up a BME280 or an SCD40 and reading numbers over I2C is the easy part — that's covered in the general air quality and sensor wiring content on this site. What isn't covered there is what happens six months later, when your "accurate" sensor is reading humidity 8% low, or your CO2 sensor has drifted so far that it never reports below 800ppm even in fresh outdoor air. Every low-cost gas and humidity sensor drifts, and if you're building anything you actually trust — a greenhouse controller, a workshop air quality monitor, a whole-home CO2 tracker — you need a calibration routine, not just a wiring diagram.

Why Environmental Sensors Drift

Automatic Self-Calibration (ASC) — and Why You Might Want to Turn It Off

The SCD40/SCD41 ships with Automatic Self-Calibration enabled by default. It works by assuming that, over a rolling multi-day window, the sensor will see at least one period of fresh outdoor-equivalent air (~420ppm) — typically overnight in a well-ventilated home — and it quietly recalibrates its baseline to that assumption. This works well for a bedroom or living room with normal ventilation. It works badly for:

In these cases, disable ASC via the sensor's I2C command set (set_automatic_self_calibration(0) in most ESP32/Arduino libraries) and instead calibrate manually with a known reference — see below.

Manual Calibration Methods by Sensor Type

SensorMethodReference NeededFrequency BME280/BME680 (humidity)Salt calibration (75% RH) or side-by-side comparison against a calibrated hygrometerSaturated NaCl solution in a sealed container, or a known-good reference sensorEvery 6–12 months SCD40/SCD41 (CO2)Forced Recalibration (FRC) command with the sensor exposed to fresh outdoor air (~420ppm) for at least 3 minutes of stable readings firstConfirmed fresh outdoor air, or a certified reference gasEvery 6 months, or after any suspected drift event MOx VOC sensors (SGP30, CCS811, etc.)Baseline resistance capture after 48-hour burn-in, stored and reloaded on every bootClean air environment for burn-inBaseline should be reloaded every boot; full recalibration every 3–6 months

The Salt Calibration Method for Humidity (Detailed)

  1. Make a saturated solution of plain table salt (NaCl) in a small amount of distilled water in a sealed container — enough salt that undissolved crystals remain visible at the bottom.
  2. Place the sensor inside the sealed container, suspended above the solution (not touching it), and seal it up.
  3. Let it equilibrate for at least 6 hours, ideally overnight, at a stable room temperature.
  4. A saturated NaCl solution produces a highly repeatable 75.3% RH environment at 25°C. Compare your sensor's reading against that reference value.
  5. Apply the offset in software — most BME280 libraries let you apply a calibration offset in the driver layer rather than modifying firmware calibration registers directly.

Building Drift Compensation Into the Firmware

Rather than treating calibration as a one-time event, a more robust design bakes drift handling into the firmware itself:

None of this turns a $10 sensor into a laboratory instrument, and it shouldn't need to — the goal is knowing roughly how much to trust a reading and catching the failure mode where a sensor drifts quietly for months while your dashboard keeps reporting numbers with false confidence. A simple 6-month calibration reminder, whether it's a recurring note or a firmware flag, is enough to keep any of the environmental monitoring projects on this site honest over the long run.