Bienvenue !
cool Bienvenue les fans de PIC !
(aux fans du langage Pascal aussi !)
Technique

Fermer Astuces

Fermer Comment supporter PMP

Fermer Documentation générale

Fermer Manuels

Autres trucs

Fermer Comment supporter PMP

Fermer Coup de coeur du jour

Fermer Documentation

Fermer Hors sujet

Recherche




Téléchargements
Astuces - Implémenter un filtre passe bas pour les ADC ou toute autre valeur

A fin d'éliminer le bruit ou limiter la réponse à des phénomènes perturbateurs, les acquisitions venant de l'ADC peuvent être traitées par un FPB (Filtre Passe-Bas), qui peut être implémenté sous la forme d'un filtre exponentiel de premier ordre (un pôle) :

Value := Value + K*(New - Value);

K est de la forme 1/N.

Si N est choisi comme un multiple de 2, l'implémentation effective pour des entiers est grandement simplifiée :

Value := (Value * (N - 1) + New) div N;

Ce qui peut ensuite être fortement optimisé par le compilateur en utilisant un décalage à droite final.

Quelles différences avec une moyenne glissante classique de la forme :

Value := (Sample_0 + Sample_1 + ... + Sample_n) div n ?

Tout d'abord, si N=2, le filtre est strictement équivalent à une moyenne classique avec la valeur courante et non sur les acquisitions uniquement :

Value := Value + (New - Value) div 2 == Value := (Value + New) div 2 ;

Ensuite vous n'avez pas à accumuler les valeurs dans un tableau ou une variable de taille supérieure.
Ensuite la réponse est très différente (exponentielle et non linéaire) et le filtre à un pôle fournit une valeur en sortie dès que la première valeur en entrée est traitée.
Finalement un meilleur traitement peut être obtenu en utilisant plusieurs pôles en cascade, avec des valeurs N plus faibles. La réponse est alors encore améliorée.

Inconvénient courant d'une implémentation purement entière : la précision des valeurs faibles est réduite et la valeur du résultat peut plafonner à une valeur dans l'intervalle Value-N .. Value + N.

Pour contourner ce problème, on peut utiliser un accumulateur mis à l'échelle, disons : un accumulateur de 32 bits pour des valeurs d'entrée de 16 bits.

Exemple:

Nous pouvons utiliser des valeurs multipliées par P32 = 65536; c'est optimal car 65536 = (1 shl 16).

La formule devient alors :

AccValue32 := (AccValue32 * (N - 1) + NewValue32 * P32) div N;

Value16 := AccValue32 div P32;

Avec N = 16, P32 = 65536 et une nouvelle valeur en entrée sur 16 bits New16, il vient :

AccValue32 := (AccValue32 * 15 + (longword(New16) shl 16) shr 4;

Value16 := hiword(AccValue32); // La valeur filtrée en sortie sur 16 bits est simplement le mot supérieur de l'accumulateur.

A l'initialisation (ou à la première valeur), on fait :

AccValue32 := longword(New16) shl 16;

Value16 := New16;

Il est aisé pour le compilateur d'optimiser la formule avec des décalages et il n'y a plus de phénomènes de plancher ou de plafonnement.


Date de création : 2010.08.13 3:44 PM
Dernière modification : 2014.03.19 1:41 PM
Catégorie : Astuces
Page lue 22713 fois


Imprimer l'article Imprimer l'article


react.gifRéactions à cet article

Personne n'a encore laissé de commentaire.
Soyez donc le premier !


Connexion...
 Liste des membres Membres : 75

Votre pseudo :

Mot de passe :

[ Mot de passe perdu ? ]


[ Devenir membre ]


Membre en ligne :  Membre en ligne :
Anonymes en ligne :  Anonymes en ligne : 15

Total visites Total visites: 1584395  

Record connectés :
Record connectés :Cumulé : 170

Le 01/01/2021 @ 17:50


Webmaster - Infos

Ip : 3.135.219.166

Recherche




Nouvelles des Amis
D'où venez-vous ?

Texte à méditer :  L’informatique des entreprises [...] est à l’image d’un site archéologique. [...] Tout au fond, on tombe sur de vrais fossiles, calcifiés : la carte perforée n’est plus physiquement là,
mais on peut trouver son « empreinte » sur des disques durs dernier cri, jusqu’à des traces d’organisation en quatre-vingt « colonnes ».  
Pierre Vandevingste, La Recherche, décembre 1996
^ Haut ^