It’s been a few days, which means it’s time to check on the results of my multi-thermistor experiment. But before I worry about that, it would be important to revisit the anomalies around the ring thermistor resistance insulation test results, fit the Molex data for all thermistors to a fifth-order equation so that I can interpret the results from the experiment and examine the performance difference in terms of computation time between the straightforward Beta model, the Steinhart-Hart model and the 5th-order model.
Table of Contents
Ring Thermistor Insulation Resistance Redux
In a previous post, I looked at insulation resistance by dipping thermistors into a thermos-like pot filled with water, using the thermos itself as an electrode and subjecting the combination to a 1000V DC insulation resistance test. The results for the ring thermistors did not look right and scottiebabe came up with a plausible explanation – condensation in the connectors, perhaps.
As a result, I decided it would be important to redo this, after giving the thermistors enough time to dry (naturally). This time, I decided to go without water first – given the thermistor was fully encapsulated in epoxy inside of the ring, I connected one side of the tester to the ring itself and the other to the two pins of the connector. That should result in a roughly-equivalent, and valid result.
In the end, I’d have to say that guess was probably spot-on – the retest shows an off-scale high reading, indicating no problems with the insulation whatsoever.
Fitting All the Thermistors to a 5th Order!
In order to convert measured resistance to a temperature, we need to use a model of the thermistor. Knowing that literally everything from ADC errors, reference voltage errors, thermistor tolerances and divider resistor drifts can affect the accuracy of the result, I wanted to minimise the model error contribution and as such, I have settled on the use of the fifth-order model with the Molex-provided rounded resistance values as the best way forward.
To do this required hand-keying all the resistance values from the drawing documents and then using a 5th-order fit to each of the curves where y = 1/T (in Kelvin) and x = ln(R). The resulting coefficients are tabulated below and the worksheet with the raw values is available for download at the end of this blog posting.
Molex 5th Order Fit Coefficients by Gough Lui |
|||||||
|
1/(T in K) = |
A * x^5 |
+ B * x^4 |
+ C * x^3 |
+ D * x^2 |
+ E * x |
+ F for x = ln(R) |
2152723307 |
3892K 3k 1% |
3.80809132E-08 |
-1.48966767E-06 |
2.32953414E-05 |
-1.79171347E-04 |
9.21772647E-04 |
3.71743954E-04 |
2152723407 |
3892K 4k7 1% |
-1.18278686E-08 |
5.93812563E-07 |
-1.10233859E-05 |
9.87776523E-05 |
-1.84247747E-04 |
1.99002543E-03 |
2152723507 |
3892K 5k 1% |
-4.33580388E-08 |
1.97478159E-06 |
-3.48279889E-05 |
3.00342165E-04 |
-1.02179886E-03 |
3.33994017E-03 |
2152723607 |
3892K 10k 1% |
-6.27547776E-08 |
2.87979118E-06 |
-5.17990752E-05 |
4.60261389E-04 |
-1.78345763E-03 |
4.64380389E-03 |
2152723707 |
3892K 12k 1% |
-6.20949445E-08 |
2.90696345E-06 |
-5.33806035E-05 |
4.84382779E-04 |
-1.93546656E-03 |
4.94777424E-03 |
2152723807 |
3892K 30k 1% |
-3.65028161E-08 |
1.93635907E-06 |
-4.07661496E-05 |
4.29336733E-04 |
-2.02408106E-03 |
5.63567887E-03 |
2152723907 |
3892K 47k 1% |
-4.76064152E-08 |
2.63913828E-06 |
-5.77562143E-05 |
6.26510176E-04 |
-3.12712817E-03 |
7.90795634E-03 |
2138601637 |
3500K 10k 1% |
-8.09793196E-08 |
3.86144435E-06 |
-7.28377697E-05 |
6.82498059E-04 |
-2.89875788E-03 |
6.64526916E-03 |
2138622637 |
3800K 10k 1% |
-5.25246443E-08 |
2.55553497E-06 |
-4.92404763E-05 |
4.72276476E-04 |
-1.99634764E-03 |
5.24166076E-03 |
Experiment: Computational Performance
If the fifth-order model is so accurate, why do the other models still get used? That’s a great question. One thing that stood out to me is the computational time necessary to derive the values which could be a constraint especially in low-powered microcontrollers. As a result, I decided to write a short benchmark in Arduino to compare the computational performance of a Beta model with the Steinhart-Hart Equation model and the fifth-order model.
// Thermistor Model Calculation Benchmark // Beta Model, Steinhart-Hart Model and 5th Order Model // by Gough Lui - August 2022 #define LOOPCOUNT 400 volatile float val[LOOPCOUNT]; volatile float res; unsigned long beginus; unsigned long endus; void fillRandom () { for (int i=0;i<LOOPCOUNT;i++) { val[i]=random(900000,1100000)/100.0; } } void setup() { randomSeed(analogRead(A0)); Serial.begin(115200); while(!Serial) { } Serial.println("Starting ..."); delay(5000); Serial.println("Thermistor Model Calculation Benchmark"); Serial.println("By Gough Lui - August 2022"); Serial.print("Beta Model: "); fillRandom(); beginus = micros(); for (int i=0;i<LOOPCOUNT;i++) { res=1/((-log(10000/val[i])/3897)+(1/(25+273.15)))-273.15; } endus = micros(); Serial.print((endus-beginus)/LOOPCOUNT); Serial.println(" us"); Serial.print("Steinhart-Hart Model: "); fillRandom(); beginus = micros(); for (int i=0;i<LOOPCOUNT;i++) { res=1/((1.100669397214E-03)+(2.389573070441E-04)*log(val[i])+(6.722278769201E-08)*pow(log(val[i]),3))-273.15; } endus = micros(); Serial.print((endus-beginus)/LOOPCOUNT); Serial.println(" us"); Serial.print("Fifth-Order Model: "); fillRandom(); beginus = micros(); for (int i=0;i<LOOPCOUNT;i++) { res=(1/((-6.27547776E-08)*pow(log(val[i]),5)+(2.87979118E-06)*pow(log(val[i]),4)+(-5.17990752E-05)*pow(log(val[i]),3)+(4.60261389E-04)*pow(log(val[i]),2)+(-1.78345763E-03)*log(val[i])+(4.64380389E-03)))-273.15; } endus = micros(); Serial.print((endus-beginus)/LOOPCOUNT); Serial.println(" us"); Serial.println("Completed!"); } void loop() { }
The benchmark generates 400 random resistance values (to 0.1-ohm resolution) and then converts these values into temperatures while timing the whole process and dividing by 400 to report the number of microseconds (integer) required to process the data. To be sure that compilers would not optimise-out the process, the resulting variable is declared volatile. To avoid influences of the time taken by the random function, the generation of values occurs before the benchmark begins, although this now means that the timing is not of just the algorithm but also memory accesses. I ran the test on any board I could find that I had on-hand that was Arduino-compatible, using 1.8.19 version IDE and the latest version of core files to support the boards.
The results were quite enlightening:
It is not unexpected that the simple Beta model was the fastest, with Steinhart-Hart taking about two to three times the amount of computation time and the fifth-order model taking seven to eight times the amount of computation time when looking at the AVR 8-bit results. For the SAMD21, the Beta model seems to be much faster, with the Steinhart-Hart taking six to seven times the amount of time and the fifth-order taking 18-times the amount of time. The differences seem even greater on the ESP32 architecture where the fifth-order model takes 30-times the amount of time.
This is most easily seen when the times are plotted as a factor of the Beta model time.
However, while the differences may be big in terms of percentage, the absolute time needed may well be acceptably short. In the case of the AVR 8-bit, the fifth-order model takes just shy of 2ms for a conversion, while on SAMD21, it was about 2.5ms.
Other architectures at their maximum clock rate were substantially better – PIC32 was 0.78ms, ESP8266 was 0.625ms, ESP32 was 0.121ms and RP2040 was just 0.071ms. At reduced clock speeds, the performance was proportionally worse; and likewise at increased clock speeds, it was proportionally better providing confidence in the benchmark accuracy.
Given these results, it seems that perhaps the time taken for the more sophisticated fifth-order model is not a dealbreaker even when implemented on microcontrollers, but the Beta model will still save time and energy at the cost of accuracy. Perhaps it’s the energy that is more of the concern, especially for battery-operated devices.
Results: Multi-Thermistor Experiment
After several days of operation, I decided I had collected enough data to call an end to the multi-thermistor experiment. In total, 334,323 samples were recorded and I analysed them using a mixture of Excel and MATLAB. Instead of using the nominal resistances for the divider resistors, I used the multimeter-measured values as posted in the previous blog.
Looking at the temperature logged by a single BMP280, the temperature varied between 14-23°C or so through the testing period.
However, agreement between the two BMP280 sensors was not as close as expected. Even though they may be ±1°C by datasheet, the resulting average temperature difference is about 0.9°C. This may be because one of the sensors was closer to the MKR WiFi 1010 and receiving some radiated heat from it.
Rather than take any one BMP280 reading as accurate, I decided to average both and use that as the reference value.
Looking first at the 3kΩ thermistor, we can see an error that has a diurnal pattern – it trends closer to zero during the daytime, with an negative error during night-time. This suggests to me that comparing the BMP280 values with the thermistor values is probably a bad idea because the BMP280 may also have a second source of error – perhaps an internal self-heating.
The difference histogram seems to have a double-peak (with a smaller peak in-between), which is probably caused by the durnal temperature error difference, even though most of the difference is confined to 1.5°C.
Graphs for all other thermistors show a similar trend, with a similar amount of error, suggesting to me that this may well be an issue with the BMP280 itself as well.
The amalgamated plot above shows just how similar the results are, with a slight offset because of individual thermistor tolerances/errors. I’ve previously noticed that such digital temperature sensors will overestimate temperature especially at lower temperatures, so perhaps this is not unexpected to me.
Instead, it seems better to compare thermistors with each other, so I took the 3kΩ reading as the reference and compared the others to it.
This gave a much better-looking plot. Lower-value thermistors appear to provide more “tightly bunched” results, perhaps due to input impedance issues resulting in lower noise readings. Such lower-valued thermistors were able to provide results within about 0.25°C. Higher valued thermistors seem to produce broader spreads of errors, but all variances remained within 0.5°C. Some error will always happen because of the curve-fitting process, but this suggests to me that the thermistors are quite accurate comparing unit-to-unit of different resistances given minimal care (averaging and reference resistances measured, but no compensation for ADC offsets or characterisation of reference resistance drift over temperature).
Post-experiment, I did a quick check and found the zero-error for the ADC was about 46ppm or about 0.19 LSB; and at full input, it saturated at the full value so the maximum input error was not accurately determined.
Conclusion
In this post, the ring thermistors were retested for insulation resistance and passed with flying colours, reading an off-scale high. This suggests it was probably condensation in the connector causing strange readings in the past.
A fifth-order equation fit was made to Molex-provided rounded resistance data. This was used in subsequent parts to determine temperature errors.
Computational time requirements for the Beta, Steinhart-Hart and fifth-order models were compared. It was no surprise that the Beta model was the fastest of all, with the Steinhart-Hart taking two to ten times the amount of time and the fifth-order taking the longest, requiring between six to 30 times the amount of time. The results were dependent on the architecture of the microcontroller used. However, even in this case, results were forthcoming in about 2.5ms at microcontroller-default clocks which still makes it fast-enough for many applications. Perhaps the use of simpler models is, in part, due to energy constraint rather than computation time.
The results of the multi-thermistor experiments showed the two BMP280 sensors had less-than-expected agreement with an average difference around 0.9°C and comparisons with thermistors showed a clear diurnal difference in errors. Histogram plots showed two or three peaks, suggesting the comparison is a poor one. The cause may be due to BMP280 internal self-heating effects, conducted/radiated heat from the MKR WiFi 1010 and the slight difference in height between the sensors. This difference is something I have previously observed when comparing digital temperature sensor results to that of thermistor-based commercial weather-station sensors.
Comparing thermistor results between each other showed lower-value thermistors (12kΩ and below) had excellent agreement, all within 0.25°C, with higher-value thermistors showing a broader spread of error values with differences reaching up to 0.5°C. Considering the minimal effort in calibrating the ADC and the use of rounded nominal values from the manufacturer, the result was quite a bit better than I had imagined.
In case you too are interested in using the fifth-order model, or you just don’t want to have to manually type in the nominal resistances from the Molex datasheet, my workbook can be downloaded here – MolexThFitData.zip
Raw sample data from the multi-day experiment is also available for download as a zipped binary Excel workbook - MultiThermExpt-NoFormulasMinData.zip
[[Characterising Thermistors Blog Index]]
- Blog #1: Characterising Thermistors - Introduction
- Blog #2: Characterising Thermistors - What's In The Box?
- Blog #3: Characterising Thermistors – A Quick Primer, Beta Value & Steinhart-Hart Coefficients
- Blog #4: Characterising Thermistors – An Inconvenient Truth, Taking Things to the Fifth Degree
- Blog #5: Characterising Thermistors – Measuring Resistance Is Not So Easy!
- Blog #6: Characterising Thermistors – Is Self-Heating a Problem or Not?
- Blog #7: Characterising Thermistors – Boiling, Freezing and Zapping the Truth Out of Them!
- Blog #8: Characterising Thermistors – Practically Running Multiple Thermistors
- Blog #9: Characterising Thermistors – Multi-T Results, Insulation R Redux, 5th Order Fits & Model Performance
- Blog #10: Characterising Thermistors – Multiple Thermistors on ESP8266
- Blog #11: Characterising Thermistors – Show Me Your Curves
- Blog #12: Characterising Thermistors – Sticking Rings on Tabs & Sinks, Absolutely Crushing It!
- Blog #13: Characterising Thermistors – Pulling Out, Overload, Response Time, Building a Flow Meter & Final Conclusion