Πίνακας περιεχομένων:

QuickFFT: Υψηλής ταχύτητας FFT για Arduino: 3 βήματα
QuickFFT: Υψηλής ταχύτητας FFT για Arduino: 3 βήματα

Βίντεο: QuickFFT: Υψηλής ταχύτητας FFT για Arduino: 3 βήματα

Βίντεο: QuickFFT: Υψηλής ταχύτητας FFT για Arduino: 3 βήματα
Βίντεο: QuickFit: Τέσσερις απλές ασκήσεις για αρχάριους 2024, Ιούνιος
Anonim
QuickFFT: Υψηλής ταχύτητας FFT για Arduino
QuickFFT: Υψηλής ταχύτητας FFT για Arduino

Το τυπικό Arduino έχει περιορισμένη μνήμη RAM και επεξεργαστική ισχύ και το FFT είναι μια υπολογιστικά εντατική διαδικασία. Για πολλές εφαρμογές σε πραγματικό χρόνο, η μόνη απαίτηση είναι να λάβετε συχνότητα με μέγιστο πλάτος ή απαιτείται για τον εντοπισμό κορυφών συχνότητας.

Σε ένα από τα διδάσκοντά μου, ετοίμασα έναν κωδικό για FFT που μπορείτε να βρείτε εδώ: EasyFFT

Αυτός ο κώδικας ήταν σε θέση να εκτελέσει FFT έως 128 δείγματα στο Arduino nano. Μεγαλύτερος αριθμός δείγματος από αυτόν δεν είναι δυνατό λόγω της περιορισμένης μνήμης του Arduino. Έχω τροποποιήσει λίγο τη λειτουργία για να βελτιώσω την ταχύτητα και να μειώσω την κατανάλωση μνήμης. Αυτή η τροποποίηση επιτρέπει στο Arduino να εκτελεί FFT πέντε φορές πιο γρήγορα και καταναλώνει σχεδόν τη μισή μνήμη. Αυτό το Εγχειρίδιο δεν καλύπτει τη λειτουργία του FFT, αναφορές για αυτό μπορείτε να βρείτε στο EasyFFT.

Βήμα 1: Εργασία

Εργαζόμενος
Εργαζόμενος
Εργαζόμενος
Εργαζόμενος
Εργαζόμενος
Εργαζόμενος
Εργαζόμενος
Εργαζόμενος

Η τυπική λειτουργία FFT τροποποιείται για να βελτιώσει την ταχύτητα με μικρότερη ακρίβεια. Όπως φαίνεται στην εικόνα, ένα σήμα δοκιμής πρέπει να πολλαπλασιαστεί με κυματομορφές ημιτόνου ή συνημίτονου. Αυτές οι τιμές μπορεί να είναι μεταξύ 0 και 1, οπότε ο επιπλέων πολλαπλασιασμός είναι απαραίτητος. στο Arduino, ο πλωτός πολλαπλασιασμός είναι αργός σε σύγκριση με ακέραιες λειτουργίες.

Σε αυτή τη συνάρτηση, το ημίτονο/συνημίτονο κύμα αντικαθίσταται από ένα τετράγωνο κύμα. Καθώς πρέπει να πολλαπλασιάσουμε ένα σήμα δοκιμής με ένα τετραγωνικό κύμα που μπορεί να έχει τιμή 0, 1 ή -1. Λόγω αυτού, μπορούμε να αντικαταστήσουμε τον κυμαινόμενο πολλαπλασιασμό σε απλά ακέραιες προσθήκες ή αφαιρέσεις. Για την αφαίρεση ακέραιων αριθμών Arduino είναι περίπου 5 φορές ταχύτερη. Αυτό καθιστά την επίλυση περίπου 5 φορές πιο γρήγορη.

