My attempts to make a rapid prototyping machine that I will use to make parts for a machine that will be able to make parts for a copy of itself.

Sunday, 25 November 2012

More accurate thermistor tables

A couple of weeks ago I wanted to create some thermistor tables for Marlin. At that time it had a copy of createTemperatureLookup.py, which I think was written by Zach Smith based on my article "Measuring temperature the easy Way". It uses the simple two constant thermistor equation based on the resistance at 25°C and beta.The two constant formula was adequate for my own software because I have separate constants for each thermistor that I use and I calibrate them against a thermocouple at the working temperature and room temperature. Marlin however has a thermistor table for each type of thermistor, so if you use the same thermistor for the bed and the hot end they share a table. The problem with the simple equation is that beta is not very constant and depends on temperature. There are several values given on the datasheet for different temperature ranges, none of them very applicable to our application. If you have beta correct for the hot end at say 250°C it is about 7°C out at the bed temperature, say 130°C.I decided to make a new script which uses the three constant Steinhart–Hart equation. The graph shows the difference between the two equations over a large temperature range: -

The two constant equation is only accurate around the two temperatures the constants are calculated at (in this case 25°C and 256°C). When these are at opposite ends of the thermistors range the error in the middle is quite large.The script I made is MakeTempTable.py. Its parameters are resistances at three temperatures. The tables is makes look like this: -

The ADC values in the table are multiplied by 16 because Marlin uses oversampling to give four more bits of precision. The old tables just multiplied the integer ADC value by 16 but I multiply it before rounding it to an integer so the table has the same precision as the oversampled ADC reading.The script can also take ADC values as parameters instead of resistances. This allows you to calibrate a thermistor in situ. If you set the temperature to a value in an existing table and let it settle and then measure it with a thermocouple you know that the ADC value for the measured temperature is the value in the table for the set temperature. You can then produce a new more accurate table.Two days after I put it on Github ErikZalm added a new script to the official version of Marlin to do exactly the same thing: createTemperatureLookupMarlin.py, amazing coincidence! It is different code but I think it uses exactly the same maths to find the three coefficients using simultaneous equations that I lifted from here.

16 comments:

Next time I will check your github before I rewrite a tool.There where some users on IRC that had problems with the thermistor accuracy. That is why I rewrote this tool.Your version is much cleaner. I replace mine.

When I work with thermistors at work, I usually use the B parameter equation. http://en.wikipedia.org/wiki/Thermistor#B_or_.CE.B2_parameter_equation

I would think with that equation you could pass the datasheet parameters, Beta, Resistance at a temperature, and the temperature that was measured at. In your table I'm not sure what Beta is, but the other two parameters would be 100k and 25. That's a good way to get an initial table, but your method may be better in the end for getting something that's well calibrated.

Thav, The whole point of the article is that the B parameter equation is not accurate enough over a wide range and the data sheet values are only given for 0-100, 20-100 and 20-80. To work at 240C you have to work out your own beta and then it isn't accurate at half that temperature. Steinhart–Hart is needed for a accuracy over a wide range.

When I was building the temperature sensor for my aquarium I got tired of playing with temperature tables. I was looking for something with decimal precision and it is a nightmare to achieve that with cheap NTC thermistors and temperature tables. Then I ended up moving to 1Wire temperature sensors, which don't require a table and are very precise.Do you think it is worth the try?

Great post as always! However there is one problem with the table. To generate it, the inverse equation is used i.e. in fact the script calculates the resistance based on the temperature. Unfortunately, the inverse equation can't be solved for all the inputs, because (B/3C)**3 + y**2 can turn negative and sqrt will be undefined in real numbers. May be that doesn't happen for Epcos thermistors, but happened to mine. So I guess one should put some effort into measuring the two resistances as precise as possible to the inverse equation work. Another option is to iterate through some range of resistances (the range could be "guessed") and calculate corresponding temperatures.

Yeah, I am quite sure. For example, if I run the script with all the same input values only changing one temperature value by one degree or even a bit less I get sqrt undefined error. I think it is easy to be one degree off with the measuring equipment most of us have unless you are willing to conduct much more tests averaging the results. In fact, I made lots of failed attempts before I got it to work in the end. Of course, my thermistor is making things worse. It is an old model with quite a range for Beta (4500-7000) so it is harder to be on spot. But my whole point was more about the possible issue with using inverse equation, rather than difficulties of measuring and using the script.