Arduino - moyenne mobile glissante permanente
Méthode très simple pour calculer une moyenne mobile dans un code arduino
PRINCIPE GÉNÉRAL: NombreDeValeursGlissantes = x Ratio = x/100; MoyenneIntantT = (ValeurLue * Ratio) + ((1-Ratio) * MoyenneIntantTInitial)
Comment calculer une moyenne mobile dans un code arduino ?.
Bonne question ! Et bien voici une façon très simple d'y arriver.
Petit rappel de ce qu'est une moyenne mobile, c'est ici: https://fr.wikipedia.org/wiki/Moyenne_glissante
Rappelons rapidement ce que nous cherchons à faire par un exemple: une tension variable qui arrive dans une fiche analogique A0, en utilisant analogRead. On veut mesurer la moyenne des données qui arrivent la fiche A0, en unités analogiques, via la fonction analogRead ( voir https://www.arduino.cc/en/Reference/analogRead).
Le manuel Arduino, en ligne, nous dit ceci à propos de analogRead: une unité analogique lue, correspond à 0.0049 volts, soit 4.9 mV par unité analogique (ce qui correspond à 5/1024, car il y a entre 0 et 1023 unités de mesures possibles, ce qui fait 1024 unités, et pas 1023 comme on peut souvent le lire). On lit aussi, que l'arduino fait 10000 mesures par seconde, et que donc, 1 mesure se fait toutes les 0.0001 secondes.
int FicheCapteur = A0; // c'est la fiche A0 que l'on mesure int DonneeCapteeEnA0 = 0; // on met à zéro la donnée en A0, au début const float UniteVoltEnA0 = 0.0049; // Une unité analogique, équivaut à 0.0049 volt float VoltsEnA0 = DonneeCapteeEnA0 * UniteVoltEnA0; // L'équivalence en volt, de la mesure en analogique float U = VoltsEnA0; // On nomme la tension U, car c'est plus élégant
On effectue la mesure du voltage dans la fiche A0, par une boucle simple de type:
void setup() { Serial.begin(9600); } void loop() { DonneeCapteeEnA0 = analogRead(FicheCapteur); // on mesure ce qui arrive dans la fiche U; // l'arduino calcul la tension U Serial.println(U); // affichage dans le moniteur série de la tension U }
Toutes les 0.0001 secondes, l'arduino fait une mesure de ce qui entre dans la fiche analogique A0 et calcule le voltage U, et l'affiche dans le moniteur série. Imaginons que cela renvoit à un moment donné, la série des 10 tensions variables suivantes:
# les données mesurées par l'arduino: O 2 5 1 3 7 8 2 4 9
On veut calculer la moyenne de ces 10 nombres. On prend donc la somme de ces 10 chiffres, et on divise cette somme par 10. Cela signifie, que l'on accorde un poids identique à chacun de ces chiffres, dans le calcul de la moyenne. Chacun pèse pour 10% (1 chiffre) dans le calcul de la moyenne (de 10 chiffres). Alors que la somme des autres valeurs (9 chiffres) de la moyenne pèse pour 90% dans le calcul de cette moyenne (de 10 chiffres). Cela pourrait s'écrire comme ceci:
MoyenneTensionsULues= [(U0x10%)]+[somme(U1;U2;...;U10)x90%] MoyenneIntantT = (ValeurLue * 10%) + ((1-(10/100)) * MoyenneIntantTInitial) MoyenneIntantT = (ValeurLue * (10/100)) + ((1-(10/100)) * MoyenneIntantTInitial)
Ce qui se traduit par:
NombreDeValeurs = 10; // Nombre de chiffres pris en compte pour le calcul Ratio = 1/NombreDeValeurs; // Poids d'une unité de chiffre, par rapport au nombre total de chiffres pris en compte pour le calcul Uµdebut; // La valeur moyenne en début de boucle Uµ = (Ratio * U) + ((1-Ration) * Uµdebut); // La valeur moyenne à l'instant de la valeur U mesurée Uµ = Uµdebut; // La valeur moyenne calculée, devient la valeur moyenne de début de boucle pour la prochaine récurrence
Dès lors, le code complet ARDUINO pour calculer une moyenne mobile glissante permanente, pourrait-être celui-ci:
// FONCTION MOYENNE MOBILE GLISSANTE PERMANENTE // Saisie des données : const int FicheCapteur = A0; // indiquez ici quelle est la fiche mesurée const int NombreDeValeurs = 10; // indiquez ici le nombre de chiffres pris en compte dans le calcul de la moyenne // Laissez la suite du code tel quel --> // Constantes et Calculs préalables versus équivalence volts et unité analogique int DonneeCaptee = 0; // on initialise la donnée à zéro const float UniteVoltAnalogique = 0.0049; // Une unité analogique, équivaut à 0.0049 volt float VoltsFicheAnalogique = DonneeCaptee * UniteVoltAnalogique; // L'équivalence en volt, de la mesure en analogique // Constantes et Calculs préalables versus calculs de la moyenne float RatioNbVal = 1 / NombreDeValeurs; // Poids d'une unité de chiffre, par rapport au nombre total de chiffres pris en compte pour le calcul float MoyenneDebut = 0; // La valeur moyenne en début de boucle, initialisée à zéro float Moyenne = (RatioNbVal * VoltsFicheAnalogique) + ((1-RatioNbVal) * MoyenneDebut); // La valeur moyenne // Initialisation du port série void setup() { Serial.begin(9600); } // Boucle infinie void loop() { DonneeCaptee = analogRead(FicheCapteur); // on mesure ce qui arrive dans la fiche Moyenne; // calcul de la moyenne Moyenne = MoyenneDebut; // Puis, la valeur moyenne devient la valeur moyenne de début de boucle pour la prochaine récurrence Serial.println(Moyenne); // affichage dans le moniteur série de la moyenne }