Stabilizing the temperature reading

I’m trying to start my weather station learning project. At the moment, I have the thin little Thermistor - 100K. I don’t know the exact model as it came in a ‘Starter Pack’.

I am read the device, and showing it on a OLED screen.

The issue I face is the temperature bounces around a lot. Each read is different… Sometimes by a degree… some times less.

It’s using a 100K ohm resistor.

So what I thought was, add a ‘Wait’ time… and in that time, keep sampling values… then average them out, and return the average for that wait period.

THis has helped, but I’d hope the temp would stay within a xx.x range… but it still changes between 24.5 and 25.5 within checks.

Is there a way to try flatten this out and make it more accurate? Maybe make the pause time longer? At the moment, I sample for 3 seconds… but maybe I need more?

Here’s my code. I created class to handle the device:

/*

  • A class to handle the reading of temperature data.
    */

class Thermostat {

int ThermistorPin = 0; // The pin this device will listen on.
int Vo; // The voltage we read from the pin.
int Period; // The time to wait to calculate the average.
float R1 = 100000; // The resistance of the resistor used.
float logR2, R2, T; // Fields for temperature calculation
float c1 = 1.009249522e-03,
c2 = 2.378405444e-04,
c3 = 2.019202697e-07; // No idea… Just values.

public:
Thermostat(int pin, float resistor, int period) {
ThermistorPin = pin;
R1 = resistor;
Period = period;
pinMode(ThermistorPin, OUTPUT);
}

int readCount = 0;
float totalReadValue = 0;

unsigned long startMillis = 0;

/*

  • Read the value from the device.
    */
    float Read() {

startMillis = millis();
readCount = 0;
totalReadValue = 0;
while(millis() - startMillis < Period) {
Serial.println(“Checking voltage…”);
Vo = analogRead(ThermistorPin);
R2 = R1 * (1023.0 / (float)Vo - 1.0);
logR2 = log(R2);
T = (1.0 / (c1 + c2logR2 + c3logR2logR2logR2));
T = T - 273.15;

readCount ++;
totalReadValue = totalReadValue + T;
}
Serial.println(“Returning…”);
Serial.println(totalReadValue);
Serial.println(readCount);

return totalReadValue / readCount;
}
};

Then I create the object in my main code:

// Create the devices.
Thermostat thermostat(THERMOSTAT_PIN, 100000, 4000);

And then I poll it every 20ms. (So the time between screen updates is 20ms + pause time.

Cralis:
I'm trying to start my weather station......... I poll it every 20ms.

You can't possibly be serious about this. A quiet sanity check will probably solve all your problems. You might also find that you are reinventing the wheel and, if you really feel the need for all that software, you might be better off using a DS18b20 - with pre-existing code.

Fantastic and helpful response. Completely invalid though. But the spelling nailed it.

If I wanted to copy someone - I’d do that. If I just want a weather station - I’d buy one.

Instead - I’m trying to learn. Hence coming to a programming forum and asking about CODE. Not the device. It’s clearly not accurate. I’m trying to get a flattened result. If the DS18b20 would give me more accurate results - I’ll invest the crazy $1 in that. :slight_smile:

Although. This site seems to indicate the one you mention isn’t as accurate.
https://lowpowerlab.com/forum/general-topics/cheap-thermistor-vs-1-wire-ds18b20/

But if you’re alluding to my 20ms pause or the fact that I am querying it too fast. Thanks for the heads up. I wasn’t aware that you should go too fast.

So to answer your question - yup. Serious.

But your stringing together of words was impressive nevertheless. Thanks.

Maybe make the pause time longer?

That is certainly something you could have tried.

Another is to just average the analog readings, instead of the calculated temperature.

Another is to print the analog readings, to see how much variation there really is.

The LAST thing you should do is blast people that offer advice, even if it is not what you wanted to hear.

I like using a low-pass filter

double smoothedTemperature = 20; // a sensible inital value

// this gets called every 20ms.
void pollTemp() {
  double tempReading = readTemperature();

  smoothedTemperature = .95*smoothedTemperature + .05*tempReading;
}

@OP

You have said that you don’t know the exact type/registration number of your thermistor. So, you have no idea about the gain and offset of your thermistor. Before you put it into operation, you need to calibrate it. Look into this post on the procedures of calibrating an ‘NTC type thermistor’.

@Nick_Pyner (in his Post#1) has suggested you to use DS18B20 temperature sensor – do you know why has he suggested you so? The DS18B20 sensor does not require any field calibration like the thermistor. Moreover, DSB1820 can offer a 4-digit precision with accuracy in the step of 0.5/0.25/0.125/0.06250C depending on what resolution (9/10/11/12 bit) you set for the sensor.

Cralis:
But if you’re alluding to my 20ms pause or the fact that I am querying it too fast.

You can read thermistors very fast, which is more than can be said for the DS18B20, but I do wonder what sort of weather you live in where the temperature merits reading 50 times a second.

Nick_Pyner:
You can read thermistors very fast, which is more than can be said for the DS18B20, but I do wonder what sort of weather you live in where the temperature merits reading 50 times a second.

New England weather might could benefit.

a7

alto777:
New England weather might could benefit.

a7

Plan to turn the furnace or AC on or off that often?

The joke was funny, though, if you got it.