NTC linearization and implementation on a microcontroller

Thread Starter

andrew74

Joined Jul 25, 2022
229
You seem to have semicolons where there should be commas. That might have been Windows trying to be "helpful".
csv files should have commas separating the variables, otherwise they should be called something else.
When you delete .hword, also delete the comma that comes after it.
Also swap the DIV/0 error for some random large number. It's the value it will read if your thermistor gets shorted to 0V.
Substituting ; with , e swap the DIV/0 error for some random large number.
Why is there // between the commas?

1686493868637.png
 

Ian0

Joined Aug 7, 2020
13,145
// tells the C compiler to ignore the rest of the line. That way you can just include the spreadsheet without any further editing.
Having the rest of the calculations available may be handy for fault finding, but it does no harm.
By the way, you still have Rpullup at 10k not the value you calculated.
Including the entire spreadsheet saves time if, for instance, you change your mind on the pullup value, or some outside party changes the pullup value for you, or changes the make and model of theremistor. Managers do that. . . "I thought they were equivalent, they both say 'thermistor'"
 
Last edited:

Thread Starter

andrew74

Joined Jul 25, 2022
229
A proposito, hai ancora Rpullup a 10k non il valore che hai calcolato.
Yes, I know, I put a random value of 10k just to try. Thank you.
Now that I understand in more technical steps, I will focus for a moment on some more "theoretical" things that are still unclear to me.

1) What do these columns represent? It is not clear to me. I colored them for simplicity so we can understand each other better.
1686497708116.png
 

Ian0

Joined Aug 7, 2020
13,145
red = temperature in tenths of degree C: 2630 = 263.0°C
yellow = data from ADC
blue = resistance value
green = temperature in Kelvin
 

Thread Starter

andrew74

Joined Jul 25, 2022
229
red = temperature in tenths of degree C: 2630 = 263.0°C
yellow = data from ADC
blue = resistance value
green = temperature in Kelvin
It is not clear to me how you constructed the lookup table, however, isn't it enough to make a table with two columns?
I mean these two: (fortunately are on the datasheet)
1686508782123.png
(there are two highlighted values but whatever, pretend they are not)

I detect the voltage on the microcontroller pin, in the code I calculate the resistance of the NTC "Rntc" (doing the inverse voltage divider formula .. since that's the circuit) ... then I compare the calculated Rntc value with those in the column on the datasheet (the table image I just attached).
As soon as I find the closest one, I take the adjacent Temperature value.

Am I wrong?
 

Ian0

Joined Aug 7, 2020
13,145
You're determined to keep your processor busy! Mine has 8 other analogue inputs to cope with four of which need RMS calculations. At a guess your processor can't divide on its own - do you realise how much of its time a division instruction takes? You're not making it do this in floating point, are you?
Not to mention the time it takes to do the search routine. Then all you do is take the nearest value on a 5°C scale. Not exactly precision.
I hope your program doesn't have anything else to do! Otherwise it might be late for its own funeral.
 

Thread Starter

andrew74

Joined Jul 25, 2022
229
You're determined to keep your processor busy! Mine has 8 other analogue inputs to cope with four of which need RMS calculations. At a guess your processor can't divide on its own - do you realise how much of its time a division instruction takes? You're not making it do this in floating point, are you?
Not to mention the time it takes to do the search routine. Then all you do is take the nearest value on a 5°C scale. Not exactly precision.
I hope your program doesn't have anything else to do! Otherwise it might be late for its own funeral.
Thank you for the advice.
Then I ask you to explain how the solution you sent me (on excell and the .csv file) should be implemented in a microcontroller and the benefits you get from it, because I haven't quite get the concept yet.
 

MrChips

Joined Oct 2, 2009
34,832
If you can come up with a few ADC counts vs temperature points I can show you how to move on from there.
The math to implement on an Arduino or any MCU is simple. It does not involve using a look-up table.
 

Ian0

Joined Aug 7, 2020
13,145
Thank you for the advice.
Then I ask you to explain how the solution you sent me (on excell and the .csv file) should be implemented in a microcontroller and the benefits you get from it, because I haven't quite get the concept yet.
Let's suppose the 10-bit value you read from your ADC is called ADCVAL.
The to get the temperature
Code:
Temperature=celsius10k[ADCVAL>>2];
and that's it.
>>2 because you just want 8 bits to access the 256 entries in the table.
 
Last edited:

Ian0

Joined Aug 7, 2020
13,145
Now, it would be a shame to let those last two bits of precision go to waste, and a pain or a waste of memory to use a longer table.
so:
Code:
Temperature_ff+=ADCVAL;                                             
Temperature_iir-=(Temperature_iir>>8);
Temperature_iir+=(celsius10k[temperature_ff>>2]);
Temperature_ff&=3;
Temperature=Temperature_iir>>8;
It feeds forward the unused least significant bits. If the least-significant bits were 0b11, then three times out of four it would read the value from the table one position higher.
Lines 2 and 3 make an IIR filter which averages the data.
Line 5 gives the real temperature to a greater degree of precision.
 

ericgibbs

Joined Jan 29, 2010
21,452
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);}
}
 

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);}
}
Thank you for the code.
However, I wonder where in your code is the table that I attached in my post #25 ... I can't see it.

Rth= (ADCvolt*Rser)/(Vss-ADCvolt);
Why didn't you reverse the voltage divider formula here to find Rth?
Or maybe you did but I don't see it explicitly
 

ericgibbs

Joined Jan 29, 2010
21,452
So, given my NTC with R0=10k at T0=25°C and beta=3977 (written on the datasheet, I don't need the online calculator but thanks anyway) and working in a range of thermperature=[25 ... 43]°C --> Tavg=34°C
hi andrew,
Reading the above, how can your Therm have a resistance of 2200R at 25C.???

Which thermistor are you using.?

E
EG57_ 867.pngEG57_ 868.png
 

Thread Starter

andrew74

Joined Jul 25, 2022
229
hi andrew,
Reading the above, how can your Therm have a resistance of 2200R at 25C.???

Which thermistor are you using.?

E
View attachment 296257View attachment 296258
No no as I had already specified you don't have to consider that yellow highlighter because it was left on the PDF file in which I took the screenshot.
The NTC that I am using has 10k at 25°C. It is this:
 

Attachments

Thread Starter

andrew74

Joined Jul 25, 2022
229
You need a look-up table to get the temperature.
Input the value of B and your pullup resistor, and the resistance at 25°C. The outputs are in tenths of a degree.
Don't forget that most thermistors have quite a wide tolerance, and ±4°C might be good for an uncalibrated one.
If you have a better than 8-bit ADC, and want better accuracy, you can use a feedforward technique, or a bigger lookup table.
As I also asked @ericgibbs .. It is not clear to me in your excell how "Resistance" was found ... why didn't you reverse the voltage divider formula here to find Rth?
1686559006942.png
In your excell if I'm not mistaken you calculated Rntc=Rpullup/(256/ADC-1)
Vout=Vntc=Vs*Rntc/(Rntc+R1) --> Rntc=.. reverse formula and you get a something like Rntc=Vntc/Vs....
 

ericgibbs

Joined Jan 29, 2010
21,452
hi andrew,
I am using this RED block of values.
I am finding Rth in order to determine the Temperature
Calculated value print out
E
EG57_ 869.pngEG57_ 870.pngEG57_ 870.pngEG57_ 871.pngEG57_ 869.png
 

Thread Starter

andrew74

Joined Jul 25, 2022
229
hi andrew,
I am using this RED block of values.
I am finding Rth in order to determine the Temperature
Calculated value print out
E
View attachment 296264View attachment 296265View attachment 296265View attachment 296263View attachment 296264
I understood your code, however it seems to me that your solution is very different and less complex than the one adopted by @Ian0
Am I wrong? They seem to me to be two different solutions.
I'm asking so that I can tell if you're talking about the same thing or not, otherwise I'm confusing
 

ericgibbs

Joined Jan 29, 2010
21,452
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
EG57_ 873.png
 

Ian0

Joined Aug 7, 2020
13,145
As I also asked @ericgibbs .. It is not clear to me in your excell how "Resistance" was found ... why didn't you reverse the voltage divider formula here to find Rth?
View attachment 296262
In your excell if I'm not mistaken you calculated Rntc=Rpullup/(256/ADC-1)
Vout=Vntc=Vs*Rntc/(Rntc+R1) --> Rntc=.. reverse formula and you get a something like Rntc=Vntc/Vs....
81E93A33-6133-424B-B89F-DD9F62A48084.jpeg@ericgibbs ‘s code is massively more complex than mine. He has a microcontroller calculating logarithms!
 
Top