Arduino not outputting correct temperature from Thermistor

(Circuit Schematic and Code at the end)

Hello!

My group is trying to build a sensor that will (eventually) take differential temperatures between inside and outside containers indoors. I'm doing my best to find and tweak an Arduino code that will read the temperature from our schematic but I keep running into the same error regardless what code I use. Whenever I run the code, the temperature always reads 273.15 C, 459 F, and 0 K. I'm thinking this is due to possibly analog input error but the code is running just fine so maybe not? I tried different beta values and that didn't change the result. I'm truly stumped on what to try next.

Any suggestions?

(also sorry for any formatting errors, this is my first time posting here)

Circuit Schematic (please ignore the note on the side)

//Thermometer with thermistor

/*thermistor parameters:
 * RT0: 10 000 Ω
 * B: 3977 K +- 0.75%
 * T0:  25 C
 * +- 5%
 */

//These values are in the datasheet
#define RT0 10000   // Ω
#define B 3977      // K
//--------------------------------------


#define VCC 5    //Supply voltage
#define R 10000  //R=10KΩ

//Variables
float RT, VR, ln, TX, T0, VRT;

void setup() {
  Serial.begin(9600);
  T0 = 25 + 273.15;                 //Temperature T0 from datasheet, conversion from Celsius to kelvin
}

void loop() {
  VRT = analogRead(A0);              //Acquisition analog value of VRT
  VRT = (5.00 / 1023.00) * VRT;      //Conversion to voltage
  VR = VCC - VRT;
  RT = VRT / (VR / R);               //Resistance of RT

  ln = log(RT / RT0);
  TX = (1 / ((ln / B) + (1 / T0))); //Temperature from thermistor

  TX = TX - 273.15;                 //Conversion to Celsius

  Serial.print("Temperature:");
  Serial.print("\t");
  Serial.print(TX);
  Serial.print("C\t\t");
  Serial.print(TX + 273.15);        //Conversion to Kelvin
  Serial.print("K\t\t");
  Serial.print((TX * 1.8) + 32);    //Conversion to Fahrenheit
  Serial.println("F");
  delay(500);

}

is there something wrong with your math

         0 x  0.000 VRT  5.000 VR        0.000 RT     -inf ln -273.150 TX
        32 x  0.156 VRT  4.844 VR      322.906 RT   -3.433 ln  128.326 TX
        64 x  0.313 VRT  4.687 VR      667.362 RT   -2.707 ln  100.912 TX
        96 x  0.469 VRT  4.531 VR     1035.599 RT   -2.268 ln   86.066 TX
       128 x  0.626 VRT  4.374 VR     1430.167 RT   -1.945 ln   75.889 TX
       160 x  0.782 VRT  4.218 VR     1853.998 RT   -1.685 ln   68.116 TX
       192 x  0.938 VRT  4.062 VR     2310.469 RT   -1.465 ln   61.789 TX
       224 x  1.095 VRT  3.905 VR     2803.504 RT   -1.272 ln   56.421 TX
       256 x  1.251 VRT  3.749 VR     3337.679 RT   -1.097 ln   51.725 TX
       288 x  1.408 VRT  3.592 VR     3918.367 RT   -0.937 ln   47.524 TX
       320 x  1.564 VRT  3.436 VR     4551.920 RT   -0.787 ln   43.695 TX
       352 x  1.720 VRT  3.280 VR     5245.902 RT   -0.645 ln   40.153 TX
       384 x  1.877 VRT  3.123 VR     6009.390 RT   -0.509 ln   36.835 TX
       416 x  2.033 VRT  2.967 VR     6853.377 RT   -0.378 ln   33.692 TX
       448 x  2.190 VRT  2.810 VR     7791.305 RT   -0.250 ln   30.685 TX
       480 x  2.346 VRT  2.654 VR     8839.778 RT   -0.123 ln   27.782 TX
       512 x  2.502 VRT  2.498 VR    10019.569 RT    0.002 ln   24.956 TX
       544 x  2.659 VRT  2.341 VR    11356.994 RT    0.127 ln   22.183 TX
       576 x  2.815 VRT  2.185 VR    12885.905 RT    0.254 ln   19.438 TX
       608 x  2.972 VRT  2.028 VR    14650.603 RT    0.382 ln   16.701 TX
       640 x  3.128 VRT  1.872 VR    16710.184 RT    0.513 ln   13.949 TX
       672 x  3.284 VRT  1.716 VR    19145.299 RT    0.649 ln   11.157 TX
       704 x  3.441 VRT  1.559 VR    22068.967 RT    0.792 ln    8.298 TX
       736 x  3.597 VRT  1.403 VR    25644.598 RT    0.942 ln    5.338 TX
       768 x  3.754 VRT  1.246 VR    30117.648 RT    1.103 ln    2.238 TX
       800 x  3.910 VRT  1.090 VR    35874.445 RT    1.277 ln   -1.058 TX
       832 x  4.066 VRT  0.934 VR    43560.203 RT    1.472 ln   -4.624 TX
       864 x  4.223 VRT  0.777 VR    54339.605 RT    1.693 ln   -8.574 TX
       896 x  4.379 VRT  0.621 VR    70551.195 RT    1.954 ln  -13.091 TX
       928 x  4.536 VRT  0.464 VR    97684.203 RT    2.279 ln  -18.509 TX
       960 x  4.692 VRT  0.308 VR   152380.844 RT    2.724 ln  -25.558 TX
       992 x  4.848 VRT  0.152 VR   320000.312 RT    3.466 ln  -36.489 TX
      1024 x  5.005 VRT -0.005 VR -10240010.000 RT     -nan ln     -nan TX
