Table des matières:

Moyenne courante pour vos projets de microcontrôleur : 6 étapes
Moyenne courante pour vos projets de microcontrôleur : 6 étapes

Vidéo: Moyenne courante pour vos projets de microcontrôleur : 6 étapes

Vidéo: Moyenne courante pour vos projets de microcontrôleur : 6 étapes
Vidéo: Concevoir des PCB pour PROFESSIONNALISER vos projets !! (Tuto EasyEDA) 2024, Novembre
Anonim
Moyenne courante pour vos projets de microcontrôleur
Moyenne courante pour vos projets de microcontrôleur

Dans ce instructable, je vais expliquer ce qu'est une moyenne courante et pourquoi vous devriez vous en soucier, ainsi que vous montrer comment elle doit être implémentée pour une efficacité de calcul maximale (ne vous inquiétez pas de la complexité, c'est très simple à comprendre et je vais fournir également une bibliothèque facile à utiliser pour vos projets arduino:)

La moyenne mobile, également communément appelée moyenne mobile, moyenne mobile ou moyenne mobile, est un terme utilisé pour décrire la valeur moyenne des N dernières valeurs d'une série de données. Il peut être calculé comme une moyenne normale ou vous pouvez utiliser une astuce pour qu'il ait un impact minimal sur les performances de votre code.

Étape 1: cas d'utilisation: lissage des mesures ADC

Cas d'utilisation: lissage des mesures ADC
Cas d'utilisation: lissage des mesures ADC

Arduino a un ADC 10 bits décent avec très peu de bruit. Lors de la mesure d'une valeur sur un capteur tel qu'un potentiomètre, une photorésistance ou d'autres composants à bruit élevé, il est difficile de croire que la mesure est correcte.

Une solution consiste à prendre plusieurs mesures à chaque fois que vous souhaitez lire votre capteur et à les faire la moyenne. Dans certains cas, c'est une solution viable, mais pas toujours. Si vous vouliez lire l'ADC 1000 fois par seconde, il vous en faudrait 10 000 si vous preniez en moyenne 10 mesures. Une énorme perte de temps de calcul.

Ma solution proposée est de prendre des mesures 1000 fois par seconde, de mettre à jour la moyenne courante à chaque fois et de l'utiliser comme valeur actuelle. Cette méthode introduit une certaine latence mais réduit la complexité de calcul de votre application, vous donnant beaucoup plus de temps pour un traitement supplémentaire.

Dans l'image ci-dessus, j'ai utilisé la moyenne courante des 32 dernières mesures. Vous verrez que cette méthode n'est pas à 100% infaillible mais elle améliore considérablement la précision (ce n'est pas pire que de faire une moyenne de 32 échantillons à chaque fois). Si vous vouliez calculer une moyenne de 32 mesures à chaque fois, cela prendrait plus de 0,25 ms sur Arduino UNO pour les mesures seules !

Étape 2: cas d'utilisation: mesure de la composante CC du signal du microphone

Cas d'utilisation: mesure de la composante CC du signal du microphone
Cas d'utilisation: mesure de la composante CC du signal du microphone
Cas d'utilisation: mesure de la composante CC du signal du microphone
Cas d'utilisation: mesure de la composante CC du signal du microphone
Cas d'utilisation: mesure de la composante CC du signal du microphone
Cas d'utilisation: mesure de la composante CC du signal du microphone

Arduino peut mesurer des tensions entre 0 et Vcc (normalement 5 V). Le signal audio est complètement AC et si vous voulez le mesurer sur un microcontrôleur, vous devez le polariser autour de 1/2 Vcc. Dans un projet Arduino UNO, cela signifierait environ 2,5 V (DC) + signal audio (AC). Lors de l'utilisation d'un ADC 10 bits et d'une alimentation 5 V, une polarisation de 2,5 V doit être égale à une mesure de 512. Donc, pour obtenir une valeur CA du signal, 512 doit être soustrait de la mesure ADC et c'est tout, n'est-ce pas ?

