Go Down

Topic: Average value of a series of analog numbers over 5 sec. (Read 247 times) previous topic - next topic

staneveraert



Hello Arduino community



I have a question about a problem I am working with ...


I need a program to calculate the average value over 5 sec. of my analog (sensor) values (that the Arduino reads). This process has to start when I push a pushbutton.



Anyone who can give me a code? I will be very thankful with that!



Kind regards


Stan




falkenauge

#1
Jan 09, 2021, 01:40 pm Last Edit: Jan 09, 2021, 01:43 pm by falkenauge Reason: improving formatting
Stan,

Please take a look at the AnalogRead() function and how to BlinkWithoutDelay, it will help you.

You need to think of how fast will you read, this will influence your cumulative variable. i.e., if you read every time, without a time delay you likely will have an overflow.

Would be good to tell us if you know how to program and it isn't a good practice to ask for a code, you should try first and ask what your problems are.

The code below is really basic and will overflow your variable, so you need to set a time between the readings and also the 5s desired times.
Code: [Select]
int analogPin = A3; // your sensor is connected here
uint32_t val = 0;  // variable to store the value read

void setup() {
  Serial.begin(9600);           //  setup serial so you can print
}

void loop() {
  val += analogRead(analogPin);  // read your sensor and add it to val
  Serial.println(val);          // debug value
}


Code: [Select]
int analogPin = A3; // your sensor is connected here
uint32_t val = 0;  // variable to store the value read

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last val = 0

// constants won't change:
const long interval = 5000;           // interval at which to reset is ms
cont int betweenReadings = 500;       // interval at which it will read your variable

void setup() {
  Serial.begin(9600);           //  setup serial so you can print
}

void loop() {
  // check to see if it's time set val=0; that is, if the difference
  // between the current time and last time you did it is bigger than
  // the interval at which you want it you happen.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you reset val
    previousMillis = currentMillis;

    val = 0;
  }

  val += analogRead(analogPin);  // read your sensor and add it to val
  Serial.println(val);           // debug value
  delay(betweenReadings);        // block the execution for this time
}


Be aware that using delay is easier but it blocks your program, it will do nothing during this time. So it is recommended to use  millis() for it too, like we did in the code above to wait the 5 seconds before reseting val.
"You can never know everything, and part of what you know is always wrong. Perhaps even the most important part. A portion of wisdom lies in knowing that. A portion of courage lies in going on anyways."
--The Eye of the World

MarkT

Hello Arduino community



I have a question about a problem I am working with ...


I need a program to calculate the average value over 5 sec. of my analog (sensor) values (that the Arduino reads). This process has to start when I push a pushbutton.



Anyone who can give me a code? I will be very thankful with that!



Kind regards


Stan

If you just want help coding an average, I presume you mean the "mean value".

mean = sum of values / number of values.

So if you record N samples over the 5 seconds:
Code: [Select]

float average (int N, int * samples)
{
  long sum = 0 ;
  for (int i = 0 ; i < N ; i++)
    sum += samples[i] ;
  return float(sum) / N;
}
[ I DO NOT respond to personal messages, I WILL delete them unread, use the forum please ]

staneveraert

Hello both reply'ers

Thanks for the assistance! But I made my program on a other way ... You can see the code below:
Code: [Select]
/*

In dit programma wordt er een kalibratie van een sensor uitgevoerd. Dit door voor een onbepaalde tijd de drukknop in te duwen.
In die tijd zal het programma zoeken naar de maximale en minimale analoge waarde die de sensor binnenleest. De referentiewaarde
die de "kalibratie" aangeeft is dan gelijk aan het gemiddelde van die twee extreme waarden.

 */
 
#include <LiquidCrystal.h>                                              
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;            
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);                              

const int sensorPin = A0;
const int indicatorLedPin = 13;
const int buttonPin = 0;

int sensorMin = 1023;
int sensorMax = 0;
int sensorValue = 0;
int Kalibratiewaarde;

void setup() {
  Serial.begin(9600);
  pinMode(indicatorLedPin, OUTPUT);
  pinMode(buttonPin, INPUT);
}

void loop() {
  while (digitalRead(buttonPin) == HIGH) {
    calibrate();
  }
  digitalWrite(indicatorLedPin, LOW);
  Kalibratiewaarde = (sensorMin + sensorMax) / 2;
  Serial.println(Kalibratiewaarde);
  lcd.setCursor(0, 0);                                                  
  lcd.print(Kalibratiewaarde);
  delay(500);                                  
}

void calibrate() {
  sensorMin = 1023;
  sensorMax = 0;
  while (digitalRead(buttonPin) == HIGH) {
    digitalWrite(indicatorLedPin, HIGH);
    sensorValue = analogRead(sensorPin);
    if (sensorValue > sensorMax) {
      sensorMax = sensorValue;
    }
    if (sensorValue < sensorMin) {
      sensorMin = sensorValue;
    }
  }
}

Thanks again for the reply!
Kind regards
Stan

MarkT

So you use the average of the minimum and maximum?  That's about the worst approach as it relies entirely
on outlier data and is more likely to be influenced by odd spikes and dropouts than either the mean, mode or median.
[ I DO NOT respond to personal messages, I WILL delete them unread, use the forum please ]

staneveraert

Hello Mark

I have to say that you are completely right ... The problem is that I'm just a beginner in programming with Arduino, and that I barely understand your example in the comment above. Is there a way that you could explain me your code?

Thanks in advance
Stan

Idahowalker

#6
Jan 13, 2021, 09:32 pm Last Edit: Jan 13, 2021, 09:33 pm by Idahowalker
Do you want to average or smooth the data?

To smooth data I use SimpleKalmanFilter
1/18/2018, got my first Arduino Uno.


johnerrington

Take 5 readings with a 1 sec delay between each
add em up as you go
divide by 5.
I'm trying to help. If I find your question interesting I'll give you karma. If you find my input useful please give me karma (I need it)

MarkT

Hello Mark

I have to say that you are completely right ... The problem is that I'm just a beginner in programming with Arduino, and that I barely understand your example in the comment above. Is there a way that you could explain me your code?

Thanks in advance
Stan
Its a function called average that takes an array of samples and an integer count of the samples,
then computes the average (to be precise, the mean).

You need to call it with an appropriate array of samples collected over the last 5 seconds...
[ I DO NOT respond to personal messages, I WILL delete them unread, use the forum please ]

Go Up