Λόγω αυτής της τροποποίησης, οι τιμές του κάδου συχνότητας μπορούν να αποθηκευτούν ως ακέραιος αριθμός (ο οποίος ήταν προηγουμένως float) και έχουμε ένα άλλο πλεονέκτημα χαμηλότερης κατανάλωσης μνήμης. Στο Arduino Nano, το int καταναλώνει 2 byte μνήμης ενώ το float καταναλώνει 4 bytes μνήμης. Λόγω αυτού του πλεονεκτήματος στον νέο κώδικα, είμαστε σε θέση να εκτελέσουμε FFT για σχεδόν 256 δείγματα (προηγουμένως 128 δείγματα).

Στο Normal FFT έπρεπε να αποθηκεύσουμε την τιμή του ημιτόνου για να κάνουμε μια λύση γρηγορότερη. Σε νέα λειτουργία, καθώς δεν απαιτούμε πλέον τιμές ημιτόνου/συνημίτονου, μπορούμε να το εξαλείψουμε και να αποθηκεύσουμε λίγη μνήμη.

Εκτέλεση:

Η εφαρμογή αυτής της λειτουργίας είναι άμεση. Μπορούμε απλά να αντιγράψουμε τη συνάρτηση στο ens του κώδικα. Αυτή η συνάρτηση μπορεί να εκτελεστεί χρησιμοποιώντας την παρακάτω εντολή:

float f = Q_FFT (δεδομένα, 256, 100). Στη συνάρτηση Q_FFT, δεδομένα: αυτός ο όρος είναι ένας πίνακας που έχει τιμές σήματος, το συνιστώμενο μέγεθος δείγματος είναι 2, 4, 8, 32, 64, 128, 256, 512,… και μετά. εάν το μέγεθος του δείγματος δεν ανήκει σε αυτές τις τιμές, θα αποκοπεί στην πλησιέστερη κάτω πλευρά των τιμών. για παράδειγμα, εάν το μέγεθος του δείγματος είναι 75, τότε θα πραγματοποιηθεί FFT για 64 αριθμούς δειγμάτων. Ο μέγιστος αριθμός μεγέθους δείγματος περιορίζεται από τη διαθέσιμη μνήμη RAM στο Arduino.

Ο δεύτερος όρος καθορίζει τον αριθμό των δειγμάτων σε έναν πίνακα και ο τελευταίος όρος είναι η συχνότητα δειγματοληψίας σε Hz.

Βήμα 2: Κωδικός

Αυτή η ενότητα εξηγεί την τροποποίηση στον κώδικα EasyFFT που πρέπει να λάβετε υπόψη κατά την τροποποίηση του κώδικα, 1. Όπως εξηγήθηκε προηγουμένως, εδώ χρησιμοποιούνται ακέραιοι αριθμοί για την εκτέλεση FFT. Το Int στο Arduino είναι ένας αριθμός 16 bit και μπορεί να περιέχει τιμές από -32768 έως 32768. όποτε η τιμή αυτού του int υπερβαίνει αυτό το εύρος προκαλεί το πρόβλημα. για την εξάλειψη αυτού του προβλήματος μετά από πάντα υπολογισμό επιπέδου. εάν κάποια από τις τιμές υπερβαίνει τους 15000 πλήρεις πίνακες θα διαιρεθεί με 100. αυτό θα αποτρέψει την υπερχείλιση του int.

2. Υπολογισμός πλάτους: Για τον υπολογισμό του πλάτους, το πραγματικό και το φανταστικό μέρος πρέπει να τετραγωνιστεί και απαιτείται η τετραγωνική ρίζα του αθροίσματος. τετραγωνισμός και η τετραγωνική ρίζα της συνάρτησης είναι χρονοβόρα. Για να γίνει η διαδικασία γρηγορότερη, αυτός ο κώδικας θα κάνει απλά μερικά από τα μεγέθη των πραγματικών και φανταστικών τμημάτων. Αυτό είναι σίγουρα λιγότερο ακριβές και μπορεί να οδηγήσει σε λάθος συμπέρασμα σε ορισμένες περιπτώσεις. μπορείτε να επιλέξετε να επιστρέψετε στην Κανονική μέθοδο για τον υπολογισμό του μεγέθους, αλλά θα χρειαστεί περισσότερος χρόνος και θα πρέπει επίσης να κάνετε κάποια ρύθμιση για να αποθηκεύσετε αυτούς τους αριθμούς.

