Temperature Sensors Accuracy and Calibration

I am in the process of deploying a dozen+ temperature sensors, and I thought sharing my experience could be of some help, especially after reading some of the comments on the forum about the poor accuracy of the ST Multi-Sensor.
Close calibration of temperature sensors is beneficial if you want to use multiple measurements points in a large house to control your central heating system.
Using the procedure outlined below and a custom handler, you can achieve +/- 0.1°C consistency.

I use a Z-Wave Fibaro FGK-101 Door/Window Sensor (http://www.fibaro.com/en/the-fibaro-system/door-window-sensor) with the optional TO-92 DS18B20 temperature sensor.
The Dallas/Maxim DS18B20 datasheet (datasheets.maximintegrated.com/en/ds/DS18B20.pdf) specifies its absolute accuracy as +/-0.5°C from –10°C to +85°C.
That implies roughly that temperature differences lower than 1°C between 2 sensors should not be significant.

But 2 things can be done to improve, at the minimum, consistency between sensors :

  1. selection of well matched DS18B20
  2. sensor temperature correction from within a custom device handler

1) Selection of well matched DS18B20
You can buy a lot of 10 DS18B20 on eBay for less than $10.
Within that lot, some items will be very close, some will father away, with a worst case of 1°C dispersion between 2 sensors
So the first thing to do if you want to closely match a dozen temperature sensors is to activate all those sensors in the same room, a few inches apart, and get all the temperature measurements, taken a the same time.
You need to set the handler so that it reports temperature values with 2 decimals.
Make 4 measurements of your sensors values at different times and temperatures, enter the results in an Excel file, and check what sensors are closest to the average value, and what are the most divergent ones.
My own experience showed most sensors within +/- 0.3°C, with one 0.9°C apart.
=> change the DS18B20 for the most divergent one(s) and check again.
After a few iterations, your sensors should report the “same” temperature within +/- 0.3°C
Note that after you manipulate by hand a DS18B20, you will need to wait for at least 2 hours for the temperature it measures to stabilize (your fingers are at 37°C…).

2) Sensors temperature correction using a custom device handler
Now that your set of DS18B20 are well matched, take half a dozen measurements at different times and temperatures.
Enter the results in a spreadsheet (I used Excel) and compute the temperature average for each set of measurements (same time).
Ideally, you want all sensors to report the same value at each of those measurement times.
Thus for each time and each sensor, you can compute a correction : correction = average_value_for_set_at_time - actual_measured_value.
Compute then for each sensor the average correction for all measurements at different times.
Then, get the hardware specific device id (log debug “${device.id}” from the IDE Simulator) and include in your custom handler a systematic correction of the returned temperature values, using code such as :

def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd) {
    switch (device.id) {
            case 'd3100f6a-22d0-4f80-97b3-b15f7c788aef' :    
                scaledSensorValue = scaledSensorValue + 0.0709 /*computed correction*/
                break;
            case '97bcdb11-69a9-4851-af7f-6482a79d1560' :    
                scaledSensorValue = scaledSensorValue - 0.0452 /*computed correction*/
                break;
        }

Using those 2 calibration procedures, I was able to achieve better that +/-0.1°C consistency over a dozen temperature sensors, over the usual heating temperature range (20-30°C).
Obviously, you do not want to go into all that if a +/-1°C consistency is good enough for you…

1 Like

Unfortunately, device.id is not as stable as I hoped : it is changed every time you pair/unpair the device to its hub.
Although it can be modified too easily, device.name is thus probably a better choice.
The example code becomes :

def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd) {
    switch (device.name) {
            case 'T001' :    
                scaledSensorValue = scaledSensorValue + 0.0709 /*computed correction*/
                break;
            case 'T002' :    
                scaledSensorValue = scaledSensorValue - 0.0452 /*computed correction*/
                break;
        }

Thanks for this! I’m in the process of setting up a Raspberry Pi with various sensors, and this is great information.

You are welcomed :slight_smile: