Trying to get (more) accurate readings from thermistor (electronics, math, and code inside)

The ESP8266 ADC is not really a very good one for instrumentation purposes. I believe it's not very linear (especially for voltages near 0V) and the internal reference voltage might be +/-10% or worse tolerance- loosely specified (with no accuracy limits that I can see, kind of a "bonus" functionality that you shouldn't depend on too much for serious applications).

You also have a pretty crummy NTC and are putting a lot of current through it at high temperatures due to the small 1K resistance (meaning self-heating).

Preferred method for thermistor measurement is ratiometric so the reference voltage cancels out, however the Espressif chip does not bring out the reference voltage, also many boards (I infer that yours is one) include a divider on the input that will load your input at least somewhat, perhaps 220K/100K for a nominal ~3.52V for 1024 counts +/- whatever. 10 bits is none too many for such a wide range of resistance.

There are other ways of measuring a thermistor resistance but they generally require more circuitry, for example to convert resistance to frequency, and switch between a reference resistor or resistors and the thermistor.

Given the huge memory in the ESP8266 you can forget all the fancy math and just build a simple lookup table with 1024 entries, but you'd probably have to build a calibration rig to do that (at least a programmable voltage) to cancel out the errors and the chip is not really specified for any particular accuracy or stability, so most of us would use an external ADC or other circuit so that the accuracy and stability is baked in at the beginning.


Unless you have a better than 1C temperature reference, I would not bother trying to get a higher absolute accuracy than what you get using nominal data sheet info. If you need a true high accuracy temperature reference, use a thermal couple or Platinum temperature sensor (RTD).

If you want to try this anyways:

  1. The reference voltage, if your info is correct will cause way more error then the 3% Beta error and 5% resistance error.
  2. First line of calibration would be to verify the resistance at the specified 25C, since the manufacture specs 5%.
  3. Then work on the 3% Beta drift... Assuming you need accuracy over a large range beyond near room temperature.

Also consider purchasing a better spec'ed NTC to save your self some time. You can find 2% Beta, 2% Resistance or better for not much more than yours.


How accurate do you want your readings to be? 0.1 of a degree? 0.01 of a degree?

You have a couple of problems. Firstly your ADC is not very accurate to begin with. You also should be looking at reducing any noise your ADC is currently subject to. MCUs produce noise, if you have done nothing about that then your ADC is probably subject to enough noise to give you inconsistent results.

Then there is the thermistor, they aren't really super accurate devices to begin with. They suffer from self heating for a start and then there is how stable your input is.

You also need accurate calibration data on your thermistor, since there can be 5% difference to the data sheet values in some cases. But getting a reading at 25 degrees isn't easy, how do you keep the sensor at 25 degrees while you measure it? Getting a reading at 100 degrees is much easier, boiling water has to be at 100 degrees (at sea level, the hotter parts become steam). So you can just stick it in some boiling water.

Once you have all your circuit issues squared away you can start thinking about your programming. Thermistors have a logarithmic relation with temperature to resistance. Generally they have better accuracy in some temperature range. The usual approach is to select the specific temperature range you're interested in (smaller range means greater accuracy) and then use your log functions over that range. Either generating a look-up table or if you have a fast enough chip that isn't terribly busy you can do the actual math on the fly.

But then this comes back to the accuracy of your ADC. If it can only produce 1024 discrete values, then you can only measure 1024 discrete temperatures.

Now if you only care that temperature is definitely between say 35.0 and 35.5 and you're only interested in temperatures between -20 and 50. Then this would entirely achievable with what you have. But if you wanted a larger range or a higher precision, it's not really going to be possible with what you're using.

To get more precision you would have use a smaller range and conversely for a larger range you have to reduce precision. Then at some point your ADC wont be able to tell the difference between two values or the noise will make it impossible to get a stable reading.

I highly recommend using this spreadsheet. You can play with the values and see what the error margins will be along with it providing recommended resistor values for measuring in a given temperature range.