#include <stdio.h>
#include <math.h>

//Thermometer with thermistor
/*thermistor parameters:
* RT0: 10 000 Ω
* B: 3977 K +- 0.75%
* T0:  25 C
* +- 5%
*/
//These values are in the datasheet
#define RT0 10000   // Ω
#define B 3977      // K
//--------------------------------------
#define VCC 5    //Supply voltage
#define R 10000  //R=10KΩ
//Variables
float RT, VR, ln, TX, T0, VRT;
void setup() {
#if 0
    Serial.begin(9600);
#endif
    T0 = 25 + 273.15;                 //Temperature T0 from datasheet, conversion from Celsius to kelvin
}

#if 0
void loop() {
    VRT = analogRead(A0);              //Acquisition analog value of VRT
    VRT = (5.00 / 1023.00) * VRT;      //Conversion to voltage
    VR = VCC - VRT;
    RT = VRT / (VR / R);               //Resistance of RT
    ln = log(RT / RT0);
    TX = (1 / ((ln / B) + (1 / T0))); //Temperature from thermistor
    TX = TX - 273.15;                 //Conversion to Celsius
    Serial.print("Temperature:");
    Serial.print("\t");
    Serial.print(TX);
    Serial.print("C\t\t");
    Serial.print(TX + 273.15);        //Conversion to Kelvin
    Serial.print("K\t\t");
    Serial.print((TX * 1.8) + 32);    //Conversion to Fahrenheit
    Serial.println("F");
    delay(500);
}
#endif

void
calc  (
    int x )
{
    VRT = (5.00 / 1023.00) * x;      //Conversion to voltage
    VR = VCC - VRT;
    RT = VRT / (VR / R);               //Resistance of RT
    ln = log(RT / RT0);
    TX = (1 / ((ln / B) + (1 / T0))); //Temperature from thermistor
    TX = TX - 273.15;                 //Conversion to Celsius

    printf (" %9d x", x);
    printf (" %6.3f VRT", VRT);
    printf (" %6.3f VR", VR);
    printf (" %12.3f RT", RT);
    printf (" %8.3f ln", ln);
    printf (" %8.3f TX", TX);
    printf ("\n");
}

int main ()
{
    setup ();
    for (unsigned i = 0; i <= 1024; i += 32)
        calc (i);

    return 0;
}

I don't think so?... The numbers you posted look about right, I think.

Is the source volts exactly 5V? Makes a difference in calculations.

Mixed data type math without type casting such as ints and floats do not always result in the expected answer. A 25 is different that a 25.0.

Again mixed data type math does not always result in the expected answer. VRT needs to be cast as float or do all the math as ints.

Put a 103 ceramic cap into the Aref pin and ground.

Use a filter of some sort. I recommend SimpleKalmanFilter - Arduino Reference. An example of use.

