-
Notifications
You must be signed in to change notification settings - Fork 12
W1209 Sensor
The W1209 sensor input consists of a ratiometric setup: the resistance of a resistive sensor is compared with a reference resistor of 20K (likely 1%). The implementation is simply a voltage divider using the 5V supply voltage. The STM8S 10bit ADC measures the ratio by using the same supply voltage as a reference, and hence drift of the supply voltage doesn't influence the measured ratio.
Note: there was a report about a hardware variant with a 5k reference sensor. Please refer to issue #17!
However, the following properties should be kept in mind:
- the setup doesn't measure resistance, but a ratio
- the resolution (resistance-change / digits) is best when the sensor resistance matches the reference resistor
- resolution is best around 0°C
- there are many sources of error (sensor/reference resistor tolerance, ADC error (offset, linearity, missing digits)
- expect 13 digits between 90°C and 100°C, and 10 digits between 100°C and 110°C.
- expect the total unadjusted error of the ADC to be up to 4 digits
- expect noise to be > +/-10 digits
The takeaway is this:
- noise can be turned into resolution by low pass filtering, but not into accuracy
- adjusting (calibration) mitigates some of the error
- never ever use the W1209 for anything that you don't want to go wrong!
Refer to the measure.fs example implementation for filtering, adjusting/scaling, and dealing with noise.
NTC sensors are cheap and highly sensitive but there are many different sensors with the same R25 rating, and very different characteristics, and accuracy. A good example are the datasheets of the EPCOS B57164, and the Vishay NTCLE100E3 thermistors.
EPCOS doesn't promise much in terms of accuracy:
Chinese vendors probably won't tell you which NTC sensor they use. A search for NTC 10K on AliExpress reveals the type MF52AT, which again point to datasheets that look like this. The R=f(temperature)
is at least similar to the temperature=f(R)
function programmed into an off-the-shelf W1209 (the error at 50°C is about 3%). Another tag sometimes found is NTC10K/B3950.
Of course, the STM8 ADC also adds error. Due to the input circuit used, between 30°C and 40°C the ADC W1209 has a delta of just 70 digits (about 0.14°K per digit). There is a lot of noise on the ADC, much more than a digit, which, through averaging, works to our advantage, and detecting relative changes much smaller than 0.1°K is possible. However, you can never know whether the change is due to the ADC, power supply noise, or a real temperature change.
The best you can hope for is reproducibility of the NTC resistance at a certain temperature. The only way to get anything like accuracy from an NTC sensor is to compare the readout with a reference, and store it. If the intension is to build an chicken egg incubator then a clinical thermometer is a good reference. On the bright side, I compared a number of temperature sensors that came with different thermostat boards (W1209, W1701), and they all gave readings within a 0.2°K range at room temperature. However, I also have a thermometer that's 1.7°K off at 20°C!
As a starting point, the following table was compiled using two W1209 boards and a trimmer. It shows low-pass-filtered ADC digits from a 1st W1209, displayed temperature (°C) from a 2nd W1209. The values were acquired with a 10k, and a 50k trimmer, the program below, and a multimeter.
Note that the resistance values do not match those of the 10k EPCOS NTC B57164K0103K000-2904 referenced above!
LPF [16* ADC6 digits] | Temp [°C] | R [kΩ] |
---|---|---|
11233 | -10.0 | 44.1 |
10384 | -5.0 | 34.6 |
9506 | 0.0 | 21.6 |
7761 | 10.0 | 18.1 |
6191 | 20.0 | 12.2 |
5471 | 25.0 | 10.0 |
4816 | 30.0 | 8.33 |
3685 | 40.0 | 5.83 |
2817 | 50.0 | 4.18 |
2160 | 60.0 | 3.05 |
1648 | 70.0 | 2.25 |
1280 | 80.0 | 1.69 |
991 | 90.0 | 1.31 |
767 | 100.0 | 1.00 |
608 | 110.0 | 0.792 |
Program used (base: W1209-FD.ihx from the STM8EF v2.2.13 binary release):
\ W1209 measures U with Q12.4 LPF U = adc + U - U/16
NVM
VARIABLE U
: adc ( -- n )
6 ADC! ADC@ 0 ADC!
;
: lpf ( n -- n )
U @ DUP 16 / - + DUP U !
;
: measure ( -- )
adc lpf .
;
: start ( -- )
0 U !
[ ' measure ] LITERAL BG !
;
' start 'BOOT !
RAM