Dans un monde idéal, ce serait vrai. Malheureusement, la vraie vie est plus compliquée et notre biais de signal a tendance à dériver. Un bruit de 50 Hz (60 Hz si vous habitez aux États-Unis) provenant du réseau électrique est très courant. Habituellement, ce n'est pas trop problématique, mais il est bon de savoir que cela existe. La dérive linéaire due au chauffage des composants est plus problématique. Vous définissez soigneusement la correction de décalage CC au démarrage et elle s'éloigne lentement au fur et à mesure que votre application s'exécute.

Je vais illustrer ce problème avec un détecteur de battement (musique). Vous configurez votre suppression de biais et les battements sont clairs (image 2). Après un certain temps, les mouvements de polarisation CC et les battements sont à peine perceptibles par le microcontrôleur (image 3). L'algorithme de détection de battement sera exploré en profondeur dans un futur instructable car il dépasse la portée de cet article.

Heureusement, il existe un moyen de continuer à calculer constamment le décalage DC de l'audio. Il n'est pas surprenant que la moyenne courante, sujet de cette instructable, fournisse une solution.

Nous savons que la valeur moyenne de tout signal AC est 0. En utilisant cette connaissance, nous pouvons déduire que la valeur moyenne du signal AC + DC est sa polarisation DC. Pour le supprimer, nous pouvons prendre une moyenne courante des dernières valeurs et la soustraire de la lecture ADC actuelle. Notez que vous devez utiliser une moyenne mobile suffisamment longue. Pour l'audio, un dixième de seconde (le nombre d'échantillons dépend de votre fréquence d'échantillonnage) devrait suffire mais sachez que des moyennes plus longues fonctionnent mieux. Dans la première image, vous pouvez voir un exemple de calcul de polarisation CC réel avec une moyenne courante avec 64 éléments à une fréquence d'échantillonnage de 1 kHz (moins que ce que j'ai recommandé mais cela fonctionne toujours).

Étape 3: Calcul

Calcul
Calcul

Vous pouvez imaginer la moyenne courante comme le poids moyen des personnes dans la salle d'attente du médecin. Le docteur finit d'examiner un patient et simultanément un nouveau entre dans la salle d'attente.

Pour connaître le poids moyen de tous les patients en attente dans la salle d'attente, l'infirmière pourrait ensuite demander à chaque patient son poids, additionner ces chiffres et diviser par le nombre de patients. Chaque fois que le médecin accepte un nouveau patient, l'infirmière répète tout le processus.

Vous pensez peut-être: « Cela ne semble pas très efficace… Il doit y avoir une meilleure façon de le faire. » Et vous auriez raison.

Pour optimiser ce processus, l'infirmière pourrait conserver un enregistrement du poids total du groupe actuel de patients. Une fois que le médecin appelle un nouveau patient, l'infirmière lui demande son poids et le soustrait du total du groupe et le laisse partir. L'infirmière demandait ensuite au patient qui venait d'entrer dans la salle d'attente son poids et l'ajoutait au total. Le poids moyen des patients après chaque quart de travail serait la somme des poids divisée par le nombre de patients (oui, comme avant, mais maintenant, l'infirmière n'a interrogé que deux personnes sur leur poids au lieu de toutes). Je me rends compte que ce paragraphe a pu être un peu déroutant, veuillez donc consulter l'illustration ci-dessus pour plus de clarté (ou posez des questions dans les commentaires).

Mais même si vous n'avez pas trouvé le dernier paragraphe déroutant, vous pourriez avoir des questions telles que ce qui devrait être dans l'accumulateur au début, comment puis-je mettre ce que je viens de lire dans un code C réel ? Cela sera abordé à l'étape suivante, où vous obtiendrez également mon code source.

Étape 4: le code

Le code
Le code

Afin de calculer la moyenne courante, vous avez d'abord besoin d'un moyen de stocker les N dernières valeurs. vous pouvez avoir un tableau avec N éléments et déplacer tout le contenu d'un endroit à chaque fois que vous ajoutez un élément (veuillez ne pas le faire), ou vous pouvez écraser un ancien élément et ajuster le pointeur sur l'élément suivant à supprimer (veuillez faire ceci:)

L'accumulateur doit démarrer initialisé à 0, il en va de même pour tous les éléments de la ligne à retard. Dans d'autres cas, votre moyenne courante sera toujours fausse. Vous verrez que delayLine_init s'occupe d'initialiser la ligne à retard, vous devriez vous occuper de l'accumulateur vous-même.

l'ajout d'un élément à la ligne à retard est aussi simple que de décrémenter l'index de l'élément le plus récent de 1, en s'assurant qu'il ne pointe pas vers le côté du tableau de la ligne à retard. après avoir décrémenté l'index lorsqu'il est à 0, il bouclera jusqu'à 255 (car il s'agit d'un entier non signé de 8 bits). L'opérateur modulo (%) avec la taille du tableau de lignes à retard garantira que l'index pointe vers un élément valide.

Le calcul d'une moyenne courante devrait être facile à comprendre si vous avez suivi mon analogie à l'étape précédente. Soustraire l'élément le plus ancien de l'accumulateur, ajouter la valeur la plus récente à l'accumulateur, envoyer la valeur la plus récente à la ligne à retard, renvoyer l'accumulateur divisé par le nombre d'éléments.

Facile, non ?

N'hésitez pas à expérimenter en utilisant le code ci-joint pour mieux comprendre comment tout cela fonctionne. Dans l'état actuel des choses, arduino lit la valeur analogique sur la broche analogique A0 et imprime "[Valeur ADC], [moyenne courante]" sur le port série à un débit de 115200 bauds. Si vous ouvrez le traceur série d'arduino avec un débit en bauds correct, vous verrez deux lignes: la valeur ADC (bleue) et la valeur lissée (rouge).

Étape 5: Suppléments

Suppléments
Suppléments

Il y a quelques choses que vous n'avez pas nécessairement besoin de savoir pour utiliser la moyenne courante dans votre projet, mais cela ne fera pas de mal de savoir.

retard: je vais commencer par parler de l'illustration de cette étape. Vous remarquerez que la moyenne courante de plus d'éléments introduit un plus grand retard. Si votre temps de réponse au changement de valeur est critique, vous pouvez utiliser une moyenne courante plus courte ou augmenter la fréquence d'échantillonnage (mesurer plus souvent).

Passer à autre chose.

initialisation: lorsque j'ai parlé de l'initialisation des éléments de l'accumulateur et du délai, j'ai dit que vous deviez tous les initialiser à 0. Vous pouvez également initialiser la ligne à retard sur ce que vous voulez, mais l'accumulateur doit commencer comme une somme des N éléments les plus récents dans la ligne à retard (où N est le nombre d'éléments dans votre moyenne courante). Si l'accumulateur démarre comme n'importe quelle autre valeur, la moyenne calculée sera erronée - soit trop faible, soit trop élevée, toujours du même montant (en supposant les mêmes conditions initiales). Je vous suggère d'essayer d'apprendre pourquoi il en est ainsi en utilisant une "simulation stylo et papier".

taille de l'accumulateur: vous devez également noter que l'accumulateur doit être suffisamment grand pour stocker la somme de tous les éléments de la ligne à retard s'ils sont tous positifs ou négatifs max. En pratique, cela signifie que l'accumulateur doit être d'un type de données supérieur aux éléments de ligne à retard et signé, si les éléments de ligne à retard sont signés.

Astuce: les longues lignes à retard prennent beaucoup de mémoire. Cela peut vite devenir un problème. Si vous êtes très limité en mémoire et que vous ne vous souciez pas beaucoup de la précision, vous pouvez approximer la moyenne courante en omettant complètement le délai et en faisant ceci à la place: soustrayez 1/N * accumulateur de l'accumulateur et ajoutez une nouvelle valeur (par exemple de 8 moyenne courante longue: accumulateur = accumulateur * 7 / 8 + newValue). Cette méthode donne un résultat erroné, mais c'est une méthode décente de calcul de la moyenne courante lorsque vous manquez de mémoire.

linguistique: « moyenne courante/moyenne » est généralement utilisée pour faire référence à la moyenne en temps réel, tandis que « moyenne mobile/moyenne » signifie généralement que l'algorithme s'exécute sur un ensemble de données statiques tel qu'une feuille de calcul Excel.

Étape 6: Conclusion

J'espère que cette instructable était assez facile à comprendre et qu'elle vous aidera dans vos futurs projets. N'hésitez pas à poster des questions dans les commentaires ci-dessous si quelque chose n'est pas clair.

Conseillé: