ADS1115 with ntc thermistor

Hi, i'm trying to get themperature using ADS1115, a 10k NTC thermistor and Esp32..

I was trying to "translate" this sketch that i used to use with arduino without ADS1115

void setup() {
  Serial.begin(9600);                 // Initialize the serial port, set the baud rate into 9600
  Serial.println("UNO is ready!");    // Print the string "UNO is ready!"
}

void loop() {
  // Convert analog value of A0 port into digital value
  int adcVal = analogRead(A0);
  // Calculate voltage
  float v = adcVal * 5.0 / 1024;
  // Calculate resistance value of thermistor
  float Rt = 10 * v / (5 - v);
  // Calculate temperature (Kelvin)
  float tempK = 1 / (log(Rt / 10) / 3950 + 1 / (273.15 + 25));
  // Calculate temperature (Celsius)
  float tempC = tempK - 273.15;

  // Send the result to computer through serial port
  Serial.print("Current temperature is: ");
  Serial.print(tempK);
  Serial.print(" K, ");
  Serial.print(tempC);
  Serial.println(" C");
  delay(5000);
}

I wish to get the same voltage read value so that i can calculate thermistor resistance and temperature..
I change only the part reguarding resolution (ASD115 read16bit instead of 10bit of arduino)and imput voltage wich is 3.3v

#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads(0x48);

void setup(void) {
Serial.begin(9600);
ads.begin();

}

void loop(void) {

 int16_t adcVal;

 adcVal = ads.readADC_SingleEnded(0); // Read ADC value from ADS1115

 float v = adcVal * (3.3 / 65535); // 3.3 is voltage supply instead of 5v..and 65535 is ASD resolution
 
 Serial.println(v);
 delay(1000);

}

But the value i get for "v" is really different..where did i wrong??

Thank you very much

Look at the singeended example sketch that came with the library. The gain of that chip has nothing to do with the external voltage supplied to operate it.

Try this and see if it gives better results.
Note that the float data-type is at the limit of its precision, so integer math would be a better idea.

#include <Wire.h>

#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads(0x48);


void setup(void) 
{
  Serial.begin(9600);

  ads.begin();
}


void loop(void) 
{

 int16_t adcVal;

 adcVal = ads.readADC_SingleEnded(0); // Read ADC value from ADS1115

 float v = adcVal * 0.0001875;     // Using default TwoThirds gain = 0.1875mV per 1-bit
 
 Serial.println(v);

 delay(1000);

}

If you have a look at the sample code @blh64 mentioned, you could possibly increase the gain and get even better resolution.

blh64:
Look at the singeended example sketch that came with the library. The gain of that chip has nothing to do with the external voltage supplied to operate it.

I think i need to calculcate voltage in function of voltage supplied becouse i need to know the value of the resistance of thermistor to get themperature like in the sketch that i used for arduino.. or am i wrong?
How fo i calculate temperature? (i've just tried to translate the sketch that i've used with arduino)

Thank you :slight_smile:

Here is explained better the reason why i put also voltage supply in the formula

NTC type thermistor of 10kΩ (thermistor resistance) is used. NTC of 10kΩ means that this thermistor has a resistance of 10kΩ at 25°C. Voltage across the 10kΩ resistor is given to the ADC.


We can calculate the voltage across series 10kΩ resistor as,

Vout = VCC * ADC_Value / ADC_Resolution

Where, Vout is the voltage measured by the ADC.

The temperature can be found out from thermistor resistance using the Steinhart-Hart equation.

Temperature(in kelvin) = 1 / (A + B[ln(Rth)] + C[ln(Rth)]^3)

where, A = 0.001129148,

B = 0.000234125,

C = 8.76741*10^-8 and

Rth is the thermistor resistance.

The thermistor resistance (Rth) can be found out using simple voltage divider network formula.

Rth + 10k = VCC * 10k / Vout

Where, Rth is the thermal resistance

In this formula they use other parameters for calculate themperature (i use Beta parameter instead of A B C) but the concept is the same..calculate thermistor resistence to get temperature

Thank you :slight_smile:

ilteo85:
I think i need to calculcate voltage in function of voltage supplied...

That is correct, you will need to know the supply voltage to calculate the resistance. However, the voltage read by the ADC is not supply dependant.

Vout = VCC * ADC_Value / ADC_Resolution

Where, Vout is the voltage measured by the ADC.

Should be replaced with

Vout = ADC_Value * 0.0001875;

To do this properly, you need to read the supply voltage to the resistor/thermistor divider using the ADS1115, and form the ratio yourself. Just one one of the other ADS1115 input channels for that.

