I have small code snippet to find the mean value of an analogRead(). Adapted from a post in this forum.
I find that the code when run on a UNO, takes about 5 millisecond to find the average of 50 samples.
Just curious to know how the timing is controlled for the analogRead() within the while() loop.
Anyway this code while doing the job, blocks the other process when doing the average .... better would be to build an array of 50 values and keep pushing the oldest one by the new one ?
unsigned long anaMillis;
unsigned int anaInterval = 1000 ;
void setup()
{
Serial.begin(9600);
}
//****************************************
void loop()
{
if (millis() - anaMillis > anaInterval)
{
anaMillis = millis();
uint16_t my_analog_value = getAnalog (A0, 50);
Serial.println( my_analog_value);
Serial.print("ms for averaging : ");
Serial.println(millis() - anaMillis);
Serial.println();
}
}
//*******************************************
uint16_t getAnalog (int port, uint16_t avg)
{
uint32_t accum = 0; // averaging accumulator
uint16_t x = avg; // copy averaging count to "X"
while (x--) {
accum += analogRead (port); // add analog readings to accumulator
}
return (accum / avg); // return averaged reading
}
Here's a reference to read on how the analogRead() timing is estblished.
110 microseconds is the time for analogRead() under default conditions with the ide.
As you will read in the reference, the standard analogRead() by itself is blocking, but the reference demonstrates non blocking methods to use.
Mogaraghu:
Anyway this code while doing the job, blocks the other process when doing the average .... better would be to build an array of 50 values and keep pushing the oldest one by the new one ?
Like this?
// Analog Moving Average
const byte AnalogAveragePin = A0;
const byte AnalogAverageCount = 50;
int AnalogSamples[AnalogAverageCount];
byte AnalogIndex;
long AnalogSum;
int AnalogAverage;
void setup() {
Serial.begin(9600);
// Initialize the analog average and circular buffer.
AnalogAverage = analogRead(AnalogAveragePin);
AnalogSum = 0;
for (int i = 0; i < AnalogAverageCount; i++) {
AnalogSamples[i] = AnalogAverage;
AnalogSum += AnalogSamples[i];
}
}
//****************************************
void loop() {
// Get a new analog sample
AnalogSum -= AnalogSamples[AnalogIndex]; // Remove the oldest reading
AnalogSamples[AnalogIndex] = analogRead(AnalogAveragePin); // Replace it with a new reading
AnalogSum += AnalogSamples[AnalogIndex]; // Add the newest reading
AnalogIndex = (AnalogIndex + 1) % AnalogAverageCount; // Next entry in circular buffer
AnalogAverage = AnalogSum / AnalogAverageCount; // New average
}
If you need to do this for more than one analog pin it should probably be made into a library.
That exactly what the doctor ordered.
Thanks ...Johnwasser.
cattledog:
Here's a reference to read on how the analogRead() timing is estblished.
Gammon Forum : Electronics : Microprocessors : ADC conversion on the Arduino (analogRead)
110 microseconds is the time for analogRead() under default conditions with the ide.
As you will read in the reference, the standard analogRead() by itself is blocking, but the reference demonstrates non blocking methods to use.
Good to get linked to that page ... I am not sure how I missed this tutorial. Yes it addresses all my doubts and more !!