void fReadBattery( void * parameter )
{
  float adcValue = 0.0f;
  const float r1 = 50500.0f; // R1 in ohm, 50K
  const float r2 = 10000.0f; // R2 in ohm, 10k potentiometer
  float Vbatt = 0.0f;
  int printCount = 0;
  float vRefScale = (3.3f / 4096.0f) * ((r1 + r2) / r2);
  uint64_t TimePastKalman  = esp_timer_get_time(); // used by the Kalman filter UpdateProcessNoise, time since last kalman calculation
  SimpleKalmanFilter KF_ADC_b( 1.0f, 1.0f, .01f );
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 1000; //delay for mS
  for (;;)
  {
    adc1_get_raw(ADC1_CHANNEL_0); //read and discard
    adcValue = float( adc1_get_raw(ADC1_CHANNEL_0) ); //take a raw ADC reading
    KF_ADC_b.setProcessNoise( (esp_timer_get_time() - TimePastKalman) / 1000000.0f ); //get time, in microsecods, since last readings
    adcValue = KF_ADC_b.updateEstimate( adcValue ); // apply simple Kalman filter
    Vbatt = adcValue * vRefScale;
    xSemaphoreTake( sema_CalculatedVoltage, portMAX_DELAY );
    CalculatedVoltage = Vbatt;
    xSemaphoreGive( sema_CalculatedVoltage );
    
      printCount++;
      if ( printCount == 3 )
      {
      //log_i( "Vbatt %f", Vbatt );
      printCount = 0;
      }
    
    TimePastKalman = esp_timer_get_time(); // time of update complete
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
    //log_i( "fReadBattery %d",  uxTaskGetStackHighWaterMark( NULL ) );
  }
  vTaskDelete( NULL );
}

Also, take 2 ADC readings throwing away the first one for better results.

This occurs when the analog input reads 1023 causing RT to become inf creating problems with subsequent calculations.

I think the best solution to prevent the issue is to use:

VRT = (5.00 / 1024.00) * VRT;    //Conversion to voltage

I changed all the variables to int and I got -274 C, -0.85 K, -461 F. I changed voltage conversion to 5/1024 but that didn't have any affect either. Regardless of these changes, whenever I try to heat up the area around the thermistor it stays constant so I'm wondering if it's an issue with my analog pin? Here's a picture of the physical circuit as well.

Where is the power to the breadboard?

Look at the Blue wire on the breadboard, it does not connect to ground, signal, or power.

powered with my laptop

See the + of the breadboard?

see the wire going from the breadboard + to the 5V of the Uno?

i don't have anything connected from the + to 5V. I have a black wire from my breadboard ground going to the arduino ground. Is that what you're referencing?

The components on the breadboard do they require power for operation?

yes -- when the circuit isn't connected to the arduino/laptop, I used 9V batteries to power it up

From the Uno there are 2 wires. The ground and the signal wire. How does power get from the Uno to the breadboard?

Why not?

So I plugged blue wire into 5V in arduino - changed VCC 5 to VCC 9 in code and left variables back in float. Turns out it was a power source issue.

UPDATE

It is a power source issue but i nearly fried my op amp with what i tried so back to drawing board

Weird.

Here's a test of your code from reply #1...

VRT = (5.00 / 1023.00) * VRT;    //Conversion to voltage

ADC: 995 RT: 355357.46 Temperature: -37.96C 235.19K -36.32F
ADC: 996 RT: 368889.25 Temperature: -38.47C 234.68K -37.25F
ADC: 997 RT: 383461.90 Temperature: -39.01C 234.14K -38.22F
ADC: 998 RT: 399200.37 Temperature: -39.56C 233.59K -39.21F
ADC: 999 RT: 416250.40 Temperature: -40.14C 233.01K -40.24F
ADC: 1000 RT: 434783.03 Temperature: -40.73C 232.42K -41.31F
ADC: 1001 RT: 455000.46 Temperature: -41.34C 231.81K -42.42F
ADC: 1002 RT: 477143.34 Temperature: -41.98C 231.17K -43.57F
ADC: 1003 RT: 501500.50 Temperature: -42.65C 230.50K -44.77F
ADC: 1004 RT: 528421.56 Temperature: -43.35C 229.80K -46.03F
ADC: 1005 RT: 558333.87 Temperature: -44.08C 229.07K -47.34F
ADC: 1006 RT: 591765.31 Temperature: -44.84C 228.31K -48.72F
ADC: 1007 RT: 629375.62 Temperature: -45.65C 227.50K -50.16F
ADC: 1008 RT: 672000.62 Temperature: -46.50C 226.65K -51.69F
ADC: 1009 RT: 720714.93 Temperature: -47.40C 225.75K -53.31F
ADC: 1010 RT: 776923.81 Temperature: -48.36C 224.79K -55.04F
ADC: 1011 RT: 842500.81 Temperature: -49.38C 223.77K -56.88F
ADC: 1012 RT: 920000.93 Temperature: -50.48C 222.67K -58.87F
ADC: 1013 RT: 1013001.00 Temperature: -51.68C 221.47K -61.02F
ADC: 1014 RT: 1126667.75 Temperature: -52.98C 220.17K -63.36F
ADC: 1015 RT: 1268751.25 Temperature: -54.42C 218.73K -65.95F
ADC: 1016 RT: 1451429.87 Temperature: -56.03C 217.12K -68.85F
ADC: 1017 RT: 1695001.62 Temperature: -57.85C 215.30K -72.13F
ADC: 1018 RT: 2036002.00 Temperature: -59.96C 213.19K -75.94F
ADC: 1019 RT: 2547502.50 Temperature: -62.49C 210.66K -80.49F
ADC: 1020 RT: 3400003.25 Temperature: -65.67C 207.48K -86.20F
ADC: 1021 RT: 5105005.00 Temperature: -69.98C 203.17K -93.96F
ADC: 1022 RT: 10220010.00 Temperature: -76.93C 196.22K -106.48F
ADC: 1023 RT: inf Temperature: -273.15C 0.00K -459.67F

