Thermistor slightly wrong values; SOLVED

Hello all!

I have this NTC 10kΩ thermistor:

I know that data sheet is in Chinese, but the important parts are all pretty clear still.

It seems that the thermistor is reading "normal" when the temperature is ~70 and up, but below that, the temperature appears to be lower than supposed to be; and it gets worst the colder it gets.

I think this is a coding problem, but I'm not sure how to fix it!

Here is my code:

#include <LiquidCrystal_I2C.h>

#define thermistor A0

int Vo;
float R1 = 10000;
float logR2, R2, T;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;

LiquidCrystal_I2C lcd(0x27,16,2);
void setup() {
  pinMode(thermistor, INPUT);

  Serial.begin(9600);
  
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Temperature: ");
}

void loop() {
  Vo = analogRead(thermistor);
  R2 = R1 * (1023.0 / (float)Vo - 1.0);
  logR2 = log(R2);
  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
  T = T - 273.15;
  T = (T * 9.0)/ 5.0 + 32.0; 
  
  Serial.println("Temperature(F): " + String(T));
  
  lcd.setCursor(1,1);
  lcd.print(T);
  delay(500);
}

I used the thermistor math code from this website:
https://www.circuitbasics.com/arduino-thermistor-temperature-sensor-tutorial/

Thanks in advance!

Your thermister is a resistor that changes resistance values as it''s temperature changes. Did you confirm the resistance at the recommended temperature? That is all it does. The rest of the process is however you have the thermister circuit wired up. Then is depends on your program.
Did you calibrate your project against a known thermometer?

Are you trying this on a 32-bit processor based board? If so, use 'double' instead of float. If you're on an 8-bit AVR, that could be as good as it gets.

Hmmm, I am using an Arduino Nano.

Yeah, I know that is what a thermistor is. It is also not linear, so I figured some of my math was wrong lol.

I have my circuit setup the same way as in the tutorial I linked. First thermistor pin to +5V, second thermistor pin to A0, with a 10k resistor from A0 to GND.

Funny enough, I don't have a working thermometer to check! I did put it in my fridge though (which has a thermometer builtin), and it consistently showed 7 degrees lower than the actual thermometer (at 37˚).
I also put it outside, and it read about ~7 degrees lower than what the weather app on my phone says.

I think that is wrong-way-around. Thermister to A0 and ground. Resister to A0 and +5v.

Hmmm. Ive seen both versions in multiple tutorials.

This is the one I followed:

That is the way to connect a NTC, if you want to get higher readings with higher temperatures.

These constants are specific to the type and manufacturer of the thermistor.

This on line calculator is useful for calibrating thermistors.

Oldie but goodie:

https://www.phanderson.com/arduino/ntc_therm.html

  • and -

https://www.phanderson.com/picaxe/lin_thermistor.html

My Uno / attiny rewrite:

// NTC_Thermistor (Arduino)
//
// Illustrates measuring temperature using an NTC thermistor in
// a voltage divider configuration.
//
//
// copyright, Peter H. Anderson, Baltimore, MD, May, '07
// Modifications by M. Ray Burnette
// 20120726 UNO:      4280 Bytes / 32256 Max (13.3%) 
// 20120726 ATtiny85: 3332 Bytes /  8192 Max (40.7%)

#include <math.h>

int measTemperature(int pin);    // Analog pin# on UNO: 0-5 / ATtiny85 1 - 3
float calcRthermistor(int ADVal);
float calcTc(float Rtherm);
float square(float x);
float cube(float x);

void setup()
{

  Serial.begin(9600);
  delay(100);
}    

void loop()
{
  int Tc_100, Whole, Fract;
  Tc_100 = measTemperature(2);   // Adjust analog pin # for uC
  Whole = Tc_100 / 100;
  Fract = Tc_100 % 100;
  Serial.print(Whole);
  Serial.print(".");
  if (Fract < 10)
  {
    Serial.print("0");
  }
  Serial.print(Fract);
  Serial.print("C = ");
  Whole = (float(Tc_100/100 * 9) / 5) + 32;
  Serial.print(Whole);
  Serial.print("F ");
  Serial.print("\n");
  delay(5000);
}

int measTemperature(int pin)
{
    int ADVal;
    float RThermistor, Tc;
    
    ADVal = analogRead(pin);
    RThermistor = calcRthermistor(ADVal);
    Tc = calcTc(RThermistor);
    return((int) (Tc * 100.0));
}

float calcRthermistor(int ADVal)
{
    float Rtherm;
    if (ADVal <=0) // avoid trouble conditions
    {
       ADVal = 10;
    }
    Rtherm = 10.0e3 / (1024.0 /((float) ADVal) - 1.0);
    return(Rtherm);
}

float calcTc(float RTherm)
{
  const float A_const = 3.354016e-3;
  const float B_const = 2.569107e-4;
  const float C_const = 2.626311e-6;
  const float D_const = 0.675278e-7;
    
  float x, TKelvin, Tc;
  
  x = log(RTherm / 10.0e3);
  TKelvin = 1.0 / (A_const + B_const * x
              + C_const * square(x) + D_const * cube(x));
  Tc = TKelvin - 273.15;
  return(Tc);
}
                
float square(float x)
{
  return(x * x);
}

float cube(float x)
{
  return(square(x) * x);
}


I figured it was an issue of that sort. Thank you so much @anon94801460 ! That fixed the issue!

Thanks @mrburnette for your help also!