In this guide
How to Calibrate Sensors for IoT Projects
A temperature sensor that reads 3 degrees high. A soil-moisture probe that reports "wet" in bone-dry soil. A weighing scale that drifts 50 grams every hour. None of these sensors are broken — they are uncalibrated. Cheap modules like the DHT22, HC-SR04 or the resistive soil-moisture probe ship with wide factory tolerances, and calibration is the process of measuring each sensor's actual behaviour against a trusted reference and correcting for it. Skip it and every number your project displays is decoration; do it and a Rs. 150 sensor becomes trustworthy enough for real decisions.
The problem: raw values are not real values
Every sensor converts a physical quantity into an electrical signal — a voltage, a resistance, a pulse width. Your microcontroller then turns that signal into a number. Two gaps open up along this chain:
- Sensor tolerance. A DHT22 lists roughly ±0.5°C and ±2–5% RH in its datasheet, and many clone modules sit at the edge of that. MQ gas sensors can vary dramatically between two units of the same batch. Nothing is wrong with your sensor; this is the price of a cheap module.
- Your circuit's quirks. Supply voltage that sags under load, a long wire picking up noise, the sensor warming itself (self-heating), mounting that traps heat — all of these bend readings away from truth.
Calibration closes both gaps at once: instead of trusting the datasheet number, you measure what your sensor in your circuit reports at known physical points, and you build a mapping from raw reading to true value.
How calibration works: the 5-step routine
The same routine applies to almost every sensor you will meet as a student:
- Decide the range you care about. Don't calibrate 0–100% humidity if your project only matters between 30 and 80%. Calibrate the range you will actually use.
- Find a reference. This is the hard part. A reference is anything you trust more than the sensor: a second calibrated instrument, a physical constant (ice water is 0°C), a known mass, a ruler, a multimeter. Better the reference, better the calibration.
- Collect raw readings at several points across the range. Power the sensor exactly as it will run in the project (same supply, same warm-up time), let each reading settle, and write down both the raw value and the reference value. Three to five points across the range is usually enough for a student project.
- Build the mapping. The simplest correction is offset + scale:
true = raw * scale + offset, found from two reference points. If the error curves (many gas and moisture sensors are nonlinear), use a small lookup table or piecewise linear segments instead of forcing one straight line. - Validate on a fresh point. Pick a reference point you did not use for fitting, apply your correction, and check the error. If it passes, record the date, the sensor, and the correction values — recalibration starts from this record, not from scratch.
Worked routines for the sensors students actually use
Temperature and humidity (DHT22 / DHT11)
Use the ice-point method: a sealed bag holding the sensor in a cup of crushed ice and a little water gives you a trustworthy 0°C reference. Let it stabilise for 5–10 minutes (temperature sensors are slow). Record the raw reading, then do the same at a comfortable room temperature checked against any decent household thermometer. Two points, one line, done. Re-check the ice point every few months — these polymer sensors drift with age and humidity exposure.
Resistive soil-moisture probes
These are relative sensors, not precision instruments, so calibrate them in relative terms: note the raw analog value with the probe in dry air, then pushed into soil watered to saturation, and let it drain to field capacity (the moisture level a few hours after watering). Map dry → 0% and field-capacity → 100%. Crucially, never power the probe continuously — constant DC through the probes corrodes them within weeks and your calibration quietly invalidates itself. Power it from a digital pin, read, then switch it off.
Load cells and weighing platforms
The HX711 amplifier plus a load cell is the classic student scale. Calibrate with two known masses: zero (empty platform) and a full bottle of water or a 1 kg weight measured on a kitchen scale. Two raw readings give you offset and scale. The common gotcha is drift: cheap load cells creep with temperature, so do the calibration at the temperature the project will actually run, and re-zero periodically in software.
Ultrasonic distance (HC-SR04)
Measure real distances with a tape measure at 30, 100 and 200 cm, holding the sensor at the height and angle it will actually be mounted. HC-SR04 errors are often a fixed offset plus a slight scale error, so a two-point line handles most of it. Temperature matters here too: the speed of sound changes about 0.6 m/s per °C, so an outdoor sensor calibrated on a 25°C afternoon will read a few percent off on a cold morning — correct with a temperature reading if the range is large.
MQ gas sensors (MQ-2, MQ-135, etc.)
Be honest about these: without a calibrated gas source you cannot get absolute ppm numbers, only relative trends — and for most student projects ("gas leak detected → alarm"), relative is enough. Burn the sensor in for 24–48 hours in clean air before trusting anything (the datasheet requires this), record the clean-air baseline resistance, and set your alert threshold as a ratio above that baseline. Recalibrate the baseline in fresh air regularly; these sensors age fast.
Applying the correction in code
Keep the math in one place so it is easy to re-run calibration later:
# Two-point linear calibration: map raw ADC readings to true units.
# cal_raw_a, cal_raw_b = raw readings at known reference points
# ref_a, ref_b = the true values at those points (measured with a reference)
def build_calibration(cal_raw_a, ref_a, cal_raw_b, ref_b):
scale = (ref_b - ref_a) / (cal_raw_b - cal_raw_a)
offset = ref_a - scale * cal_raw_a
return scale, offset
def apply_calibration(raw, scale, offset):
return raw * scale + offset
# Example: soil-moisture probe, dry air = 980, field capacity = 350
scale, offset = build_calibration(980, 0.0, 350, 100.0)
moisture = apply_calibration(620, scale, offset) # ~55.4 %
Two habits make calibration stick in firmware. First, average several readings before correcting — a 5-sample moving average removes the jitter that makes calibration look worse than it is. Second, store the calibration constants as named values at the top of your code (or in EEPROM/flash on an ESP32), never baked into random lines of logic, so re-running step 3 above means changing two numbers instead of rewriting the sketch.
Drift, recalibration and when to stop
Calibration is not permanent. Polymer humidity sensors drift with age, gas sensors age noticeably, load cells creep, and batteries sagging from 4.2 V to 3.7 V change every analog reference derived from supply voltage. Practical schedule for a student build: re-verify against your reference points right before the demo or review, and any time you change the power supply, the wiring length, or the mounting. For long-running deployments, re-zero against a known state (empty platform, clean air) on a weekly or monthly rhythm.
Also know when calibration is not the answer. If readings jump randomly between samples, you have a noise or grounding problem — fix the wiring before fitting any line. If the sensor saturates (analog value pinned at 0 or 4095 across your whole range), it is the wrong sensor for the range, and no math rescues it. And some sensors simply cannot be calibrated absolutely on a student budget — MQ gas sensors and cheap dust sensors are trend devices; treat them as such in your report and you will sound more competent, not less.
FAQ
Can I calibrate without any reference instrument?
Often, yes — physical constants are free references. Ice water (0°C), a tape measure, a known mass of water (1 litre ≈ 1 kg), dry air versus saturated soil — these cover most student projects. The reference just has to be more trustworthy than the sensor for the range you care about.
How many calibration points do I need?
Two points are enough when the error is linear (offset + scale), which covers most student cases. Add three to five points and a piecewise mapping when you see the error curving — typical for moisture, gas and light sensors.
Does factory calibration count?
It counts as a starting point, not a finished job. Factory specs describe the sensor element on a test bench, not your module, your 3.3 V rail, your wiring and your enclosure. The cheap modules students buy are often clones with looser tolerances than the datasheet anyway.
Should calibration live in the sensor library or my code?
In your code (or your config values). Libraries report the sensor's raw behaviour; the calibration describes your specific sensor, in your circuit, at your site. Keeping it separate means a sensor swap costs you a two-number change instead of a firmware rewrite.
Why do my readings drift between morning and evening?
Temperature. Sensor behaviour, supply voltage, the speed of sound for ultrasonics — all temperature-sensitive. If the project runs in varying temperatures, either calibrate across the temperature range too or add a temperature sensor and correct in software.
Limitations
- Calibration corrects systematic error, not noise: if readings jitter wildly, fix grounding, decoupling and wiring first.
- Without a trustworthy reference, the best you can claim is repeatability (same conditions → same reading), not absolute accuracy — say so in your documentation.
- Student-grade sensors drift: treat calibration as periodic maintenance, not a one-time ritual.
- Some sensors (MQ gas, cheap particulate sensors) give only relative trends on a student budget; presenting them as calibrated instruments misleads whoever reads your report.