3. Αυτός ο κωδικός δεν διαθέτει μονάδα για ανίχνευση πολλαπλών κορυφών. Απλώς θα επιλέξει την τιμή με το μέγιστο πλάτος (εξαιρουμένου του πρώτου αριθμού που είναι DC offset). Εάν χρειάζεστε πολλές κορυφές, μπορείτε να ανατρέξετε στον κώδικα EasyFFT και να κάνετε την απαιτούμενη τροποποίηση εδώ. Σε αυτήν την περίπτωση, κάποια συστοιχία/μεταβλητή πρέπει επίσης να δηλωθεί ως καθολική μεταβλητή.

4. Η συνάρτηση περιέχει την ακόλουθη γραμμή:

ανυπόγραφο int Pow2 [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

Η δήλωση των παραπάνω μεταβλητών ως καθολική μεταβλητή (η επικόλλησή της στην αρχή του κώδικα) θα εξοικονομήσει κάπου 1 χιλιοστό του χρόνου σε κάθε εκτέλεση.

5. Σε αντίθεση με τη λειτουργία EasyFFT, όπου οι κορυφαίες 5 κορυφές αποθηκεύτηκαν στον προκαθορισμένο πίνακα. Αυτή η συνάρτηση θα επιστρέψει μια τιμή float. αυτή η τιμή αντιπροσωπεύει τη συχνότητα με το μέγιστο πλάτος σε Hz. Έτσι, η αναπαράσταση του κώδικα θα μοιάζει κάπως έτσι.

float f = Q_FFT (δεδομένα, 256, 100);

6. Ανίχνευση αιχμής: Μόλις βρεθεί συχνότητα με μέγιστο πλάτος, αυτή η συνάρτηση χρησιμοποιεί ένα πλάτος συχνότητας λίγο πριν και μετά από αυτό για τον υπολογισμό των ακριβών αποτελεσμάτων. Το πλάτος που χρησιμοποιείται σε αυτόν τον υπολογισμό είναι επίσης το άθροισμα του μέτρου (όχι η τετραγωνική ρίζα του αθροίσματος των τετραγώνων)

αν Fn είναι η συχνότητα με μέγιστο πλάτος τότε η συχνότητα μπορεί να υπολογιστεί από τον παρακάτω τύπο.

Πραγματικό F = (A n-1 *Fn-1+An-1 *Fn-1+An-1 *Fn-1) / (An-1+An+An+1)

όπου An είναι πλάτος n της συχνότητας και Fn-1 είναι τιμή συχνότητας.

Βήμα 3: Αποτελέσματα:

Αποτελέσματα
Αποτελέσματα
Αποτελέσματα
Αποτελέσματα

Ο χρόνος επίλυσης εμφανίζεται στην παραπάνω σύγκριση εικόνας με το EasyFFT. Η ταχύτητα εμφανίζεται με τη σύγκριση.

Για δείγματα δεδομένων που έχουν 3 ημιτονοειδή κύματα με διαφορετικές συχνότητες εμφανίζεται. Το αποτέλεσμα από το QuickFFT συγκρίνεται με την έξοδο Scilab. Όπως βλέπουμε στην εικόνα 3 κορυφές με μέγιστο πλάτος ταιριάζουν με την έξοδο Scilab. Ωστόσο, η έξοδος αποτελείται από πολύ θόρυβο, ο οποίος μπορεί να είναι παραπλανητικός για ορισμένες εφαρμογές. Επομένως, συνιστάται να ελέγξετε σωστά τον κωδικό πριν υποβάλετε αίτηση στην αίτησή σας.

Ελπίζω να βρήκατε αυτόν τον κώδικα χρήσιμο για το έργο σας. Σε περίπτωση οποιουδήποτε ερωτήματος ή πρότασης παρακαλώ σχολιάστε.

Συνιστάται: