NTC linearization and implementation on a microcontroller

Thread Starter

andrew74

Joined Jul 25, 2022
229
hi andrew,
I consider using the manufacturer's Rth versus Temperature is the best approach to use.
Both methods rely on the accuracy of the ADC converter.

Why don't you as an exercise run both methods and compare your results, they would be helpful to other readers.

E
View attachment 296272
If instead of this formula I used the more simplified one R(T)=R0+e^beta(1/T-1/T0) ... in your experience, do you think there are so many differences?
 

ericgibbs

Joined Jan 29, 2010
21,452
hi andrew.
You could use that formula, providing you knew the temperature.?

But that is the parameter you want to determine.

E
 

Thread Starter

andrew74

Joined Jul 25, 2022
229
hi andrew.
You could use that formula, providing you knew the temperature.?

But that is the parameter you want to determine.

E
If I get Rntc by inverting the voltage divider formula as you did ... then I put it into Rntc(T)=R0+e^beta(1/T-1/T0) and invert to find T (which is the only unknown)
 

Thread Starter

andrew74

Joined Jul 25, 2022
229
hi andrew.
You could use that formula, providing you knew the temperature.?

But that is the parameter you want to determine.

E
Correct me if I'm wrong, but in any application where you use NTC (regardless of the formula and code you write) you have to test and verify that at 0 C° the NTC measures at 0 C° and at 100 C° it measures 100 C°.
@Ian0
 

Thread Starter

andrew74

Joined Jul 25, 2022
229
hi andrew.
You could use that formula, providing you knew the temperature.?

But that is the parameter you want to determine.

E
Code:
#define ntc1_pin A0   


#define R0_NTC1 10000
#define temperatura_nominale 25   
#define beta1 3977   

#define Rref 10000     

float samples1 = 0.0;


float temp1 = 0.0; 
float Tread = 0.0; 

float Voltage1 = 0;
float Rntc1 = 0;

int i = 0;         


void setup() {

  Serial.begin(19200);

}


void loop() {


  int samples_num = 20;

    for (i = 0; i < samples_num ; i++) {
      samples1 = samples1 + (float)analogRead(ntc1_pin);
      delay(5);
  }
 
  Voltage1 = samples1 / samples_num;
  Voltage1 = Voltage1 / 1024.0*5;
  samples1=0;

  Rntc1 = Voltage1*Rref/(5*(1-Voltage1/5));

  Rntc2 = tensione2*Rref/(5*(1-tensione2/5));


  temp1 = (1./296.15+log(Rntc1/R0_NTC1)/beta1);
  temp1 = 1/temp1;
  temp1 = temp1-273.15;

}
 

Thread Starter

andrew74

Joined Jul 25, 2022
229
hi andrew,
I often use the same method as described in your post #25, it works OK.
You need to ensure that the therm values etc are the thermistor type you use.

E

C-like:
/* thermistor temperature profile 12/05/2023 ESP57

Vadc = 5.0* (Rt / (Rt + 10000))
ADCout = (Vadc /5.0) * 1024
*/
#define ADCin1    0// pin

float R0 = 10000;  // Therm resistance at 25C
float Bval= 3370;  // Therm Beta value
float Rth = 0;
float ADCcnt= 0;
float Rser = 10000; // Series resistor with Therm
float ADCvolt = 0;
float Vss =5.0; //  ref Volts

float TambAvg =0;

float Tref = 298.15; // 25C
float Tamb = 298.15; // 25C
int i =0;
int avg=0;



void setup()
{
  Serial.begin(115200);
  Serial.println("NTC1");
}

void loop() {

for (i = 0; i<= 99; i++){

// get ADC count for the ADC inp voltage
  ADCcnt= analogRead(ADCin1);

// Calc ADC input voltage
  ADCvolt = Vss*(ADCcnt/1024);

// Calc Therm resistance that will give ADCvolt
  Rth= (ADCvolt*Rser)/(Vss-ADCvolt);

//Transposed Equation for Tamb, Therm Temperature
  Tamb =(Tref*Bval)/((Tref * log(Rth/R0)+Bval));
/*
  Serial.print("ADCcnt=");
  Serial.print(ADCcnt,0);
  Serial.print("  ADCvolt=");
  Serial.print(ADCvolt,4);
  Serial.print("  Rth=");
  Serial.print(Rth);
  Serial.print("  Cdeg=");
  Serial.println((Tamb-273.15),3);
*/
  TambAvg=TambAvg + Tamb;
  avg=avg+1;
}
// take 100 samples and average
  if (avg >= 99){
  Serial.print ("   TambAvg=");
  Serial.println((TambAvg/avg)-273.15);
  TambAvg=0;
  avg=0;
  delay(100);}
}
Comparing my code with yours, I notice that the only difference is that you calculated the Rth, the temperature etc. inside the for loop that reads the value from the NTC ... while I just put analogRead(ntc1_pin) in the for loop and calculated the rest after it
I don't think that changes much, do you?
 

Thread Starter

andrew74

Joined Jul 25, 2022
229
Never heard of such a rule.
Strange, then how can you be sure with a temperature sensor that you have calibrated it right?
You have to test it at some reference points (like 0 and 100°C) where you can verify that the NTC marks that temperature.

Providing you with a practical example, I put the NTC in a closet with a range of [20 ... 50]°C ... but I didn't know if the NTC I used/configured gave me the correct temperature ... so I think that the solutions are two:
1) I had to compare the results with a professional thermometer I already had at home
2) I put the NTC at 0 °C and 100 °C (ice and boiling water) and verify that it measures those temeperatures .. if it measures 0 C° and 100 °C ... then I have configured it right

(I tell you these two temperatures 0 °C and 100 °C because they are two certain temperatures that we also have at home and it is easy to reproduce them)
 

Ian0

Joined Aug 7, 2020
13,145
Strange, then how can you be sure with a temperature sensor that you have calibrated it right?
You have to test it at some reference points (like 0 and 100°C) where you can verify that the NTC marks that temperature.

Providing you with a practical example, I put the NTC in a closet with a range of [20 ... 50]°C ... but I didn't know if the NTC I used/configured gave me the correct temperature ... so I think that the solutions are two:
1) I had to compare the results with a professional thermometer I already had at home
2) I put the NTC at 0 °C and 100 °C (ice and boiling water) and verify that it measures those temeperatures .. if it measures 0 C° and 100 °C ... then I have configured it right

(I tell you these two temperatures 0 °C and 100 °C because they are two certain temperatures that we also have at home and it is easy to reproduce them)
I buy curve-matched thermistors.
 

ericgibbs

Joined Jan 29, 2010
21,452
hi andrew.
On a Hardware point, add a good quality capacitor on the ADC input pin, to 0v, say 1n through 10n depending upon the sampling rate. The cap will reduce the effect of any electrical noise that appears on the pin.
Also, good decoupling on the +5V supply line.
Let's see your results when ready.:)
E
 

Ian0

Joined Aug 7, 2020
13,145
Connect your thermistor with a screened lead, or a twisted pair, especially if the lead is long. 10nF is only a 100us time constant. The temperature is not going to change much in 100us. 10uF would probably be a more appropriate filter capacitor. Also, an IIR filter in the software will filter it even further.
 

ericgibbs

Joined Jan 29, 2010
21,452
Hi andrew.
Don't fit a 10uF electrolytic, they leak like a bath tub, use a quality low leakage, 10nF, at the most a 100nf.

I am talking from experience, not a Wiki page. ;)
E
 

Ian0

Joined Aug 7, 2020
13,145
For example? Do you have an example of curve-matched NTC?
That I'm not clear what what "curve" are you referring to? Temperature-Resistance?
Exactly.
https://uk.rs-online.com/web/p/ther...3685F6B6579776F72645F6170703D3031353132323126


