Sylvain Mahé Le site Web Retour à l'accueil Principes Partager des idées et des projets. Contact 06.45.49.96.98
contact@sylvainmahe.site
Écriture de la page : Sylvain Mahé
Filtrer des valeurs avec la classe Filter Le filtrage de données brutes provenant de sources analogiques bruitées est essentiel dans beaucoup de projets, ainsi que l'obtention de moyennes en temps réel ou avec progressivité dans le temps afin par exemple d'en stabiliser la visualisation sur des affichages. La classe Filter est un filtre linéaire non prédictif très performant qui automatise cette tâche et offre l'avantage de pouvoir effectuer des moyennes soit sur l'équivalent d'un certain nombre d'échantillons, soit sur une certaine durée paramétrable, ce qui dans ce dernier cas est très intéressant car cette fonction rend les moyennes effectuées complètement indépendantes de la vitesse d'exécution du programme. L'intérêt de lisser des valeurs fluctuantes sur un temps bien défini permet de faire abstraction des temps d'exécution des boucles de calculs. Ceci est utile pour maintenir la même capacité à calculer en temps réel quel que soit la complexité des algorithmes mis en œuvre dans vos programmes. Exemple de filtrage sur 50 échantillons : #include <Filter.h> #include <AnalogRead.h> int main() { Filter myFilter = Filter (50, false); AnalogRead myPotentiometer = AnalogRead (25); while (true) { myPotentiometer.read(); myFilter.set (myPotentiometer.value); //myFilter.value est un filtrage effectué sur l'équivalent de 50 échantillons de la valeur retournée par le potentiomètre } return 0; } Dans cet exemple, un objet myFilter de type Filter est déclaré :
- Le 1er paramètre indique d'effectuer un filtrage sur l'équivalent de 50 échantillons ou sur une durée de 50 millisecondes (selon l'état du paramètre suivant).
- Le 2ème paramètre false spécifie un filtrage sur l'équivalent d'un certain nombre d'échantillons.
Si vous souhaitez effectuer un filtrage sur une durée plutôt que sur l'équivalent d'un certain nombre d'échantillons, indiquez true en paramètre. Ensuite un objet myPotentiometer de type AnalogRead est déclaré, en paramètre est indiqué d'utiliser le port GPIO numéro 25 de l'automate programmable en entrée. Dans la boucle, cet objet myPotentiometer appelle la fonction read ce qui permet de lire l'entrée analogique concernée, et donc de mettre à jour la variable value attachée à cet objet, variable qui est envoyée en paramètre à la fonction set de l'objet myFilter à la ligne suivante, et fonction qui se charge d'effectuer le filtrage. Ainsi la variable value de l'objet myFilter est un filtrage effectué sur l'équivalent de 50 échantillons de la valeur retournée par le potentiomètre. Plus l'amplitude du filtre est élevée, plus les valeurs sont lissées. Exemple de filtrage sur 50 millisecondes : #include <Filter.h> #include <AnalogRead.h> int main() { Filter myFilter = Filter (50, true); AnalogRead myPotentiometer = AnalogRead (25); while (true) { myPotentiometer.read(); myFilter.set (myPotentiometer.value); //myFilter.value est un filtrage effectué sur une durée de 50 millisecondes de la valeur retournée par le potentiomètre } return 0; } Le seul changement ici par rapport au précédent exemple est le 2ème paramètre passé de false à true à la déclaration de l'objet myFilter. Pour comprendre le filtrage indépendant de la vitesse d'exécution : Si la durée du filtrage est spécifiée à 1000 millisecondes, et qu'entre 2 itérations, soit 2 appels à la fonction set, un temps de 8 millisecondes s'est écoulé, alors le filtre effectuera à cet instant l'équivalent d'une moyenne sur 125 échantillons, car :
1000ms / 8ms = 125 échantillons

En mode de filtrage temporel, la durée qui précède le dernier appel à la fonction set est intégré dans les calculs de la moyenne, de sorte d'effectuer un filtrage indépendamment des vitesses d'exécution du code, ce qui est fondamental pour garder une homogénéité dans le comportement des données filtrées.
Pour finir, d'autres fonctions utiles existent : - amount : permet de modifier à tout moment l'amplitude du filtrage.
- reset : permet de réinitialiser le filtre, donc lors du prochain appel à la fonction set la valeur filtrée résultante prendra effet sur de nouvelles valeurs envoyées en paramètre à cette fonction (comme si les précédentes données avaient été effacées).
Le filtrage est généralement indispensable dans la majorité des projets, ne serait-ce que pour pouvoir visualiser sur des affichages numériques des valeurs stables. La classe Filter est un bon complément en association avec la classe Hysteresis dans le but de produire des informations exploitables pour l'utilisateur. Références : Récapitulatif des fonctions et variables de cette classe : float value = 0; Filter (const unsigned long AMOUNT, const bool TIME_COMPENSATION); void set (const float VALUE); void amount (const unsigned long AMOUNT); void reset();