Media su 10 letture sensore

Scusate se la domanda è abbastanza banale per chi conosce il codice di programmazione di Arduino:

avrei bisogno di fare la media su 10 letture di un sensore, mi potreste indicare un esempio per il codice da utilizzare? devo utilizzare la funzione "array"?

void loop(){
int b[9];
for(int i=0;i<=9;i++){
  int a = analogRead(0);
  b[i]= a;}
for( int j=0;j<=9;j++){
int media = 0;
media= b[j] + media;
}
media = media/10;
Serial.println(media);
}

spero la sintassi sia corretta....
ci sono modi per farlo molto più efficente ma l'ho fatto rapidamente.... :slight_smile:

se non servono i valori singoli puoi subito fare la somma e poi dividere per i numeri di letture.

for(int i=0;i<=9;i++){
int a += analogRead(A0);
}
media = a/10;

Ciao Uwe

Non avevo mai usato l'operatore += stupendo ora ne so una nuova :slight_smile:

ratto93:
Non avevo mai usato l'operatore += stupendo ora ne so una nuova :slight_smile:

Il mio C è migliore del tuo XD

leo72:

ratto93:
Non avevo mai usato l'operatore += stupendo ora ne so una nuova :slight_smile:

Il mio C è migliore del tuo XD

Per stavolta si :stuck_out_tongue:
cè chi la pensa così, soprattutto quelli a cui mostro i miei esperimenti, a loro non gli interassa niente di cosa ci sta dietro ed un giorno mi sento dire :
L'importante non è come,L'importante è che funzioni :slight_smile:
li mi son cadute le oo cè dopo tanto lavoro ti senti dire una roba del genere ti smonta.... e io non gli faccio più vedere niente :slight_smile:

ratto93:
L'importante non è come,L'importante è che funzioni :slight_smile:

Questa è la filosofia dei produttori cinesi: non è importante la qualità del prodotto finito, l'importante è che il prodotto faccia quello che è stato fissato. Quindi se viene usata un tipo di plastica che dura 2 giorni di numero non gliene frega nulla. O le macchine di burro che nei crash test si accartocciano come lattine XD

grazie per i consigli, siete troppo efficienti!

se non abuso troppo, vorrei lanciare la funzione media ogni 5 secondi per esempio (cioè fare la media al tempo 5 secondi, al tempo 10 sec, poi 15 secondi, ecc)

va bene un codice di questo tipo:

int intervallo = 5;  // è l'intervallo in secondi a cui decido di fare la media
unsigned long currentMillis = millis();

void loop()
{
if (currentMillis > ritardo)
         media();   // lancio la funzione media
         ritardo = currentMillis + intervallo;  //aggiorno il valore di ritardo
}

Se vuoi usare Millis si sennò puoi usare un semplicissimo delay

Massi, il tuo codice fa una media ogni 5 ms, non ogni 5 secondi :smiley:
Tu calcoli su millis che conta appunto i millisecondi.

Modifica così:

int intervallo = 5000;  // è l'intervallo in millisecondi a cui decido di fare la media

oopps scusate mi ero dimenticato che Arduino ragiona in millisecondi, è corretto 5000 come segnalato da Leo

in realtà dovresti guardare la frequenza di lavoro del sensore. è "inutile" leggere il sensore più velocemente della sua frequenza di aggiornamento, un po' come leggere le lancetta dei secondi 10 volte al secondo....

lesto:
in realtà dovresti guardare la frequenza di lavoro del sensore.

immagino che si trovi sui varai datasheet ma come si chiama questo valore?

sensor freuqency o roba del genere, il valore generalmente è dato in Hz

skaxxo:
immagino che si trovi sui varai datasheet ma come si chiama questo valore?

Solitamente è indicato come banda passante, bandwidth in inglese.

se non servono i valori singoli puoi subito fare la somma e poi dividere per i numeri di letture.

Quote
for(int i=0;i<=9;i++){
int a += analogRead(A0);
}
media = a/10;

Ciao Uwe

Se fai così non hai una media degli ultimi 10 valori ma fai la media fra l'ultimo e la media di tutti i precedenti.

Ti dico come l'avrei fatto io:

class calcola_media {
  public:
    calcola_media();
    unsigned int aggiorna(unsigned int);  //Quando chiami la funzione metti dentro il nuovo valore e ti ritorna la media
  
  private:
    unsigned int valori[10];    //ci metto dentro i valori
    byte indice;            //Memorizzo l'indice di dove ho messo l'ultimo dato
};

calcola_media::calcola_media() {
  for (int i = 0; i < 9; i++) {
    valori[i] = 0;
  }
  indice = 0;
};

unsigned int calcola_media::aggiorna(unsigned int nuovo_valore) {
  if (++indice >= 10) indice = 0; //Incremento indice e se, una volta incrementato, vale 10 lo riporto a 0
  valori[indice] = nuovo_valore;
  unsigned int risultato_media = 0;
  for (int i = 0; i < 9; i++) {
    risultato_media += valori[i];
  }
  risultato_media /= 10;
  return risultato_media;
};

calcola_media media;

unsigned int media_attuale = 0;
unsigned long tempo_ultima_media = 0;

void loop() {
  if ((tempo_ultima_media - millis()) > 5000) {
    tempo_ultima_media = millis();
    media_attuale = media.aggiorna(analogRead(A0));
  }
}

buona soluzione, ogni 5s fai una lettura e ne calcoli la media, ma non hai considerato che le prime 9 medie son da scartare perché l'array di valori non è ancora stato "abitato" (non mi viene il termine -.-")

Hai ragione. Ecco la modifica:

class calcola_media {
  public:
    calcola_media();
    unsigned int aggiorna(unsigned int);  //Quando chiami la funzione metti dentro il nuovo valore e ti ritorna la media
  
  private:
    unsigned int valori[10];    //ci metto dentro i valori
    byte indice;            //Memorizzo l'indice di dove ho messo l'ultimo dato
    boolean array_riempito;
};

calcola_media::calcola_media() {
  for (int i = 0; i < 9; i++) {
    valori[i] = 0;
  }
  indice = 0;
  array_riempito = false;
};

unsigned int calcola_media::aggiorna(unsigned int nuovo_valore) {
  if (++indice >= 10) {
    indice = 0; //Incremento indice e se, una volta incrementato, vale 10 lo riporto a 0
    array_riempito = true;
  }
  valori[indice] = nuovo_valore;
  unsigned int risultato_media = 0;
  if (!array_riempito) {
    for (int i = 0; i <= indice; i++) {
      risultato_media += valori[i];
    }
    risultato_media /= (indice + 1);
  }
  else {
    for (int i = 0; i < 9; i++) {
      risultato_media += valori[i];
    }
    risultato_media /= 10;
  }
  return risultato_media;
};

calcola_media media;

unsigned int media_attuale = 0;
unsigned long tempo_ultima_media = 0;

void loop() {
  if ((tempo_ultima_media - millis()) > 5000) {
    tempo_ultima_media = millis();
    media_attuale = media.aggiorna(analogRead(A0));
  }
}

lesto:
non è ancora stato "abitato" (non mi viene il termine -.-")

Si dice "popolato", se non ricordo male.