Hi, I need help with storing lets say 20 values from A0 store them in an array and average them.
Post what you have tried (please use code tags) and explain the problems.
EDIT: As the others have pointed out, this is an incorrect approach and will give wrong results.
If you only store the values to compute the average, you should compute the average iteratively. The following snippet calculates the new average based on the old average, the number of readings and the new value. Obviously this is a trade-off, because now you need to do a division on every update.
int newAverage = oldAverage + 1/n*(newValue - oldAverage);
Delta_G:
Except that keeps a running average and OP asked for average of last 20 values.
Which is the same after 20 iterations. Except that the running average is more costly to compute. However, in my last project I needed to take the average of about 30000 numbers. Since the OP's question was more general "[...] lets say 20 [...]" I thought why not suggest the running average.
Hi, I need help with storing lets say 20 values from A0 store them in an array and average them.
You don't need to store them, you just need to keep a running total then divide the total by the number of readings that went into the total.
Delta_G:
But not after 21 or more.Point being that OP needs to be more specific about what he wants before you can offer a real solution.
Exactly. But then he would also compute the average over 21 stored numbers, right? But I totaly agree with you.
PerryBebbington:
You don't need to store them, you just need to keep a running total then divide the total by the number of readings that went into the total.
How do you handle large numbers?
Class assignment, most likely.
How do you handle large numbers?
You mean too large for the largest number that can be stored in any format in an Arduino? You don't. However, if you can be sure you won't exceed that then this works.
For example:
uint16_t cumulative_measurement;
The maximum possible output of a 10 bit A2D is 0x3ff, which obviously uses 10 bits. Add this to cumulative_measurement. The 6 highest bits in cumulative_measurement are not used for 1 measurement. 6 bits leaves space for 64 times 10 bits (I hope I'm explaining this well enough!). Add 64 or fewer 10 bit measurements to cumulative_measurement and the total cannot be more than 0xffff. Divide the result by however many results were added to cumulative_measurement, save the result somewhere else, set cumulative_measurement = 0 and start again.
If cumulative_measurement is 32 bits that would allow 4194304 measurements to be added without risking overflow. I've not idea what the OP is doing, but I can't imagine that being a problem.
LightuC:
If you only store the values to compute the average, you should compute the average iteratively. The following snippet calculates the new average based on the old average, the number of readings and the new value. Obviously this is a trade-off, because now you need to do a division on every update.int newAverage = oldAverage + 1/n*(newValue - oldAverage);
In addition to being more compute intensive, that will NOT give the same result as summing all 20 numbers and dividing by 20, due to truncation. It will generally give a lower result. Much better to sum the numbers into a long, then do a single divide by 20 after summing all 20 numbers.
Regards,
Ray L.
LightuC:
int newAverage = oldAverage + 1/n*(newValue - oldAverage);
Given the fact that an integer one divided by any integer greater than one results in zero, clarifying "n" would be a good choice. Or, you could reorder the terms.
In addition, assuming oldAverage is also int, your snippet truncates towards zero. That's rarely wanted with any form of averaging.
Now I'm feeling pretty dumb, you are all very right. I was doing it with floats and just copied it to the forum. Of course I forgot about integer truncation, what a stupid mistake.
I do not have a code to show, all I want the code to do is store 20 values from A0 in an array and average those 20 values display the result and start again.
Munna9310:
I do not have a code to show, all I want the code to do is store 20 values from A0 in an array and average those 20 values display the result and start again.
Go ahead and implement it then? Read the values with analogRead(), store them in an array and keep a count on how many readings you took. If it is more than 20 compute the average.
LightuC:
Go ahead and implement it then? Read the values with analogRead(), store them in an array and keep a count on how many readings you took. If it is more than 20 compute the average.
If I would know how to implement it I would not post here.
Then why not read up on it? I gave you a lot of keywords to search for. Also you can take a look at one of the examples in the arduino IDE. You can find it under File->Examples->03.Analog->Smoothing
Munna9310:
If I would know how to implement it I would not post here.
We will acquire 20 readings from an LM35 type temperature sensor via A0-pin of Arduino UNO at 1/2-sec interval. After that, we will compute an average which will be displayed on Serial Monitor. While conducting this tutorial, it is hoped that you (the OP) will note down important and useful information.
Let us carry out these steps:
1. Connect an LM35 (hope you have this one) sensor with the A0-pin (ADC Channel - 0) of the UNO as per following diagram.
2. Upload the following Sketch in the UNO.
float sampleArray[20] = {}; //array to store 20 samples of temperature signals
int sampleCounter = 0; //array pointer
float avrgTempC = 0.0; //average temp in degC
void setup()
{
Serial.begin(9600); //Bd rate
analogReference(DEFAULT); //ADC Vref is 5V
}
void loop()
{
//----check if 1/2-sec has gone-------
unsigned long presentMillis = millis();
while (millis() - presentMillis < 500) //500 ms
{
; //wait here
}
presentMillis = millis(); //1/2-sec has gone
//----take a temperature signal from LM35 and save in array
float tempC = (float)100 * (5 / 1023.0) * analogRead(A0); //this is Formula; want derivation? place request
sampleArray[sampleCounter] = tempC; //every float sample occupied 4 memory locations
sampleCounter++;
if (sampleCounter == 20) //20 samples are collected
{
//--compute average tempC //temperature in degC
for (int i = 0; i < 20; i++)
{
avrgTempC = avrgTempC + sampleArray[i]; //all 20 samples are added
}
avrgTempC = avrgTempC / 20;
//------show average Temp in degC------------
Serial.print("The Average Temparatute : ");
Serial.print(avrgTempC, 2); //show temp wth 2-digit after decimal point
Serial.println(" degC");
Serial.println("================================================");
//----reset array and sampleCounter---
// sampleArray[20] = {};
sampleCounter = 0;
//-----------------------------------
}
}
3. Bring in the Serial Monitor (SM) at 9600 Bd
4. Check that the SM shows the room temperature.
5. Rub the LM35 sensor with fingers; observe that (you have to wait for 10-sec) SM value changes.
If I would know how to implement it I would not post here.
Do you know how to read an analogue pin and print the value on the Serial monitor ?
Besides the fact that sampleArray doesn't have an element 20, and the fact that there's no need to zero the array anyway.
Delta_G:
You can't clear an array like that. You should just overwrite it in this example, but if you really want to blank it then you need to use memset. You can only use a brace enclosed list at creation.
1. I have done few things in the example of Post#18 without verifying much particularly on the creation/initialization/reset of float type array. When the example codes get compiled-uploaded-executed and have started giving the expected result, I have posted it. I am now pleased to receive feedback which will help me to know things that I didn't know before.
2. I wanted to initialize the float type array this way: float sampleArray[20] = {}; having had idea from this char type array: char myArray[10] = ""; where the members are assigned 0s. Now, I see that the style is correct only at the creation time; it is not valid in the loop() space. The float array has to be over-written by resetting the sampleCounter to zero which I have done. (I will delete this line : sampleArray[20] = {}; from the loop() space of my sketch of Post#18.)
3. Is this declaration: float sampleArray[20] = {}; not containing 20 members where each member is composed of 4 memory locations?locations. I don't understand why you/@AWOL are saying that there is no spot 20/member 20 in that array.
Here, I'll make it clear for you.float sampleArray[20] = {};
sampleArray has twenty elements, with indices zero to nineteen, inclusive.
//----reset array and sampleCounter---
sampleArray[20] = {};
There is no element of sampleArray with the index twenty.