VRT = (5.00 / 1024.00) * VRT; //Conversion to voltage

ADC: 995 RT: 343103.46 Temperature: -37.47C 235.68K -35.44F
ADC: 996 RT: 355714.28 Temperature: -37.97C 235.18K -36.35F
ADC: 997 RT: 369259.25 Temperature: -38.49C 234.66K -37.28F
ADC: 998 RT: 383846.15 Temperature: -39.02C 234.13K -38.24F
ADC: 999 RT: 399600.00 Temperature: -39.58C 233.57K -39.24F
ADC: 1000 RT: 416666.65 Temperature: -40.15C 233.00K -40.27F
ADC: 1001 RT: 435217.37 Temperature: -40.74C 232.41K -41.34F
ADC: 1002 RT: 455454.56 Temperature: -41.36C 231.79K -42.44F
ADC: 1003 RT: 477619.06 Temperature: -42.00C 231.15K -43.60F
ADC: 1004 RT: 502000.00 Temperature: -42.67C 230.48K -44.80F
ADC: 1005 RT: 528947.37 Temperature: -43.36C 229.79K -46.05F
ADC: 1006 RT: 558888.93 Temperature: -44.09C 229.06K -47.36F
ADC: 1007 RT: 592352.93 Temperature: -44.85C 228.30K -48.74F
ADC: 1008 RT: 630000.00 Temperature: -45.66C 227.49K -50.19F
ADC: 1009 RT: 672666.68 Temperature: -46.51C 226.64K -51.72F
ADC: 1010 RT: 721428.56 Temperature: -47.41C 225.74K -53.34F
ADC: 1011 RT: 777692.31 Temperature: -48.37C 224.78K -55.06F
ADC: 1012 RT: 843333.31 Temperature: -49.39C 223.76K -56.91F
ADC: 1013 RT: 920909.12 Temperature: -50.49C 222.66K -58.89F
ADC: 1014 RT: 1014000.00 Temperature: -51.69C 221.46K -61.04F
ADC: 1015 RT: 1127777.87 Temperature: -52.99C 220.16K -63.39F
ADC: 1016 RT: 1270000.00 Temperature: -54.43C 218.72K -65.97F
ADC: 1017 RT: 1452857.12 Temperature: -56.04C 217.11K -68.87F
ADC: 1018 RT: 1696666.62 Temperature: -57.86C 215.29K -72.15F
ADC: 1019 RT: 2038000.00 Temperature: -59.98C 213.17K -75.96F
ADC: 1020 RT: 2550000.00 Temperature: -62.51C 210.64K -80.51F
ADC: 1021 RT: 3403333.25 Temperature: -65.68C 207.47K -86.22F
ADC: 1022 RT: 5110000.00 Temperature: -69.99C 203.16K -93.97F
ADC: 1023 RT: 10230000.00 Temperature: -76.94C 196.21K -106.50F

so turns out it seems to be more of a power connection issue than a code issue but I did switch to 5/1024 still :))

So I guess the issue is finding a way to get power from arduino to circuit without frying my components. Any ideas? Should I try plugging batteries into circuit while it's plugged into the arduino?

I have to ask, is there a particular reason for using thermistors in this application?

The DS18B20 digital temperature sensors are pretty accurate and a lot easier to use than thermistors.

class project guidelines