Sensor calibration
SHT41 calibration against a simple reference setup
I wanted to know whether two SHT41 boards in the house were different enough to justify per-sensor offsets. The goal was not laboratory calibration. I only needed a repeatable check that could separate a real sensor offset from placement effects, self-heating, and normal room gradients.
Setup
Both boards were powered from the same 3.3 V rail and connected one at a time to the same ESP32. SDA used GPIO 21 and SCL used GPIO 22, with 4.7 kΩ pull-ups to 3.3 V. I kept the boards about 30 mm apart inside a 1.5 L food container with several small holes in the lid. A slow 40 mm fan outside the container moved room air around it without blowing directly across either sensor. The reference was a calibrated handheld thermo-hygrometer placed between the boards.
I sampled every five seconds and ignored the first twenty minutes. After that, I logged thirty minutes of data and compared medians rather than individual readings. The room was deliberately left undisturbed: no open window, no humidifier, and no direct sunlight.
| Device | Temperature | Humidity | ΔT vs ref. | ΔRH vs ref. |
|---|---|---|---|---|
| Reference | 22.42 °C | 45.8 %RH | — | — |
| SHT41 A | 22.55 °C | 46.1 %RH | +0.13 °C | +0.3 %RH |
| SHT41 B | 22.78 °C | 44.9 %RH | +0.36 °C | −0.9 %RH |
The most useful observation came from swapping the physical positions of A and B. About 0.08 °C of the original difference followed the position rather than the sensor. That was enough to stop me from treating a single side-by-side reading as a calibration result.
Applied correction
I left sensor A uncorrected. For sensor B I stored only a temperature offset of −0.25 °C. The humidity difference was small enough that adding a correction would mostly create false precision. The firmware applies the temperature correction after reading the sensor and before publishing the value:
float temperature = sht41.getTemperature();
float humidity = sht41.getHumidity();
temperature += config.temperatureOffsetC;
publishClimate(temperature, humidity);
I also repeated the check at roughly 18 °C and 25 °C. The B sensor stayed high by about 0.2–0.3 °C, which is consistent enough for this use. If the offset had changed strongly with temperature, a single constant would have been the wrong model.