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 23699 fois


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 : 24

Total visites Total visites: 1705877  

Record connectés :
Record connectés :Cumulé : 200

Le 20/10/2024 @ 06:06


Webmaster - Infos

Ip : 3.147.62.5

Recherche




Nouvelles des Amis
D'où venez-vous ?

Texte à méditer :  Quand un scientifique distingué mais âgé dit que quelque chose est possible, il a presque certainement raison. Quand il déclare que quelque chose est impossible, il a très probablement tort.  Arthur C. Clarke
^ Haut ^