Help with reading thermistor

I'm working on project where I need to read temperature from NTC 10k on every 10secs, i use 5 samples with delay of 5ms and then average results, on little longer cable about 8 meters i have issues with readings for example 1st read is 22C and 2nd after 10sec is 23C and then again 22*C, I am using (int) cast to get from FP value not round(), my question is what would be better solution to this:

Solution 1: 10 reading with delay of 2ms
Solution 2: 10 reading with delay of 1ms
Solution 3: Adding capacitor between GND and A0 (Analog input of Arduino)
Solution 4: Anything you suggest, but one thing to keep in mind is to don't have too much time for readings because of reading touch events from Nextion display. Thanks for help.

Try several approaches and decide which works best.

I was looking for advice, maybe someone has experience about it.

Make sure you ‘turn off’ the thermistor between readings. If it’s powered up for 5 or 10 seconds it will self-heat and give false readings. You should only need to turn it on for a few milliseconds before taking a reading.

Try reading every (say) 100mS, to 0.1C resolution, and use a running average. And as Quilkin sugests, turn it off between readings if the self heating may be significant.

The thermistor itself will probably have a time constant of > 1 sec, so there will always be a lag.

If interference is a problem a capacitor may help. Choose one which gives a < 100mS time constant.

Allan

I like idea of multiple readings during 10sec pause and when 10 sec expire just take average of temerature readings. I can take one temperature every 2sec and average it after 10sec.
How can i turn off thermistor when it’s connected to 5V on Arduino?
Is 100nF ceramic going to work between GND and A0?

Use a digital pin to drive it, and measure the digital pin output voltage using another analog input - scale to that.

5v into 10k is 2.5mW - do you know the self-heating coefiicient of the thermistor? Is 2.5mW significant?

By a running average I mean something like this… not an array and a block add/divide.

    ave2 += altitude;
    ave2 *= (1-1/aveLen);
    ave3 = ave2/(aveLen-1);

As you may guess this was for an altimeter, but the idea is applicable.

Avelen is the number of (int) samples over which to average.

Floats for everything else

Allan

I see point of this, but for altitude value you think it's should be analog read value and then pass average float value to function stainhartt to get temerature or altitude value should be already calculated temperatures?

Best to average the analog values, then use the Steinhart equation afterwards. The maths for this takes quite a lot of processor time so no need to do it many times.

allanhurst:
5v into 10k is 2.5mW - do you know the self-heating coefiicient of the thermistor? Is 2.5mW significant?

self-heating will depend on the thermistor package type and it's casing (i.e. is it potted into a waterproof cover?). If it's very small and not encased , self-heating will be important.

allanhurst:
Use a digital pin to drive it, and measure the digital pin output voltage using another analog input - scale to that.

Yes, if you use a digital pin to drive the thermistor you can use that to turn it on and off as you please.

Actually I was wrong about the self heating… If you use a 10k thermistor and a 10k resistor in series ( a typical setup) the thermistor will only dissipate about 0.6mW worst case…

And the scaling to the digital pin output voltage may be unnecessary - it will have an output impedance < 200 ohms. Give it a try.

Your 10k reference resistor will be at best 1%, which is +/- 100 ohms. And thermistors ( good ones eg Omega ) are +/-2%. And the given temperature coefficient is approximate. Correction tables are available.

It will all need calibrating against a known accurate thermometer.

I’d use a bigger capacitor - 10uF will give about a 50mS timeconstant.

Allan

I am little bad at English because it's not my primary language. So, I understand everything you talked so to be sure I will put 10uF capacitor and do my sketch like this:

float ave2;
int i=0;
void loop(){
if(millis() - displayAndCalculationTime > 10000){
display(temperatureFromSteintHart(getAverage()));
otherCalculations();
}
if(millis() - readTime > 1000){
ave2 += analogRead(a0);
i++;
delay(3);
}

LISTENTouch();

}

double getAverage(){
  ave2 *= (1-1/i);
i=0;
   return ave2/(i-1);
}

Not full code but you can see what i am thinking about.

You completely misunderstand my running average idea!

avelen is a CONSTANT!

your i is being continually incremented.

Do it like I said.

Allan

I am very thankful for your help Allan, but i can't get it, it's my bad or you are not much precise at explanations. I can't figure how to use code you gave me...

    ave2 += altitude;
    ave2 *= (1-1/aveLen);
    ave3 = ave2/(aveLen-1);

I run this in loop() every whatever mS.

OK.. Suppose avelen is 10.

Ave2 is increased by this loop's altitude value every time. It contains a cumulative sum of altitude.
If I did nothing else it would climb to infinity.

But.

I multiply it by (1 - 1/10) ie 9/10ths.

If I put in a continuous stream of eg 1000's, this would end up with a value of 9000

I then divide that by 10- 1 ie 9 to get ave3.

So I get my 1000 back.

This doesn't affect the ave2 value

so each new Ave3 value is altered by only the contribution of 1/9 of new altitude input per loop

Suppose 1 in nine of my 1000's was a 900.

Then the running total would be ( 8x1000 +900) = 8900,and ave3 would be 8900/9 = 989 - ie a single value in nine samples 10% away from the average would only give a running average change of about 1%.

Try it

Allan

Hi,
Welcome to the Forum

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Have you tried twisting the pair of wires you have to the thermistor or using a shielded twin-core cable?

Thanks Tom... :slight_smile: