Multiple 10k NTC Thermistors + Arduinio Mega + LCD+ADC noise smoothing algorithm

Hello Scientists;

I want to measure Temperature (Surface and Air) inside a Cabinet , thus I’m using nine (9) 10k NTC Thermistors , five for the surface Temp and four for the Air Temp.
I’m using Megunolinklibrary (exactly the Exponential Filter) to smooth noisy measurements.

Sketch:

``````#include "MegunoLink.h"
#include "Filter.h"
#include <LiquidCrystal.h>

//LCD Vars
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

float T_Sur_avr, T_Air_avr;

TimePlot Plot;

//Exponential Filter Algorithm
// the <float> makes a filter for float numbers
// 20 is the weight (20 => 20%)
// 0 is the initial value of the filter
ExponentialFilter<float> FilteredTemperatureSurface(20, 0);
ExponentialFilter<float> FilteredTemperatureAir(20, 0);

void setup()
{
lcd.begin(16, 2);
Serial.begin(9600);
lcd.clear();
lcd.print("*** WELCOME! ***");
lcd.setCursor(4, 1);
lcd.print("Initializing");
delay(5000); //some time for Stabilization
}

void loop()
{
//Average Surfae Temperature
T_Sur_avr = (MeasureTemperatureSurface(A0) + MeasureTemperatureSurface(A1) + MeasureTemperatureSurface(A2) + MeasureTemperatureSurface(A3) + MeasureTemperatureSurface(A4)) / 5;
Plot.SendData("Surface Temperature", T_Sur_avr); //Plot Surface Temperature via Serial on Laptop

//Average Air Temperature
T_Air_avr = (MeasureTemperatureAir(A5) + MeasureTemperatureAir(A6) + MeasureTemperatureAir(A7) + MeasureTemperatureAir(A8)) / 4;
Plot.SendData("Air Temperature", T_Air_avr); //Plot Air Temperature

//LCD Display
lcd.clear();

lcd.print("Temp Surf:");
lcd.setCursor(11, 0);
lcd.print(T_Sur_avr);
lcd.print((char)223);
lcd.print("C");

lcd.setCursor(0, 1);

lcd.print("Temp Air:");
lcd.setCursor(11, 1);
lcd.print(T_Air_avr);
lcd.print((char)223);
lcd.print("C");

delay(500);
}

//TempSurf Function
float MeasureTemperatureSurface(int A)
{

/* Constants to help conver the raw analogue measurement into
temperature in degrees Celcius
*/

const float ThermistorResistance = 10000; // Thermistor resistance at some nominal temperature
const float R  = 10000;
const float NominalTemperature = 25; // The nominal temperature where resistance is known.
const float BCoefficient = 3950; // The beta coefficient of the thermistor (from data-sheet)
const float Vsupply = 5.00;  // The supply voltage for the voltage divider.
const float Vref = 5.00; // Analogue reference voltage.

// Calculate the output voltage of the voltage divider; it depends on temperature.
float Vout = (float)nRawThermistor * Vref / 1023.0;

// Calculate the thermistor resistance.
float VR = Vsupply - Vout;
float Rtherm = Vout / (VR / R);;

// Convert thermistor resistance into temperature using the Steinhart equation
float Temperature;
Temperature = Rtherm / ThermistorResistance;
Temperature = log(Temperature);
Temperature /= BCoefficient;
Temperature += 1.0 / (NominalTemperature + 273.15);
Temperature = 1.0 / Temperature;

Temperature -= 273.15; // convert to C

////Exponential Filter  Algorithm to Smooth Surface Temperature measurement;
FilteredTemperatureSurface.Filter(Temperature);
float SmoothTemperatureSurface = FilteredTemperatureSurface.Current();

return SmoothTemperatureSurface;
}

//TempAir Function
float MeasureTemperatureAir(int Analog)
{

/* Constants to help conver the raw analogue measurement into
temperature in degrees Celcius
*/

const float ThermistorResistance = 10000; // Thermistor resistance at some nominal temperature
const float R  = 10000;
const float NominalTemperature = 25; // The nominal temperature where resistance is known.
const float BCoefficient = 3950; // The beta coefficient of the thermistor (from data-sheet)
const float Vsupply = 5.00;  // The supply voltage for the voltage divider.
const float Vref = 4.94; // Analogue reference voltage.

// Calculate the output voltage of the voltage divider; it depends on temperature.
float Vout = (float)nRawThermistor * Vref / 1023.0;

// Calculate the thermistor resistance.
float VR = Vsupply - Vout;
float Rtherm = Vout / (VR / R);;

// Convert thermistor resistance into temperature using the Steinhart equation
float Temperature;
Temperature = Rtherm / ThermistorResistance;
Temperature = log(Temperature);
Temperature /= BCoefficient;
Temperature += 1.0 / (NominalTemperature + 273.15);
Temperature = 1.0 / Temperature;

Temperature -= 273.15; // convert to C

////Exponential Filter Algorithm to Smooth Air Temperature measurement;
FilteredTemperatureAir.Filter(Temperature);
float SmoothTemperatureAir = FilteredTemperatureAir.Current();

return SmoothTemperatureAir;
}
``````

Electronics:

1—>I’m using External Adapter (9v 2A) to power on Arduino Mega via Vin.
2—>from the adapter I use LM2596 DC-DC Step Down Adjustable PSU Module fixed on 5v to power the voltage divider and the LCD (qapass lcd 16*2) with a 10k potentiometer for backlight adjust.
3—>10k NTC Thermistor sensor range (-40 ℃ to +300 ℃)
4-Multimeter (Farnell tenma 72-7725)

So everything works perfectly , I just have some issues that I would learn about :

1st—>When I power the arduino with Vin without USB cable , the readings on the LCD are changing fast , if the Temp is e.g 22° C on the lcd it’s showing 15° C 20 , 25 , 12 , 19°C …
Question1: I wonder why does this happen?

2nd—>When I plug the USB cable in the laptop to plot the Temperature ,first the sketch reset,second the readings are stable , so if the Temp is 22° C , on LCD it’s 22° C ±0.1 !!
Q2: why the the arduino reset when I plug the usb cable ?
And why the readings are stable?

3rd—>When I take off the USB Cable , the LCD display wierd caracters "sometimes"until I reset the Arduino or power it off than power on again to get rid of these wierd caracters !!

4th—>if the Vin is off and the USB cable is plugged , I noticed that the the backlight of the LCD is on without any caracters despite of powering the LCD from the external +5v from the LM2596 , the only cables between LCD and Arduino are ofc RS , E , (D4-D7) and GND.
Q3: how or why this happens ?

5th—>I measured the 5v and 3.3v on arduino with the multimeter and I found respectivly 4.94/4.95 and 3.24.
Q5: is there anyway to increase it to real 5v or 3.3 ?!

Thx for any help :))))

This thread is a cross-post with this thread. You should be aware that cross-posting is against forum rules and can get you in trouble with the forum moderators, so please don’t do this again.

PaulRB:
This thread is a cross-post with this thread. You should be aware that cross-posting is against forum rules and can get you in trouble with the forum moderators, so please don't do this again.

Thx PaulRB,I didn't know about cross-posting, I'm new here , the other thread was a question about weird symbols on LCD which is part of this project , so I thought It would be better if I merged both .

Any tips on some of these issues ?!!

Powering through Vin: sounds like a problem with your power supply. What are you using?

Powering through USB: sounds like the supply is more stable. I think it is normal for the Arduino to reset when you connect USB. In fact, even if the usb is already connected, opening the Serial Monitor will cause the Arduino to reset.

Wierd characters: could be another problem caused by your external power supply.

LCD backlight: you will need to provide a full schematic, and explain more clearly the configuration when this occurs. But it sounds like "parasitic powering" where power is flowing to the LCD backlight from an unexpected route. This is not a good thing and could be damaging the Arduino or other components.

Power supply voltages are often not exactly as advertised. Possibly your multimeter is not perfectly accurate either. Especially USB power via an Arduino, which contains circuits which are designed to protect the PC against wiring errors and have the side effect of dropping some voltage. Don't worry that it is not exactly 5V, this probably won't affect the accuracy of sensors because they give a signal which is proportional to the supply voltage.

5V for logic devices normally means anything in the range 4.75 to 5.25V - noone cares at all so long as it works.
For analog sensing its a different matter, but the normal way to finesse the problem is to use ratiometric
sensing so the supply voltage doesn't affect the reading at all.

Its absolutely crucial to power all your thermistor dividers from the Arduino 5V rail or none of your
measurements are ratiometric or meaningful.

Your LM2596 supply will be quite noisy as its switch-mode, further compounding your problem

MarkT:
Its absolutely crucial to power all your thermistor dividers from the Arduino 5V rail or none of your
measurements are ratiometric or meaningful.

Alternative: create a clean, stable reference voltage (e.g. using a TL431 reference diode), put that through a buffer (unity gain OpAmp), and use the output to power both the NTCs and connect it to the AREF pin as external reference.

Simpler, still pretty clean: diode (to prevent the low part of the ripple from coming through) and smoothing cap, use that for AREF and the thermistors.

Clean power (for analog only), and still perfectly ratiometric.

wvmarle:
Alternative: create a clean, stable reference voltage (e.g. using a TL431 reference diode), put that through a buffer (unity gain OpAmp), and use the output to power both the NTCs and connect it to the AREF pin as external reference.

Why all of that if you have a stable/clean/unused 3.3volt pin on a Mega.
Power all thermistors, and connect Aref to that 3.3volt pin.
Don't forget to set Aref to EXTERNAL in setup().
No need to change thermistor code.
Leo..

Why not do the normal and simplest thing and just power the thermistors from the 5V rail, normally
works fine.