 # first attempt at millis and "smoothing"

this is a section of code I'm testing for checking and smoothing sensor value. Obviously I know I'm doing something out of the norm. But with my somewhat limited ability to speak C++, I dont know what it is.

I'm wanting to check a sensor value every second (the timing potion of the code is working)

I'm also wanting to average a sensor reading and the serial monitor gave some very unexpected values. using { average = (average + sensor) / count } See code. I removed the division portion of the equation and the serial monitor values switched from positive to negative every other reading...

also I had set sensorTemp and sensorAverage as a float. Serial says NAN

``````int SensorPin = A1;
int sensorVal;
int sensorTemp;
int sensorAverage;
int SensorCount;
unsigned long TimeNow;
unsigned long LastTime;
int SensorTimer = 1000;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
SensorCount = 0;
sensorAverage = 0;
TimeNow = 0;
LastTime = 0;

}

void loop() {
// put your main code here, to run repeatedly:
TimeNow = millis();
if (TimeNow >= LastTime + SensorTimer) {
SensorCount++;

sensorTemp = map (sensorVal, 416, 795, 18, 76);

LastTime = TimeNow;
Serial.print(sensorAverage);
Serial.print("  ");
}

sensorAverage = ((sensorAverage + sensorTemp) / SensorCount);
}
``````

There are two major problems with your code. It would make more sense to calculate the average inside the 'if' statement and before you print it.

The other problem is that you aren't calculating the average. If the value of sensorTemp is always 50 degrees, then your code should always calculate and print an average of 50. But this is what happens (assuming that sensorAverage is calculated just before it is printed)

``````sensorTemp SensorCount sensorAverage
50          1           50
50          2           50
50          3           33
50          4           20
etc.
``````

Pete

ahh ok. For some reason i was thinking that average would've gone up 0, 50, 100, 150 etc. how would i accomplish that? i looked at the smoothing example but i didnt fully grasp it. also, i as mention when i removed the divider the values flip flopped from positive to neg.. any ideas to why that happened?

forgive my ignorance. but that's exactly what it is.... I DONT KNOW. just trying to learn.

Your on the right track, can use another variable to sum how much the sensor reports, then when your ready for a average, divide the total sum of that variable by the count for your average variable.

So instead of: sensorAverage = ((sensorAverage + sensorTemp) / SensorCount);

Try: sensorSum = sensorSum + sensorTemp sensorAverage = (sensorSum / SensorCount);

You can can have a function that “seeds” the variables with say 10 times your expected value with corresponding 10 count values so that your code doesn’t start off with low sample size and if you decide to reset say every minute or hour of whatever just call that function again.

Are your sensors giving errant values occasionally or are you just monitoring something that has minor fluctuations you want to smooth?

I've been experiencing some inaccuracies with the temp sensor when I compared it to the temp reading that my fluke meter was giving me.

if you look at the code in the map function, the first two numbers are the values on the ADC (I took a voltage reading on the pin and calculated what the ADC value was) the next two numbers are temperature in degrees F as per my fluke (I taped the two sensors together and tested in the freezer and in ambient temp)

but the arduino has been off by 6 degrees at times.

so in short... im attempting to get the sensor to be accurate through out the map function. i was hoping "smoothing" might help

``````  if (TimeNow >= LastTime + SensorTimer) {
``````

Subtraction. Always subtraction. That is the way of safe unsigned rollover.

Landon are your readings from the Arduino vs the Fluke always off by the same amount at the same temperature? If so, then maybe the sensor you have connected to the Arduino isn't linear over the whole range you are using in your map calculation.

I would suggest taking more readings and making a graph of Fluke readings vs Arduino readings to verify what the relationship between the two are. Or if you have the data sheet for the sensor it should have a graph of voltage vs temperature.

@ coding badly....noted @ metallor..... it seems to be off in the middle of the spectrum. I collected some data on it. I will post it when I get home

What kind of temp sensor?

here is the data I collected. all temps were taken from a fluke 233.

temp VDC @ analogPin calculated ADC value from 5 volt ref

18 2.034 416.5
28 2.56 524.3
38 2.67 547
46 2.832 580
76 3.86 790.5
92.5 4.12 844

sensor im using for arduino

the sensor is R1 in the voltage divider. R2 is 24.6k ohms

Your using a \$300 fluke compared to a \$5 arduino and expecting the same accuracy?

You can get a lot closer by using a thermocouple breakout board.

Are you sure the thermistor is linear? I looked up a data sheet for NTC thermistors here: https://www.murata.com/~/media/webrenewal/support/library/catalog/products/thermistor/ntc/r44e.ashx and it appears the formula given is exponential. Failing that, as long as the reading into the arduino is the same each time for a given temperature, just create a lookup table and extrapolate your temperature from that.

@metallor No I believe there is exponential graphing... will the "map" function not handle that?

parameter

No I believe there is exponential graphing... will the "map" function not handle that?

No, the map function is linear. A lookup table would be good, but if you want to use mathematical conversion take a look at this Adafruit tutorial https://learn.adafruit.com/thermistor/using-a-thermistor

The simplified B parameter equation looks simple.

It also covers the averaging to smooth the data.

There is example code provided.

Thanks. Super helpful. I will test this and get back with y'all as soon as I can... again, thank you for the assistance

sorry for the delay in response… I have done a little digging on Steinhart equations and I found this page.

https://rusefi.com/Steinhart-Hart.html

it gives a formula for C language. Is it usable?
the equations is a little past what I did in high school lol

I’ve attached a chart for the thermistor and a picture of what the calculator showed with the values I gave it. 