Voltage readings by the ADS1115 are "absolute" whereas with the standard Arduino, they are ratiometric.

Make sure that all voltages presented to the ADS1115 inputs are between the ADS1115 supply voltage, and ground. Otherwise you will damage the ADS1115.

Martin-X:
That is correct, you will need to know the supply voltage to calculate the resistance. However, the voltage read by the ADC is not supply dependant.

Should be replaced with

Thank you very much! so once i've calculated Vout

Vout = ADC_Value  * 0.0001875;

i can use it in the formula

Rth + 10k = VCC * 10k / Vout

to calculate resistence and then use this

Temperature(in kelvin) = 1 / (A + B[ln(Rth)] + C[ln(Rth)]^3)

to get temperature?

jremington:
Make sure that all voltages presented to the ADS1115 inputs are between the ADS1115 supply voltage, and ground. Otherwise you will damage the ADS1115.

you mean the value that i'm measuring in anlog pin of ADS1115?

I've found also this sketch that seems to work..but is for another thermistor..and i dont't know how to calculate A, B, C, D factor for my thermistor wich is MF55-103 10 kOhm

#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads;


void setup()
{
  Serial.begin(19200);
  ads.begin();
  ads.setGain(GAIN_ONE);
}


void loop()
{
  // get ADC values --------------------------------------------//
  int16_t adc0 = ads.readADC_SingleEnded(0);
  int16_t adc0_average = samples(0);
  
  // get resistance --------------------------------------------//
  float R0 = resistance(adc0);
  float R0_avg = resistance(adc0_average);
  
  // get temperature --------------------------------------------//
  float temperature0 = steinhart(R0);
  float temperature0_avg = steinhart(R0_avg);
  
  // print everything -------------------------------------------//
  Serial.print("Temperature 0: ");
  Serial.println(temperature0, 3);
  
  Serial.print("Temperature 0 (average): ");
  Serial.println(temperature0_avg, 3);
  
  Serial.println("---------------------------------------------");
  Serial.println();
  delay(2000);
}

// Get resistance -------------------------------------------//
float resistance(int16_t adc)
{
  float ADCvalue = adc*(8.192/3.3);  // Vcc = 8.192 on GAIN_ONE setting, Arduino Vcc = 3.3V in this case
  float R = 10000/(65535/ADCvalue-1);  // 65535 refers to 16-bit number
  return R;
}

// Get temperature from Steinhart equation -------------------------------------------//
float steinhart(float R)
{
  float Rref = 10000.0;
  float A = 0.003354016;
  float B = 0.0002569850;
  float C = 0.000002620131;
  float D = 0.00000006383091;
  float E = log(R/Rref);
  
  float T = 1/(A + (B*E) + (C*(E*E)) + (D*(E*E*E)));
  return T-273.15;
}

// Perform multiple iterations to get higher accuracy ADC values (reduce noise) --------------------------------//
int16_t samples(int pin)
{
  int n=5;  // number of iterations to perform
  int32_t sum=0;  //store sum as a 32-bit number
  for(int i=0;i<n;i++)
  {
    int16_t value = ads.readADC_SingleEnded(pin);
    sum = sum + value;
    delay(10);
  }
  int32_t average = sum/n;   //store average as a 32-bit number
  return average;
}

Thank you very much!

Steinhart-Hart thermistor calculator

You really need to know the parameters of your particular thermistor otherwise the efforts of using a higher resolution ADC are wasted. The minimum requirement would be the B-value, which is normally appended to the part number: For example MF55-103-3950 has a B-value of 3950.

You could of course do your own experiments and feed the results into the calculator that @jremington referred to.

Do some internet research and see if you can find a datasheet for your exact thermistor type.

Transposing the formula you quoted should give you something like this:

float Rt = (Vcc / Vout * 10000.0) - 10000.0;   // Thermistor resistance Rt (Ohms)

When you've got the parameters you can then start working on temperature readings.

Using a (ratiometric) thermistor with an absolute A/D (ADS1115) is IMHO not worth the effort.

The ESP32 has AFAIK a ratiometric A/D, and should be a far better/easier option on it's own.
Leo..

Martin-X:
For example MF55-103-3950 has a B-value of 3950.

You could of course do your own experiments and feed the results into the calculator that @jremington referred to.

Do some internet research and see if you can find a datasheet for your exact thermistor type.

I attach here the datasheet i've found.. I've tried to use @jremington's calculator.. but even if i insert data that are written on datasheet he gives me different Beta value than the one written on datasheet..
I've reed somewhere that those calculator are specific for each productor..
Furthermore this calculator doesn't calculate "D" value... I've found just another excel sheet that calculate that but also those give me wrong parameters..

Wawa:
The ESP32 has AFAIK a ratiometric A/D, and should be a far better/easier option on it's own.
Leo..

Esp32 ADCs is rally bad is non linear and need to be adjusted..

i've tried to fix it in some of the ways that are written..but i'm not so sure about results so i prefered
to use an external ADC wich is really more precise..

Have you been able to fix it in some ways? if yes please share your experience :slight_smile:

Thank you very much!!!!

ntc table.pdf (212 KB)

Don't know about the linearity of the A/D in the ESP32.
I do know that if you are going to use an absolute A/D for a thermistor,
then you should also measure it's supply/pull up voltage, and take that into your calculation.
Much easier to start off with a ratiometric A/D for a ratiometric source (thermistor, pot, etc.).
Leave the ADS1115 for true voltage sources.

Thermistor/resistor sensors with A/Ds have a rather narrow range of resolution,
and are hard to get accurate across a wider temp span (Steinhart/Hart).
Why a thermistor. What are you trying to measure.
Leo..

Wawa:
Thermistor/resistor sensors with A/Ds have a rather narrow range of resolution,
and are hard to get accurate across a wider temp span (Steinhart/Hart).
Why a thermistor. What are you trying to measure.
Leo..

For me it' s ok haf degrees of tolerance..and it seems to be quite accurate for this use.
I need to measure the temperature of bees brood..so i need a really small probe..because i will "hide" it inside
the wax wich is 2 mm more or less.. it will work in a range of 25 to 45 degrees C

Thanks a lot :slight_smile:

i insert data that are written on datasheet he gives me different Beta value than the one written on datasheet.

To use the Steinhart-Hart calculator properly, feed it the resistance data that you measure for your thermistor, and the calculator will give you the beta value that is correct for your thermistor.

For the use you describe, you almost certainly don't need the "D" term.

25C to 45C, with a resolution of 0.5C.
The A/D of the ESP32 should be more than good enough for that.
Seems you are trying the crack an egg with a hammer (with the ADS).

Measure the thermistor resistance at a temp of ~35C (middle of the range),
and use a pull up resistor of that value.
Leo..

Here's a snippet which should get you somewhere near:

float Bval = 3930.0;   // best fit B-Value
float Rstd = 8048.0;   // best fit standard resistance
float Tstd = 30.0;     // best fit standard temp

float calcTemp(float Res)
{
  float stA = (1.0 / (Tstd + 273.15)) - ((1.0 / Bval) * log(Rstd));  // Steinhart A
  float stB = 1.0 / Bval;      // Steinhart B

  float Tc = 1.0 / (stA + (stB * log(Res))) - 273.15;

  return Tc;
}

The datasheet you linked contains quite a few errors, the above parameters give the best fit based on crappy values, but should be OK within 20 to 40c.

A thermistor is not a good choice for your application. A thermal measurement IC is not only more linear and accurate, but also easier to interface.

Wawa:
25C to 45C, with a resolution of 0.5C.
The A/D of the ESP32 should be more than good enough for that.
Seems you are trying the crack an egg with a hammer (with the ADS).

Measure the thermistor resistance at a temp of ~35C (middle of the range),
and use a pull up resistor of that value.
Leo..

Ahahahah no i won't crack any egg :slight_smile: thank you actually one of my intention is to build this accurate thermoscope with ADS to compare how accurate it is if i use the same thermistor in the same situation with internal esp32 adc. I'm happy to ear you are saying it will be good becouse if i should not use ADS will save money and space :slight_smile:

Martin-X:
Here's a snippet which should get you somewhere near:

float Bval = 3930.0;   // best fit B-Value

float Rstd = 8048.0;  // best fit standard resistance
float Tstd = 30.0;    // best fit standard temp

}

Thank you so much..i' m really sorry yesterday i discover i gave you wrong information becouse thermistor's seller told me that Beta value is 3435..i've found this other datasheet..
I will try your sketch this evening with the right data value.. But i didn't understand why you use 30 C instead of 25 C.. In this datasheet there are no value for 30 C you think i should use 25 and use the defined resistence of 10 kohm?

Thank you very much!!!!!!

aarg:
A thermistor is not a good choice for your application. A thermal measurement IC is not only more linear and accurate, but also easier to interface.

As i said in past post i need to use a really small probe 1,2 mm .. if you know any small probe that works better than thermistor any suggestion are welcome!

Thank you!

mf52.pdf (121 KB)