This for loop is "blocking code" and takes more than 1/10 second to execute on an Arduino Uno and the like. Since the loop function loops, you don't need a separate loop to count up and average values.
for(int i=0;i<1000;i++)
{
float val = (float) analogRead(A2);
total = total + val;
}
If you just want to get rid of (electronic) noise, then there is already an improvement with 5 samples. The analogRead() can be called without extra delay. About 20 to 100 is more than enough. In most cases that is fast enough to complete them all each time the loop() runs.
However, if you want to get rid of the 50/60 Hz noise from the mains, then 1000 samples might not be enough, you probably need a different filter.
Or if you want to know the average daylight with 10 samples per hour then you can use a millis-timer.
When you do this:
int Amount;
uint32_t total;
...
return total / Amount;
If you have a millis-timer for a led, then please use one millis-timer and adjust the interval.
kolaha shows a millis-timer with different intervals, but you may use more code lines, I don't write code that compact.
But I have one more question about this code.
Is it also possible "volt" be seen outside the if(){} like Serial printing the average outside the if{} . Or it's just like if I want to use "volt" I have to do it inside only?
sum += analogRead(A2);
count++;
if (count >= 100) {
float volt=sum/count;
count = 0;
sum = 0;
}
Serial.print("Average = ");
Serial.println(volt);
If you want to use a variable everywhere, then use a global variable.
Some make all the variables global, but I prefer to make variables local if that is possible.
// global variables
float volt;
void setup()
{
}
void loop()
{
long count; // 'count' is local within the loop() function.
for (int i=0; i<10; i++) // 'i' is local within the for-loop
{
...
}
volt = ... // update the global variable
}
Analog read returns ints. A long can store a lot of accumulated ints.
What I might do in your case is to make the number of samples binary, say 4 or 8 to start so that the reads can be stored in a circular buffer with variables for head and tail, the new read always overwriting the oldest once the buffer is full and head always the newest read. With a straight buffer you would have to copy-move elements up (like a bit shift does with bits) to add a new read. With a circular buffer you increment the index then mask that value with the number of bits in the size of the buffer-1 which ...
if the buffer is 8 values, array[0] to array[7] so when the index reaches 8, ( 8 & 7 ) = 0, the index circles to 0 hence circular buffer.
And that is to keep the reads available for this shortcut.
I would keep a running total of the last X reads in a long variable to shift-right divide for the average. Before a new read, subtract the tail of the full buffer from the total, add the new read and shift to divide for the average int read value. The bigger the circular buffer the better running average you can get without EVER adding them all up in one go.
I would still have to write the code for until the buffer gets full and not report averages until the buffer is full so steps till then do less.
There are statistical means to run averages that involve adding squares and getting square roots. I had calculators that did that while I waited... I wouldn't try that with an AVR but that way you never buffer reads regardless of how many. With a PC or an ARM with FPU and 100+ MHz clock it likely wouldn't matter but a 16 MHz AVR needs shortcuts!
A 256 read buffer only needs more RAM than a 16 read buffer but should run just as fast. A long can hold 65536 int reads added up.
Convert the average read value to float volts or integer mV? Analog read steps, calculate as microvolts then round off to millivolts in integers is wayyy faster on an AVR that using floats.