Using a Thermistor on the ADS1115

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
chinswain
 
Posts: 22
Joined: Fri Mar 13, 2015 4:30 pm

Using a Thermistor on the ADS1115

Post by chinswain »

Hi all,

I'm trying to use the ADS1115 breakout to improve my thermistor readings, I'm following this tutorial.

I have a 39k resistor as the other resistor and I'm powering the ADS1115 with 3.3v (via a voltage regulator).

The termistor is 50K @ 25C but I'm getting the below values when I would expect nearer 50K ohms:

Average analog reading 10289.80
Thermistor resistance 7282.51

Have I missed some conversion or value that differs between the arduino and ADS1115?
Here's my code:

Code: Select all

#include <Adafruit_ADS1015.h>
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 5
// the value of the 'other' resistor
#define SERIESRESISTOR 39100

Adafruit_ADS1115 ads;

int samples[NUMSAMPLES];

void setup(void) {
  Serial.begin(115200);
   ads.begin();
}

void loop(void) {
  uint8_t i;
  float average;

  // take N samples in a row, with a slight delay
  for (i = 0; i < NUMSAMPLES; i++) {
    samples[i] = ads.readADC_SingleEnded(3);
    delay(10);
  }

  // average all the samples out
  average = 0;
  for (i = 0; i < NUMSAMPLES; i++) {
    average += samples[i];
  }
  average /= NUMSAMPLES;

  Serial.print("Average analog reading ");
  Serial.println(average);
  // convert the value to resistance
  average = 65535 / average - 1;
  average = SERIESRESISTOR / average;

  Serial.print("Thermistor resistance ");
  Serial.println(average);

  delay(1000);
}



User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Using a Thermistor on the ADS1115

Post by adafruit_support_bill »

Code: Select all

average = 65535 / average - 1;
A couple of problems there.

First, the max raw reading for the ADS1115 in single-ended mode is 327678.

Second, it looks like you are using the default analog range which is +/-6.144v. But the max input for the device is 5v. Assuming that you are connecting your thermistor/resistor bridge between 5v and GND, the maximum achievable raw reading would be:

32767 / 6.144v * 5v = 26665.85

User avatar
chinswain
 
Posts: 22
Joined: Fri Mar 13, 2015 4:30 pm

Re: Using a Thermistor on the ADS1115

Post by chinswain »

Hi Bill,

Thanks for the reply.

I'm using 3.3v for everything including the voltage divider.

The below script gives me these values:

adc3 43406
multiplier 0.1875000
Voltage 2.0316
Thermistor resistance 19550.00

From the article, the calculation for resistance is:

R = SERIESRESISTOR / (ADC_RANGE/thermistor.value - 1)

R = 39100 / (32767/43426 - 1)

R = -159297.9266347687

I'm guessing the issue is the scale as you mentioned? Can you advise on how to account for this?

Code: Select all

#include <Adafruit_ADS1015.h>
#define SERIESRESISTOR 39100

Adafruit_ADS1115 ads;
float multiplier;

void setup() {
  Serial.begin(115200);
  ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  ads.begin();
  multiplier = ads.voltsPerBit() * 1000.0F;
}

unsigned long previousMillis = 0;

void loop() {

  unsigned long currentMillis = millis();
  float average;

  if (currentMillis - previousMillis >= 1000) {
    previousMillis = currentMillis;

    int adc3 = ads.readADC_SingleEnded(3);
    float Voltage = (adc3 * multiplier);

    Serial.print("adc3 "); Serial.println(adc3, 7);
    Serial.print("multiplier "); Serial.println(multiplier, 7);
    Serial.print("Voltage "); Serial.println(Voltage / 1000, 4);
   
    average = 32767 / adc3 - 1; average = SERIESRESISTOR / average;
    Serial.print("Thermistor resistance "); Serial.println(average);
    Serial.println();
    
  }
}

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Using a Thermistor on the ADS1115

Post by adafruit_support_bill »

The below script gives me these values:

adc3 43406
Not sure how you are getting a value larger than 32767. The output range of the device is -32768 to +32767 for differential readings and 0 to +32767 for single-ended.

And if you are powering with 3.3v, then the effective ADC raw range using the default gain setting is:

32767 / 6.144v * 3.3v = 17599.46

User avatar
chinswain
 
Posts: 22
Joined: Fri Mar 13, 2015 4:30 pm

Re: Using a Thermistor on the ADS1115

Post by chinswain »

Thanks Bill, the ADC error was due to the print statement formatting.

That makes sense - I've made the range dynamic, does this make sense?

ADCRange = 32767 / (32767 * ads.voltsPerBit()) * 3.3;

Temperature results seems to be as expected with the changes:

Code: Select all

#include <Adafruit_ADS1015.h>
#define SERIESRESISTOR 46000
#define THERMISTORNOMINAL 50000
#define BCOEFFICIENT 3950
#define TEMPERATURENOMINAL 25

Adafruit_ADS1115 ads;

float ADCRange;
unsigned long previousMillis = 0;

void setup() {
  Serial.begin(115200);
  ads.begin();
  //ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV

  ADCRange = 32767 / (32767 * ads.voltsPerBit()) * 3.3;
}

void loop() {

  unsigned long currentMillis = millis();
  float average;

  if (currentMillis - previousMillis >= 1000) {
    previousMillis = currentMillis;

    int adc3 = ads.readADC_SingleEnded(3);

    Serial.print("Voltage\t\t"); Serial.println(adc3 * ads.voltsPerBit());
    Serial.print("Temperature\t"); Serial.println(readThermistor(adc3));
  }
}

float readThermistor(float ADC)
{
  byte i;
  float avg_reading;
  int samples[10];

  // take N samples in a row, with a slight delay
  for (i = 0; i < 10; i++) {
    samples[i] = ADC;
    delay(5);
  }

  // average all the samples out
  avg_reading = 0;
  for (i = 0; i < 10; i++) {
    avg_reading += samples[i];
  }
  avg_reading /= 10;

  avg_reading = ADCRange / avg_reading - 1;   // convert the value to resistance
  avg_reading = SERIESRESISTOR / avg_reading;

  float steinhart;
  steinhart = avg_reading / THERMISTORNOMINAL;     // (R/Ro)
  steinhart = log(steinhart);                  // ln(R/Ro)
  steinhart /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
  steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
  steinhart = 1.0 / steinhart;                 // Invert
  steinhart -= 273.15;                         // convert to C

  return (steinhart);
}
I have one of your LM4040 voltage reference modules I purchased but never used - Could I connect it like this for a more accurate reading? (Changing the code to 2.048V instead of 3.3V)
Image

User avatar
mallamike
 
Posts: 1
Joined: Sat Jun 15, 2019 12:46 am

Re: Using a Thermistor on the ADS1115

Post by mallamike »

I know this is an old post. Did you ever figure out the issue? I am working on a similar project and was looking for some guidance

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”