Table des matières:

QuickFFT : FFT haute vitesse pour Arduino : 3 étapes
QuickFFT : FFT haute vitesse pour Arduino : 3 étapes

Vidéo: QuickFFT : FFT haute vitesse pour Arduino : 3 étapes

Vidéo: QuickFFT : FFT haute vitesse pour Arduino : 3 étapes
Vidéo: Эквивалент сети. DIY LISN. Синфазный дроссель. Своими руками. 2024, Novembre
Anonim
QuickFFT: FFT haute vitesse pour Arduino
QuickFFT: FFT haute vitesse pour Arduino

Arduino typique a une RAM et une puissance de traitement limitées, et FFT est un processus gourmand en calcul. Pour de nombreuses applications en temps réel, la seule exigence est d'obtenir une fréquence avec une amplitude maximale ou requise pour détecter les pics de fréquence.

Dans l'un de mes instructable, j'ai préparé un code pour FFT qui peut être trouvé ici: EasyFFT

Ce code était capable d'effectuer une FFT jusqu'à 128 échantillons sur Arduino nano. Un nombre d'échantillons supérieur à celui-ci n'est pas possible en raison de la mémoire limitée d'Arduino. J'ai légèrement modifié la fonction pour améliorer la vitesse et réduire la consommation de mémoire. Cette modification permet à Arduino d'effectuer la FFT cinq fois plus rapidement et consomme près de la moitié de la mémoire. Ce Instructable ne couvre pas le travail de FFT, des références pour cela peuvent être trouvées à EasyFFT.

Étape 1: Travailler

Travail
Travail
Travail
Travail
Travail
Travail
Travail
Travail

La fonction FFT typique est modifiée pour améliorer la vitesse avec une précision moindre. Comme le montre l'image, un signal de test doit être multiplié par des formes d'onde sinusoïdales ou cosinusoïdales. Ces valeurs peuvent être comprises entre 0 et 1, il est donc indispensable de faire une multiplication flottante. dans Arduino, la multiplication flottante est lente par rapport aux opérations sur des nombres entiers.

Dans cette fonction, l'onde sinus/cosinus est remplacée par une onde carrée. Comme nous devons multiplier un signal de test par un signal carré qui peut avoir la valeur 0, 1 ou -1. Pour cette raison, nous pouvons remplacer la multiplication flottante par une simple addition ou soustraction d'entiers. Pour Arduino, l'addition ou la soustraction d'entiers est environ 5 fois plus rapide. Cela rend la résolution environ 5 fois plus rapide.

En raison de cette modification, les valeurs des intervalles de fréquence peuvent désormais être stockées sous forme d'entier (qui était auparavant flottant) et nous obtenons un autre avantage de la consommation de mémoire inférieure. Dans Arduino Nano, int consomme 2 octets de mémoire tandis que float consomme 4 octets de mémoire. En raison de cet avantage dans le nouveau code, nous sommes en mesure d'effectuer une FFT pour près de 256 échantillons (auparavant 128 échantillons).

Dans la FFT normale, nous devions stocker la valeur du sinus pour accélérer la résolution. Dans la nouvelle fonction, comme nous n'avons plus besoin de valeurs sinus/cosinus, nous pouvons l'éliminer et économiser de la mémoire.

Mise en œuvre:

La mise en œuvre de cette fonction est simple. Nous pouvons simplement copier la fonction à la fin du code. Cette fonction peut être exécutée à l'aide de la commande ci-dessous:

float f= Q_FFT(données, 256, 100); Dans la fonction Q_FFT, données: ce terme est un tableau ayant des valeurs de signal, la taille d'échantillon recommandée est de 2, 4, 8, 32, 64, 128, 256, 512, … et plus. si la taille de l'échantillon n'appartient pas à ces valeurs, il sera tronqué au côté inférieur le plus proche des valeurs. par exemple, si la taille de l'échantillon est de 75, la FFT sera effectuée pour 64 nombres d'échantillons. Le nombre maximum de taille d'échantillon est limité par la RAM disponible sur Arduino.

Le deuxième terme spécifie le nombre d'échantillons dans un tableau et le dernier terme est la fréquence d'échantillonnage en Hz.

Étape 2: Coder

Cette section explique la modification apportée au code EasyFFT qui doit être gardée à l'esprit lors de la modification du code, 1. Comme expliqué précédemment, ici les entiers sont utilisés pour faire la FFT. Int dans Arduino est un nombre 16 bits et peut contenir des valeurs de -32768 à 32768. chaque fois que la valeur de cet int dépasse cette plage, cela pose problème. pour éliminer ce problème après chaque calcul de niveau. si l'une des valeurs dépasse 15 000, les tableaux complets seront divisés par 100. Cela empêchera le débordement de l'int.

2. Calcul d'amplitude: Pour calculer l'amplitude, la partie réelle et imaginaire doit être mise au carré et la racine carrée de la somme est requise. la quadrature et la racine carrée de la fonction prend du temps. pour accélérer le processus, ce code fera simplement certaines des grandeurs des parties réelles et imaginaires. Ceci est sûrement moins précis et peut conduire à une conclusion erronée dans certains cas. vous pouvez choisir de revenir à la méthode normale pour le calcul de la magnitude, mais cela prendra plus de temps et vous devrez également prendre des dispositions pour stocker ces nombres.

3. Ce code n'a pas de module pour la détection de pics multiples. Il choisira simplement la valeur avec l'amplitude max (à l'exclusion du premier nombre qui est DC offset). Si vous avez besoin de plusieurs pics, vous pouvez vous référer au code EasyFFT et effectuer les modifications requises ici. Dans ce cas, un tableau/une variable doit également être déclaré en tant que variable globale.

4. La fonction contient la ligne suivante:

int non signé Pow2[13]={1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

déclarer les variables ci-dessus en tant que variable globale (la coller au début du code) fera gagner environ 1 milliseconde de temps à chaque exécution.

5. Contrairement à la fonction EasyFFT, où les 5 meilleurs pics étaient stockés dans le tableau prédéfini. Cette fonction renverra une valeur flottante. cette valeur représente la fréquence d'amplitude maximale en Hz. La représentation du code ressemblera donc à ceci.

float f= Q_FFT(données, 256, 100);

6. Détection de crête: Une fois la fréquence avec une amplitude maximale trouvée, cette fonction utilise une amplitude de fréquence juste avant et après pour calculer les résultats précis. L'amplitude utilisée dans ce calcul est également la somme des modules (pas la racine carrée de la somme des carrés)

si Fn est la fréquence avec une amplitude maximale, la fréquence peut être calculée à partir de la formule ci-dessous.

F réel= (A n-1 *Fn-1 + An-1 *Fn-1 + An-1 *Fn-1) / (An-1+An+An+1)

où An est l'amplitude de n la fréquence et Fn-1 est la valeur de fréquence.

Étape 3: Résultats:

Résultats
Résultats
Résultats
Résultats

Le temps de résolution est indiqué dans la comparaison de l'image ci-dessus avec EasyFFT. Vitesse de celui-ci montré avec la comparaison.

Pour des exemples de données ayant 3 ondes sinusoïdales avec différentes fréquences sont affichées. Le résultat de QuickFFT est comparé à la sortie de Scilab. Comme nous pouvons le voir sur l'image, 3 pics avec une amplitude maximale correspondent à la sortie Scilab. Cependant, la sortie contient beaucoup de bruit, ce qui peut être trompeur pour certaines applications. Il est donc conseillé de bien vérifier le code avant de postuler à votre candidature.

J'espère que vous avez trouvé ce code utile pour votre projet. En cas de question ou de suggestion, veuillez commenter.

Conseillé: