Πίνακας περιεχομένων:
- Βήμα 1: Εισαγωγή στον μετασχηματισμό συχνότητας
- Βήμα 2: Γρήγορος μετασχηματισμός Fourier
- Βήμα 3: Επεξήγηση του κώδικα
- Βήμα 4: Επεξήγηση του κώδικα: Λειτουργία FFT
- Βήμα 5: Δοκιμή του κώδικα
- Βήμα 6: Συμπέρασμα
Βίντεο: EasyFFT: Fast Fourier Transform (FFT) για Arduino: 6 βήματα
2024 Συγγραφέας: John Day | [email protected]. Τελευταία τροποποίηση: 2024-01-30 08:32
Η μέτρηση της συχνότητας από το σήμα που έχει ληφθεί μπορεί να είναι μια δύσκολη εργασία, ειδικά στο Arduino καθώς έχει χαμηλότερη υπολογιστική ισχύ. Υπάρχουν διαθέσιμες μέθοδοι για τη λήψη μηδενικής διέλευσης όπου η συχνότητα καταγράφεται ελέγχοντας πόσες φορές το σήμα διασχίζει μηδενικές γραμμές εντός του δεδομένου χρόνου. Μια τέτοια μέθοδος μπορεί να μην λειτουργεί όταν το σήμα είναι ένας συνδυασμός διαφόρων συχνοτήτων.
Αυτό είναι κατά κάποιο τρόπο δύσκολο να κωδικοποιηθεί εάν δεν είστε από τέτοιο υπόβαθρο. Όμως, ως τσιγκούνης αυτός ο κώδικας μπορεί να είναι ιδιαίτερα χρήσιμος για διάφορα έργα που σχετίζονται με τη μουσική, την ανάλυση σήματος. Το κίνητρο αυτού του έργου ήταν να προετοιμάσει έναν κώδικα που είναι εύκολο να εφαρμοστεί στο Arduino χωρίς να μπει στο παρασκήνιο του.
Αυτό το έργο δεν εξηγεί τη λειτουργία του FFT αλλά εξηγεί την εφαρμογή της συνάρτησης FFT. Η ίδια διαδικασία εξηγείται επίσης στο συνημμένο βίντεο.
Εάν ενδιαφέρεστε μόνο για την εφαρμογή του κώδικα και όχι για μια εξήγησή του. Μπορείτε να μεταβείτε απευθείας στο βήμα 3.
Βήμα 1: Εισαγωγή στον μετασχηματισμό συχνότητας
Κάθε σήμα μπορεί να αποτελείται από ένα συνδυασμό διαφόρων ημιτονοειδών κυμάτων. Έτσι, κάθε σήμα που βασίζεται στο χρόνο μπορεί επίσης να εμφανιστεί ως ένας συνδυασμός των διαφόρων ημιτόνων με διαφορετικά πλάτη.
Προσπάθησα να εξηγήσω τη λειτουργία του DFT (διακριτός μετασχηματισμός Fourier) σε ένα από τα προηγούμενα εκπαιδευτικά (https://www.instructables.com/id/Arduino-Frequency…). Αυτές οι μέθοδοι είναι εξαιρετικά αργές για κάθε εφαρμογή σε πραγματικό χρόνο. που το καθιστά σχεδόν άχρηστο.
Στην εικόνα, εμφανίζεται ένα σήμα που είναι ένας συνδυασμός δύο συχνοτήτων f2 και f5. Αυτό το σήμα πολλαπλασιάζεται με ημιτονοειδή κύματα τιμών f1 έως f5.
Μπορεί να αποδειχθεί μαθηματικά ότι -το άθροισμα του πολλαπλασιασμού δύο αρμονικών συνόλων δεδομένων με διαφορετική συχνότητα τείνει στο μηδέν (υψηλότερος αριθμός δεδομένων μπορεί να οδηγήσει σε αποτέλεσμα ζύμωσης). Στην περίπτωσή μας, εάν αυτές οι δύο συχνότητες πολλαπλασιασμού έχουν την ίδια (ή πολύ κοντινή) συχνότητα, το άθροισμα του πολλαπλασιασμού είναι ο μη μηδενικός αριθμός.
Έτσι, εάν το σήμα μας πολλαπλασιαστεί με f1, το άθροισμα του πολλαπλασιασμού θα είναι μηδέν (κοντά στο μηδέν για πραγματική εφαρμογή). Παρόμοια είναι η περίπτωση για f3, f4. Ωστόσο, για την τιμή, η έξοδος f2 και f5 δεν θα είναι μηδέν, αλλά σημαντικά υψηλότερη από τις υπόλοιπες τιμές.
Εδώ ένα σήμα δοκιμάζεται με 5 συχνότητες, οπότε το σήμα πρέπει να πολλαπλασιαστεί με πέντε συχνότητες. Ένας τέτοιος έντονος υπολογισμός απαιτεί μεγαλύτερο χρόνο. Μαθηματικά αποδεικνύεται ότι για Ν αριθμό δειγμάτων χρειάζεται πολλαπλασιασμός συμπλόκου Ν*Ν.
Βήμα 2: Γρήγορος μετασχηματισμός Fourier
Για να γίνει ο υπολογισμός του DFT γρηγορότερος αλγόριθμος FFT αναπτύχθηκε από τους James Cooley και John Tukey. Αυτός ο αλγόριθμος θεωρείται επίσης ένας από τους σημαντικότερους αλγόριθμους του 20ού αιώνα. Χωρίζει ένα σήμα σε ένα περιττό και ζυγό ακολουθία που μειώνει τον αριθμό των απαιτούμενων υπολογισμών. Με τη χρήση του, ο συνολικός απαιτούμενος πολύπλοκος πολλαπλασιασμός μπορεί να μειωθεί σε NlogN. που αποτελεί σημαντική βελτίωση.
Μπορείτε να ανατρέξετε στις παρακάτω αναφορές στις οποίες αναφέρθηκα κατά τη σύνταξη του κώδικα για λεπτομερή κατανόηση των μαθηματικών πίσω από το FFT:
1.
2.
3.
4.
Βήμα 3: Επεξήγηση του κώδικα
1. Fast sine and Cosine:
Υπολογισμός FFT λαμβάνει την τιμή διαφόρων ημιτόνων και συνημίτονων πολλές φορές. Η ενσωματωμένη λειτουργία του Arduino δεν είναι αρκετά γρήγορη και χρειάζεται πολύς χρόνος για να παρέχει την απαιτούμενη τιμή. Αυτό καθιστά τον κώδικα σημαντικά πιο αργό (διπλασιάζει το χρόνο για 64 δείγματα). Για την αντιμετώπιση αυτού του ζητήματος η τιμή του ημιτόνου για 0 έως 90 μοίρες αποθηκεύεται ως πολλαπλή του 255. Με αυτόν τον τρόπο θα εξαλειφθεί η ανάγκη χρήσης αποθήκευσης αριθμών ως float και μπορούμε να τον αποθηκεύσουμε ως byte, ο οποίος καταλαμβάνει το 1/4 του χώρου στο Arduino. Το sine_data πρέπει να επικολληθεί στο επάνω μέρος του κώδικα για να το δηλώσει ως καθολική μεταβλητή.
Εκτός από τα sine_data, ένας πίνακας που ονομάζεται f_peaks δηλώθηκε ως καθολική μεταβλητή. Μετά από κάθε εκτέλεση της λειτουργίας FFT, αυτός ο πίνακας ενημερώνεται. Όπου f_peaks [0] είναι η κυρίαρχη συχνότητα και περαιτέρω τιμές σε φθίνουσα σειρά.
byte sine_data [91] = {0, 4, 9, 13, 18, 22, 27, 31, 35, 40, 44, 49, 53, 57, 62, 66, 70, 75, 79, 83, 87, 91, 96, 100, 104, 108, 112, 116, 120, 124, 127, 131, 135, 139, 143, 146, 150, 153, 157, 160, 164, 167, 171, 174, 177, 180, 183, 186, 189, 192, 195, 198, 201, 204, 206, 209, 211, 214, 216, 219, 221, 223, 225, 227, 229, 231, 233, 235, 236, 238, 240, 241, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, 255} · float f_peaks [5];
Καθώς έχουμε αποθηκεύσει την τιμή του ημιτόνου για 0 έως 90 μοίρες, μπορεί να υπολογιστεί οποιαδήποτε τιμή ημιτόνου ή συνημίτονου. Κάτω από τη λειτουργία ο πρώτος κύκλος του αριθμού σε μηδέν δεκαδικό ψηφίο και η τιμή επιστροφής από τα αποθηκευμένα δεδομένα. αυτή η μέθοδος χρειάζεται μόνο μία κυμαινόμενη διαίρεση. Αυτό μπορεί να μειωθεί περαιτέρω με την απευθείας αποθήκευση τιμών ημιτόνου (όχι 255 πολλαπλάσια). αλλά αυτό τρώει υψηλή μνήμη στο Arduino.
Η χρήση της παραπάνω διαδικασίας μειώνει την ακρίβεια αλλά βελτιώνει την ταχύτητα. Για 64 πόντους, δίνει το πλεονέκτημα των 8ms και για 128 πόντους δίνει πλεονέκτημα 20ms.
Βήμα 4: Επεξήγηση του κώδικα: Λειτουργία FFT
Το FFT μπορεί να εκτελεστεί μόνο για το μέγεθος δείγματος 2, 4, 8, 16, 32, 64 και ούτω καθεξής. αν η τιμή δεν είναι 2^n, τότε θα πάρει την κάτω πλευρά της τιμής. Για παράδειγμα, εάν επιλέξουμε το μέγεθος δείγματος 70 τότε θα λάβει υπόψη μόνο τα πρώτα 64 δείγματα και θα παραλείψει το υπόλοιπο.
Συνιστάται πάντα να έχετε μέγεθος δείγματος 2^n. Το οποίο μπορεί να είναι:
2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, …
Δύο floats out_r και out_im θα χρειαστούν μεγάλη ποσότητα μνήμης. για Arduino nano δεν θα λειτουργήσει για δείγματα υψηλότερα από 128 (και σε ορισμένες περιπτώσεις 128) λόγω έλλειψης διαθέσιμης μνήμης.
ανυπόγραφα δεδομένα int [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
int a, c1, f, o, x; a = N; για (int i = 0; i <12; i ++) // υπολογισμός των επιπέδων {if (data <= a) {o = i;}} int in_ps [data [o] = {}; // είσοδος για αλληλουχία float out_r [data [o] = {}; // πραγματικό μέρος του transform float out_im [data [o] = {}; // φανταστικό μέρος του μετασχηματισμού
Η περαιτέρω ροή έχει ως εξής:
1. Ο κώδικας δημιουργεί λίγο αντίστροφη σειρά για το δεδομένο μέγεθος δείγματος (λεπτομέρειες για την αναστροφή bit σε αναφορές: βήμα 2)
2. Τα δεδομένα εισαγωγής ταξινομούνται σύμφωνα με την παραγόμενη παραγγελία, 3. Πραγματοποιήθηκε FFT
4. Υπολογίζεται το πλάτος του μιγαδικού αριθμού, 5. Οι κορυφές εντοπίζονται και διατάσσονται με φθίνουσα σειρά
6. Μπορείτε να έχετε πρόσβαση στα αποτελέσματα από το f_peaks.
[για πρόσβαση σε άλλα δεδομένα (εκτός από τη μέγιστη συχνότητα) ο κώδικας πρέπει να τροποποιηθεί, έτσι ώστε η τοπική μεταβλητή να μπορεί να αντιγραφεί σε κάποια προκαθορισμένη καθολική μεταβλητή]
Βήμα 5: Δοκιμή του κώδικα
Ένα δείγμα κύματος τριγώνου δίνεται ως είσοδος. για αυτό το κύμα η συχνότητα δειγματοληψίας είναι 10 Hz και η συχνότητα του ίδιου του κύματος είναι 1,25 Hz.
Όπως μπορεί να φανεί από την ακατέργαστη παραγωγή, η τιμή αντιστοιχεί στο FFT που υπολογίζεται από τον Scilab. Ωστόσο, αυτές οι τιμές δεν είναι ακριβώς οι ίδιες με αυτές της χαμηλής ακρίβειας αλλά του ταχύτερου ημιτονοειδούς κύματος.
Στη συχνότητα εξόδου συχνότητα συστοιχίας είναι 1,25 και 3,75. δεν είναι απαραίτητο να λαμβάνετε την ακριβή τιμή κάθε φορά. συνήθως αυτοί οι αριθμοί ονομάζονται κάδοι συχνότητας. έτσι η τιμή εξόδου μπορεί να βρίσκεται οπουδήποτε εντός καθορισμένων κάδων.
Ταχύτητα:
για το Arduino nano χρειάζεται:
16 Πόντοι: 4ms32 Πόντοι: 10ms 64 Πόντοι: 26ms 128 Πόντοι: 53ms
Βήμα 6: Συμπέρασμα
Αυτός ο κώδικας FFT μπορεί να χρησιμοποιηθεί σε εφαρμογές σε πραγματικό χρόνο. Καθώς χρειάζονται περίπου 30 ms για να ολοκληρωθεί ο υπολογισμός. Ωστόσο, η ανάλυση του περιορίζεται από έναν αριθμό δειγμάτων. Ο αριθμός του δείγματος περιορίζεται από τη μνήμη Arduino. Με τη χρήση του Arduino Mega ή άλλης υψηλότερης απόδοσης, η ακρίβεια του πίνακα μπορεί να βελτιωθεί.
εάν έχετε ερωτήσεις, προτάσεις ή διορθώσεις, μη διστάσετε να σχολιάσετε.
Ενημέρωση (2/5/21)
Ενημερώσεις: // ----------------------------- Λειτουργία FFT --------------- ---------------------------------- // float FFT (int in , int N, float Frequency)
Ο τύπος δεδομένων του Ν άλλαξε σε Ακέραιο (υπάρχον Byte) για υποστήριξη> 255 μεγέθους δείγματος. Εάν το μέγεθος του δείγματος είναι <= 128, θα πρέπει να χρησιμοποιηθεί τύπος δεδομένων byte.
Συνιστάται:
Arduino: Frequency Transform (DFT): 6 βήματα
Arduino: Frequency Transform (DFT): αυτό το πρόγραμμα πρέπει να υπολογίζει τον μετασχηματισμό συχνότητας στο arduino με έλεγχο κτύπου στις παραμέτρους. Επιλύεται χρησιμοποιώντας βεβήλωση τέταρτου μετασχηματισμού. αυτό δεν είναι FFT. Ο FFT είναι αλγόριθμος που χρησιμοποιείται για την επίλυση του DFT με μικρότερο χρόνο. Μπορείτε να βρείτε τον κωδικό FFT εδώ
Φασματικό στηθοσκόπιο Fast Hartley Transform: 22 Βήματα
Φασματικό στηθοσκόπιο Fast Hartley Transform: Σε αυτό το διδακτικό θα μάθετε πώς να φτιάχνετε ένα φασματικό στηθοσκόπιο χρησιμοποιώντας τον γρήγορο μετασχηματισμό hartley. Αυτό μπορεί να χρησιμοποιηθεί για να απεικονίσει τους ήχους της καρδιάς και των πνευμόνων
Αισθητήρας θερμοκρασίας για Arduino Εφαρμόστηκε για βήματα COVID 19: 12 (με εικόνες)
Αισθητήρας θερμοκρασίας για Arduino Εφαρμόστηκε για COVID 19: Ο αισθητήρας θερμοκρασίας για το Arduino είναι ένα θεμελιώδες στοιχείο όταν θέλουμε να μετρήσουμε τη θερμοκρασία ενός επεξεργαστή του ανθρώπινου σώματος. Ο αισθητήρας θερμοκρασίας με το Arduino πρέπει να είναι σε επαφή ή κοντά για να λάβει και να μετρήσει το επίπεδο θερμότητας. Έτσι
QuickFFT: Υψηλής ταχύτητας FFT για Arduino: 3 βήματα
QuickFFT: Υψηλής ταχύτητας FFT για Arduino: Το τυπικό Arduino έχει περιορισμένη μνήμη RAM και επεξεργαστική ισχύ και το FFT είναι μια διαδικασία υπολογιστικής έντασης. Για πολλές εφαρμογές σε πραγματικό χρόνο, η μόνη απαίτηση είναι να λάβετε συχνότητα με μέγιστο πλάτος ή απαιτείται για τον εντοπισμό κορυφών συχνότητας. Σε μία από τις
Οδηγός για αρχάριους για τη χρήση αισθητήρων DHT11/ DHT22 W/ Arduino: 9 βήματα
Οδηγός για αρχάριους για τη χρήση αισθητήρων DHT11/ DHT22 W/ Arduino: Μπορείτε να διαβάσετε αυτό και άλλα εκπληκτικά σεμινάρια στον επίσημο ιστότοπο της ElectroPeak Μάθετε: DHT11 και DHT22