Hi andrew.
Don't fit a 10uF electrolytic, they leak like a bath tub, use a quality low leakage, 10nF, at the most a 100nf.

I am talking from experience, not a Wiki page. ;)
E
You can get those new-fangled multilayer ceramic capacitors in values as high as 10uF these days!
. . . and my bathtub doesn’t leak.

By the way, Typical leakage for a 10uF 16V aluminium electrolytic is 3uA. That would represent only a 1% error compared to the current through a resistance of 10k. Accuracy would deteriorate as the thermistor gets colder and its resistance gets higher, but that would be out of the range of interest.
 
https://learn.adafruit.com/thermistor/using-a-thermistor is quite a helpful explanation. The lookup table should be more accurate than the formula but I favour a combination of both where you calibrate a number of known values (like ice in water, room temperature and boiling water) and write a short lookup table using those points and linear extrapolation between them to correct the formula.

1686576268065.png

“You only need to know To (which is room temperature, 25 °C = 298.15 K) B, the coefficient of the thermistor and Ro the resistance at room temp. Plug in R (resistance measured) and get out T (temperature in Kelvin) which is easy to convert to °C”.

Adjust the value of B to get close before correcting with a lookup table. As already mentioned, your biggest error may come from the non-linearity of your ADC.
 

ericgibbs

Joined Jan 29, 2010
21,452
Hi andrew,
Attached a NTC Sketch for your Thermistor, you may find helpful.
Also, some results.
E
EG57_ 886.png
C++:
/* thermistor temperature profile 13/05/2023 ESP57

Vadc = 5.0* (Rt / (Rt + 22000))
ADCout = (Vadc /5.0) * 1024
*/

float R0 = 10000;  // Therm resistance at 25C
float Bval= 3977;  // Therm Beta value
float Rth = 0;
float ADCcnt=1;
float Rser = 10000; // Series resistor with Therm
float ADCvolt = 0;
float Vss =5.0; //  ref Volts

float TambAvg =0;

float Tref = 273.15; // 25C
float Tamb = 25.0; // 25C
int i =0;
int avg=0;



void setup()
{
  Serial.begin(115200);
  Serial.println("NTC1");
}

void loop() {
  Tamb=0;
for (i = 0; i<= 20; i++){
Serial.print(Tamb);
Serial.print("  ");
 Rth=10000*exp(-14.6337+4791.842/(Tamb+Tref)-115334/(pow((Tamb+Tref),2))-(3.730530E6)/(pow(Tamb+Tref,3)));
Serial.println( Rth);
Tamb=Tamb+5;
delay(1000);
}
Tamb=0;
}
 

Attachments

kalemaxon89

Joined Oct 12, 2022
389
Hi andrew,
Attached a NTC Sketch for your Thermistor, you may find helpful.
Also, some results.
E
View attachment 296373
C++:
/* thermistor temperature profile 13/05/2023 ESP57

Vadc = 5.0* (Rt / (Rt + 22000))
ADCout = (Vadc /5.0) * 1024
*/

float R0 = 10000;  // Therm resistance at 25C
float Bval= 3977;  // Therm Beta value
float Rth = 0;
float ADCcnt=1;
float Rser = 10000; // Series resistor with Therm
float ADCvolt = 0;
float Vss =5.0; //  ref Volts

float TambAvg =0;

float Tref = 273.15; // 25C
float Tamb = 25.0; // 25C
int i =0;
int avg=0;



void setup()
{
  Serial.begin(115200);
  Serial.println("NTC1");
}

void loop() {
  Tamb=0;
for (i = 0; i<= 20; i++){
Serial.print(Tamb);
Serial.print("  ");
Rth=10000*exp(-14.6337+4791.842/(Tamb+Tref)-115334/(pow((Tamb+Tref),2))-(3.730530E6)/(pow(Tamb+Tref,3)));
Serial.println( Rth);
Tamb=Tamb+5;
delay(1000);
}
Tamb=0;
}
Thank you, very kind
 
Top