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

1024 δείγματα FFT Spectrum Analyzer Χρησιμοποιώντας βήματα Atmega1284: 9
1024 δείγματα FFT Spectrum Analyzer Χρησιμοποιώντας βήματα Atmega1284: 9

Βίντεο: 1024 δείγματα FFT Spectrum Analyzer Χρησιμοποιώντας βήματα Atmega1284: 9

Βίντεο: 1024 δείγματα FFT Spectrum Analyzer Χρησιμοποιώντας βήματα Atmega1284: 9
Βίντεο: Εργαστηριακή άσκηση 12: Ταχύς Μ/Σ Fourier 2024, Ιούλιος
Anonim
1024 Δείγματα FFT Spectrum Analyzer χρησιμοποιώντας ένα Atmega1284
1024 Δείγματα FFT Spectrum Analyzer χρησιμοποιώντας ένα Atmega1284
1024 Δείγματα FFT Spectrum Analyzer χρησιμοποιώντας ένα Atmega1284
1024 Δείγματα FFT Spectrum Analyzer χρησιμοποιώντας ένα Atmega1284

Αυτό το σχετικά εύκολο σεμινάριο (λαμβάνοντας υπόψη την πολυπλοκότητα αυτού του θέματος) θα σας δείξει πώς μπορείτε να φτιάξετε έναν πολύ απλό αναλυτή φάσματος 1024 δειγμάτων χρησιμοποιώντας έναν πίνακα τύπου Arduino (1284 Narrow) και τον σειριακό σχεδιαστή. Οποιοδήποτε είδος συμβατού πίνακα Arduino θα κάνει, αλλά όσο περισσότερη RAM έχει, τόσο καλύτερη ανάλυση συχνότητας θα έχετε. Θα χρειαστούν περισσότερα από 8 KB RAM για τον υπολογισμό του FFT με 1024 δείγματα.

Η ανάλυση φάσματος χρησιμοποιείται για τον προσδιορισμό των κύριων συστατικών συχνοτήτων ενός σήματος. Πολλοί ήχοι (όπως αυτοί που παράγονται από ένα μουσικό όργανο) αποτελούνται από μια θεμελιώδη συχνότητα και μερικές αρμονικές που έχουν μια συχνότητα που είναι ακέραιο πολλαπλάσιο της θεμελιώδους συχνότητας. Ο αναλυτής φάσματος θα σας δείξει όλα αυτά τα φασματικά στοιχεία.

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

Θα εστιάσουμε εδώ στο κομμάτι του λογισμικού. Εάν θέλετε να δημιουργήσετε ένα μόνιμο κύκλωμα για μια συγκεκριμένη εφαρμογή, θα πρέπει να ενισχύσετε και να φιλτράρετε το σήμα. Αυτή η προ-προετοιμασία εξαρτάται πλήρως από το σήμα που θέλετε να μελετήσετε, ανάλογα με το πλάτος, τη σύνθετη αντίσταση, τη μέγιστη συχνότητα κλπ… Μπορείτε να ελέγξετε

Βήμα 1: Εγκατάσταση της βιβλιοθήκης

Θα χρησιμοποιήσουμε τη βιβλιοθήκη ArduinoFFT γραμμένη από τον Enrique Condes. Δεδομένου ότι θέλουμε να εξοικονομήσουμε RAM όσο το δυνατόν περισσότερο, θα χρησιμοποιήσουμε τον κλάδο ανάπτυξης αυτού του αποθετηρίου που επιτρέπει τη χρήση του τύπου float data (αντί του διπλού) για την αποθήκευση των δειγμάτων και των υπολογισμένων δεδομένων. Πρέπει λοιπόν να το εγκαταστήσουμε χειροκίνητα. Μην ανησυχείτε, απλώς κατεβάστε το αρχείο και αποσυμπιέστε το στο φάκελο βιβλιοθήκης Arduino (για παράδειγμα στις προεπιλεγμένες ρυθμίσεις των Windows 10: C: / Users / _your_user_name_ / Documents / Arduino / βιβλιοθήκες)

Μπορείτε να ελέγξετε ότι η βιβλιοθήκη είναι σωστά εγκατεστημένη, συγκεντρώνοντας ένα από τα παραδείγματα που παρέχονται, όπως "FFT_01.ino."

Βήμα 2: Fourier Transform και FFT Concepts

Προειδοποίηση: αν δεν αντέχετε να βλέπετε κάποιο μαθηματικό συμβολισμό, ίσως θελήσετε να μεταβείτε στο Βήμα 3. Τέλος πάντων, αν δεν τα καταλάβετε όλα, απλώς εξετάστε το συμπέρασμα στο τέλος της ενότητας.

Το φάσμα συχνοτήτων λαμβάνεται μέσω ενός αλγορίθμου Fast Fourier Transform. Το FFT είναι μια ψηφιακή εφαρμογή που προσεγγίζει τη μαθηματική έννοια του μετασχηματισμού Fourier. Κάτω από αυτήν την έννοια μόλις λάβετε την εξέλιξη ενός σήματος ακολουθώντας έναν άξονα χρόνου, μπορείτε να γνωρίζετε την αναπαράστασή του σε έναν τομέα συχνοτήτων, που αποτελείται από πολύπλοκες (πραγματικές + φανταστικές) τιμές. Η έννοια είναι αμοιβαία, οπότε όταν γνωρίζετε την αναπαράσταση του πεδίου συχνότητας μπορείτε να την μετατρέψετε πίσω στον τομέα του χρόνου και να λάβετε το σήμα πίσω ακριβώς όπως πριν από τον μετασχηματισμό.

Τι θα κάνουμε όμως με αυτό το σύνολο υπολογισμένων σύνθετων τιμών στον τομέα χρόνου; Λοιπόν, το μεγαλύτερο μέρος θα αφεθεί στους μηχανικούς. Για εμάς θα καλέσουμε έναν άλλο αλγόριθμο που θα μετατρέψει αυτές τις πολύπλοκες τιμές σε δεδομένα φασματικής πυκνότητας: δηλαδή μια τιμή μεγέθους (= έντασης) που σχετίζεται με κάθε ζώνη συχνοτήτων. Ο αριθμός της ζώνης συχνοτήτων θα είναι ο ίδιος με τον αριθμό των δειγμάτων.

Είστε σίγουρα εξοικειωμένοι με την ιδέα του ισοσταθμιστή, όπως αυτή Επιστροφή στη δεκαετία του 1980 Με το Graphic EQ. Λοιπόν, θα έχουμε τα ίδια αποτελέσματα, αλλά με 1024 ζώνες αντί για 16 και πολύ μεγαλύτερη ανάλυση έντασης. Όταν ο ισοσταθμιστής δίνει μια παγκόσμια εικόνα της μουσικής, η λεπτή φασματική ανάλυση επιτρέπει τον ακριβή υπολογισμό της έντασης κάθε μιας από τις 1024 μπάντες.

Μια τέλεια ιδέα, αλλά:

  1. Δεδομένου ότι το FFT είναι μια ψηφιοποιημένη έκδοση του μετασχηματισμού Fourier, προσεγγίζει το ψηφιακό σήμα και χάνει ορισμένες πληροφορίες. Έτσι, αυστηρά μιλώντας, το αποτέλεσμα του FFT αν μετατραπεί πίσω με έναν ανεστραμμένο αλγόριθμο FFT δεν θα έδινε ακριβώς το αρχικό σήμα.
  2. Επίσης η θεωρία θεωρεί ένα σήμα που δεν είναι πεπερασμένο, αλλά αυτό είναι ένα διαρκές σταθερό σήμα. Δεδομένου ότι θα το ψηφιοποιήσουμε μόνο για ορισμένο χρονικό διάστημα (δηλ. Δείγματα), θα εισαχθούν μερικά ακόμη σφάλματα.
  3. Τέλος, η ανάλυση της αναλογικής σε ψηφιακή μετατροπή θα επηρεάσει την ποιότητα των υπολογισμένων τιμών.

Στην πράξη

1) Η συχνότητα δειγματοληψίας (σημειώνεται fs)

Θα λαμβάνουμε δείγμα από ένα σήμα, δηλαδή μετράμε το πλάτος του, κάθε 1/fs δευτερόλεπτα. fs είναι η συχνότητα δειγματοληψίας. Για παράδειγμα, αν κάνουμε δειγματοληψία στα 8 KHz, το ADC (μετατροπέας αναλογικού σε ψηφιακό) που βρίσκεται στο τσιπ θα παρέχει μια μέτρηση κάθε 1/8000 δευτερόλεπτα.

2) Ο αριθμός των δειγμάτων (σημειώνεται Ν ή δείγματα στον κωδικό)

Δεδομένου ότι πρέπει να λάβουμε όλες τις τιμές πριν εκτελέσουμε το FFT θα πρέπει να τις αποθηκεύσουμε και έτσι θα περιορίσουμε τον αριθμό των δειγμάτων. Ο αλγόριθμος FFT χρειάζεται έναν αριθμό δειγμάτων που έχουν ισχύ 2. Όσο περισσότερα δείγματα έχουμε τόσο το καλύτερο αλλά χρειάζεται πολλή μνήμη, τόσο περισσότερο που θα χρειαστεί επίσης για την αποθήκευση των μετασχηματισμένων δεδομένων, που είναι πολύπλοκες τιμές. Η βιβλιοθήκη Arduino FFT εξοικονομεί χώρο χρησιμοποιώντας

  • Ένας πίνακας με το όνομα "vReal" για την αποθήκευση των δειγματοληπτικών δεδομένων και στη συνέχεια το πραγματικό μέρος των μετασχηματισμένων δεδομένων
  • Ένας πίνακας που ονομάζεται "vImag" για να αποθηκεύσει το φανταστικό μέρος των μετασχηματισμένων δεδομένων

Η απαιτούμενη ποσότητα RAM είναι 2 (πίνακες) * 32 (bits) * N (δείγματα).

Έτσι, στο Atmega1284 που έχει ωραία μνήμη RAM 16 KB θα αποθηκεύσουμε το πολύ N = 16000*8 /64 = 2000 τιμές. Δεδομένου ότι ο αριθμός των τιμών πρέπει να είναι δύναμη 2, θα αποθηκεύσουμε το πολύ 1024 τιμές.

3) Η ανάλυση συχνότητας

Το FFT θα υπολογίσει τιμές για όσες ζώνες συχνοτήτων είναι ο αριθμός των δειγμάτων. Αυτές οι ζώνες θα εκτείνονται από 0 HZ έως τη συχνότητα δειγματοληψίας (fs). Ως εκ τούτου, η ανάλυση συχνότητας είναι:

Ανάλυση = fs / N

Η ανάλυση είναι καλύτερη όταν είναι χαμηλότερη. Έτσι για καλύτερη ανάλυση (χαμηλότερη) θέλουμε:

  • περισσότερα δείγματα και/ή
  • ένα χαμηλότερο fs

Αλλά…

4) Ελάχιστα fs

Δεδομένου ότι θέλουμε να δούμε πολλές συχνότητες, μερικές από αυτές είναι πολύ υψηλότερες από τη "θεμελιώδη συχνότητα", δεν μπορούμε να θέσουμε fs πολύ χαμηλά. Στην πραγματικότητα υπάρχει το θεώρημα δειγματοληψίας Nyquist -Shannon που μας αναγκάζει να έχουμε μια συχνότητα δειγματοληψίας πολύ μεγαλύτερη από τη διπλάσια από τη μέγιστη συχνότητα που θα θέλαμε να δοκιμάσουμε.

Για παράδειγμα, αν θέλουμε να αναλύσουμε όλο το φάσμα από 0 Hz έως 15 KHz, που είναι περίπου η μέγιστη συχνότητα που οι περισσότεροι άνθρωποι μπορούν να ακούσουν ευδιάκριτα, πρέπει να ορίσουμε τη συχνότητα δειγματοληψίας στα 30 KHz. Στην πραγματικότητα οι ηλεκτρονικοί συχνά το θέτουν σε 2,5 (ή και 2,52) * τη μέγιστη συχνότητα. Σε αυτό το παράδειγμα αυτό θα ήταν 2,5 * 15 KHz = 37,5 KHz. Οι συνηθισμένες συχνότητες δειγματοληψίας στον επαγγελματικό ήχο είναι 44,1 KHz (εγγραφή CD ήχου), 48 KHz και περισσότερες.

Συμπέρασμα:

Τα σημεία 1 έως 4 οδηγούν στο: θέλουμε να χρησιμοποιήσουμε όσο το δυνατόν περισσότερα δείγματα. Στην περίπτωσή μας με συσκευή RAM 16 KB θα εξετάσουμε 1024 δείγματα. Θέλουμε να κάνουμε δειγματοληψία στη χαμηλότερη δυνατή συχνότητα δειγματοληψίας, αρκεί να είναι αρκετά υψηλή για να αναλύσουμε την υψηλότερη συχνότητα που περιμένουμε στο σήμα μας (2,5 * αυτή η συχνότητα, τουλάχιστον).

Βήμα 3: Προσομοίωση σήματος

Προσομοίωση σήματος
Προσομοίωση σήματος

Για την πρώτη μας προσπάθεια, θα τροποποιήσουμε ελαφρώς το παράδειγμα TFT_01.ino που δίνεται στη βιβλιοθήκη, για να αναλύσουμε ένα σήμα που αποτελείται από

  • Η βασική συχνότητα, ρυθμισμένη στα 440 Hz (μουσικό Α)
  • 3η αρμονική στο μισό της ισχύος του θεμελιώδους ("-3 dB")
  • 5η αρμονική στο 1/4 της ισχύος του θεμελιώδους ("-6 dB)

Μπορείτε να δείτε στην παραπάνω εικόνα το σήμα που προκύπτει. Μοιάζει όντως πολύ με ένα πραγματικό σήμα που μπορεί κανείς να δει σε έναν παλμογράφο (θα το έλεγα "Batman") σε μια κατάσταση όταν υπάρχει ένα απόκομμα ημιτονοειδούς σήματος.

Βήμα 4: Ανάλυση προσομοιωμένου σήματος - Κωδικοποίηση

0) Συμπεριλάβετε τη βιβλιοθήκη

#include "arduinoFFT.h"

1) Ορισμοί

Στις ενότητες δηλώσεων, έχουμε

const byte adcPin = 0; // A0

const uint16_t δείγματα = 1024; // Αυτή η τιμή ΠΡΕΠΕΙ να είναι ΠΑΝΤΑ δύναμη 2 const uint16_t samplingFrequency = 8000; // Θα επηρεάσει τη μέγιστη τιμή του χρονοδιακόπτη στο timer_setup () SYSCLOCK/8/samplingΗ συχνότητα θα πρέπει να είναι ακέραιος

Δεδομένου ότι το σήμα έχει 5η αρμονική (συχνότητα αυτής της αρμονικής = 5 * 440 = 2200 Hz) πρέπει να ορίσουμε τη συχνότητα δειγματοληψίας πάνω από 2,5 * 2200 = 5500 Hz. Εδώ επέλεξα 8000 Hz.

Δηλώνουμε επίσης τους πίνακες όπου θα αποθηκεύσουμε τα ακατέργαστα και υπολογισμένα δεδομένα

float vReal [δείγματα]?

float vImag [δείγματα]?

2) Υλοποίηση

Δημιουργούμε ένα αντικείμενο ArduinoFFT. Η έκδοση dev του ArduinoFFT χρησιμοποιεί ένα πρότυπο, ώστε να μπορούμε να χρησιμοποιήσουμε είτε τον float είτε τον διπλό τύπο δεδομένων. Το Float (32 bit) είναι αρκετό σε σχέση με τη συνολική ακρίβεια του προγράμματός μας.

ArduinoFFT FFT = ArduinoFFT (vReal, vImag, δείγματα, samplingFrequency);

3) Προσομοίωση του σήματος συμπληρώνοντας τον πίνακα vReal, αντί να το συμπληρώσετε με τιμές ADC.

Στην αρχή του βρόχου συμπληρώνουμε τον πίνακα vReal με:

float cycles = (((δείγματα) * signalFrequency) / samplingFrequency)? // Αριθμός κύκλων σήματος που θα διαβάσει η δειγματοληψία

για (uint16_t i = 0; i <δείγματα; i ++) {vReal = float ((πλάτος * (sin ((i * (TWO_PI * κύκλοι))) / δείγματα)))) / / * Δημιουργία δεδομένων με θετικά και αρνητικές τιμές */ vReal += float ((εύρος * (sin ((3 * i * (TWO_PI * κύκλοι))/ δείγματα)))/ 2.0);/ * Δημιουργία δεδομένων με θετικές και αρνητικές τιμές */ vReal += float ((πλάτος * (sin ((5 * i * (TWO_PI * κύκλοι))) / δείγματα))) / 4.0); / * Δημιουργία δεδομένων με θετικές και αρνητικές τιμές * / vImag = 0.0 ? // Το φανταστικό μέρος πρέπει να μηδενιστεί σε περίπτωση βρόχου για να αποφευχθούν λάθος υπολογισμοί και υπερχειλίσεις}

Προσθέτουμε μια ψηφιοποίηση του θεμελιώδους κύματος και των δύο αρμονικών με μικρότερο πλάτος. Στη συνέχεια, αρχικοποιούμε τον φανταστικό πίνακα με μηδενικά. Δεδομένου ότι αυτός ο πίνακας συμπληρώνεται από τον αλγόριθμο FFT, πρέπει να τον καθαρίσουμε ξανά πριν από κάθε νέο υπολογισμό.

4) Υπολογισμός FFT

Στη συνέχεια υπολογίζουμε το FFT και τη φασματική πυκνότητα

FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward);

FFT.compute (FFTDirection:: Forward); / * Compute FFT */ FFT.complexToMagnitude (); / * Υπολογισμός μεγεθών */

Η λειτουργία FFT.windowing (…) τροποποιεί τα ακατέργαστα δεδομένα επειδή εκτελούμε το FFT σε περιορισμένο αριθμό δειγμάτων. Το πρώτο και το τελευταίο δείγμα παρουσιάζουν ασυνέχεια (δεν υπάρχει "τίποτα" στη μία πλευρά τους). Αυτό είναι πηγή λάθους. Η λειτουργία "παραθύρων" τείνει να μειώσει αυτό το σφάλμα.

Το FFT.compute (…) με την κατεύθυνση "Εμπρός" υπολογίζει τον μετασχηματισμό από τον τομέα χρόνου στον τομέα συχνοτήτων.

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

5) Σειριακό σχέδιο plotter

Ας εκτυπώσουμε τις τιμές στο σειριακό σχεδιαστή καλώντας τη συνάρτηση printVector (…)

PrintVector (vReal, (δείγματα >> 1), SCL_FREQUENCY);

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

Εκτυπώνουμε επίσης τη συχνότητα της ζώνης που έχει την υψηλότερη τιμή μεγέθους

float x = FFT.majorPeak ();

Serial.print ("f0 ="); Serial.print (x, 6); Serial.println ("Hz");

Βήμα 5: Ανάλυση προσομοιωμένου σήματος - Αποτελέσματα

Ανάλυση προσομοιωμένου σήματος - Αποτελέσματα
Ανάλυση προσομοιωμένου σήματος - Αποτελέσματα

Βλέπουμε 3 αιχμές που αντιστοιχούν στη θεμελιώδη συχνότητα (f0), την 3η και την 5η αρμονική, με το μισό και το 1/4 του μεγέθους f0, όπως ήταν αναμενόμενο. Μπορούμε να διαβάσουμε στο πάνω μέρος του παραθύρου f0 = 440.430114 Hz. Αυτή η τιμή δεν είναι ακριβώς 440 Hz, για όλους τους λόγους που εξηγήθηκαν παραπάνω, αλλά είναι πολύ κοντά στην πραγματική τιμή. Δεν ήταν πραγματικά απαραίτητο να δείξουμε τόσα ασήμαντα δεκαδικά.

Βήμα 6: Ανάλυση πραγματικού σήματος - Καλωδίωση του ADC

Ανάλυση πραγματικού σήματος - Καλωδίωση του ADC
Ανάλυση πραγματικού σήματος - Καλωδίωση του ADC

Δεδομένου ότι γνωρίζουμε πώς να προχωρήσουμε στη θεωρία, θα θέλαμε να αναλύσουμε ένα πραγματικό σήμα.

Η καλωδίωση είναι πολύ απλή. Συνδέστε τη γείωση μαζί και τη γραμμή σήματος στον ακροδέκτη A0 της πλακέτας σας μέσω μιας αντίστασης σειράς με τιμή 1 KOhm έως 10 KOhm.

Αυτή η αντίσταση σειράς θα προστατεύσει την αναλογική είσοδο και θα αποφύγει το κουδούνισμα. Πρέπει να είναι όσο το δυνατόν υψηλότερο για να αποφεύγεται ο ήχος και όσο το δυνατόν χαμηλότερα για να παρέχει αρκετό ρεύμα για να φορτίζει γρήγορα το ADC. Ανατρέξτε στο φύλλο δεδομένων MCU για να μάθετε την αναμενόμενη σύνθετη αντίσταση του σήματος που συνδέεται στην είσοδο ADC.

Για αυτό το demo χρησιμοποίησα μια γεννήτρια λειτουργίας για να τροφοδοτήσω ένα ημιτονοειδές σήμα συχνότητας 440 Hz και πλάτους περίπου 5 βολτ (είναι καλύτερο εάν το πλάτος είναι μεταξύ 3 και 5 βολτ, ώστε το ADC να χρησιμοποιείται σχεδόν σε πλήρη κλίμακα), μέσω αντίστασης 1,2 KOhm Το

Βήμα 7: Ανάλυση πραγματικού σήματος - Κωδικοποίηση

0) Συμπεριλάβετε τη βιβλιοθήκη

#include "arduinoFFT.h"

1) Δηλώσεις και εγκατάσταση

Στην ενότητα δήλωσης ορίζουμε την είσοδο ADC (A0), τον αριθμό δειγμάτων και τη συχνότητα δειγματοληψίας, όπως στο προηγούμενο παράδειγμα.

const byte adcPin = 0; // A0

const uint16_t δείγματα = 1024; // Αυτή η τιμή ΠΡΕΠΕΙ να είναι ΠΑΝΤΑ δύναμη 2 const uint16_t samplingFrequency = 8000; // Θα επηρεάσει τη μέγιστη τιμή του χρονοδιακόπτη στο timer_setup () SYSCLOCK/8/samplingΗ συχνότητα θα πρέπει να είναι ακέραιος αριθμός

Δημιουργούμε το αντικείμενο ArduinoFFT

ArduinoFFT FFT = ArduinoFFT (vReal, vImag, δείγματα, samplingFrequency);

2) Ρύθμιση χρονοδιακόπτη και ADC

Ρυθμίζουμε τον χρονοδιακόπτη 1 ώστε να κάνει κύκλους στη συχνότητα δειγματοληψίας (8 KHz) και αυξάνει τη διακοπή στην σύγκριση εξόδου.

void timer_setup () {

// επαναφορά χρονοδιακόπτη 1 TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; TCCR1B = bit (CS11) | bit (WGM12); // CTC, prescaler 8 TIMSK1 = bit (OCIE1B); OCR1A = ((16000000 /8) / samplingFrequency) -1; }

Και ρυθμίστε το ADC έτσι

  • Χρησιμοποιεί το A0 ως είσοδο
  • Ενεργοποιεί αυτόματα σε κάθε έξοδο χρονοδιακόπτη 1 σύγκριση αντιστοίχισης Β
  • Δημιουργεί μια διακοπή όταν ολοκληρωθεί η μετατροπή

Το ρολόι ADC ορίζεται σε 1 MHz, με προεπιλογή του ρολογιού συστήματος (16 MHz) κατά 16. Δεδομένου ότι κάθε μετατροπή διαρκεί περίπου 13 ρολόγια σε πλήρη κλίμακα, οι μετατροπές μπορούν να επιτευχθούν με συχνότητα 1/13 = 0,076 MHz = 76 KHz. Η συχνότητα δειγματοληψίας πρέπει να είναι σημαντικά χαμηλότερη από 76 KHz για να αφήσει το ADC να έχει το χρόνο να δοκιμάσει τα δεδομένα. (επιλέξαμε fs = 8 KHz).

void adc_setup () {

ADCSRA = bit (ADEN) | bit (ADIE) | bit (ADIF); // ενεργοποιήστε το ADC, θέλετε διακοπή κατά την ολοκλήρωση ADCSRA | = bit (ADPS2); // Προσωματοποιητής 16 ADMUX = bit (REFS0) | (adcPin & 7); // ρύθμιση της εισόδου ADC ADCSRB = bit (ADTS0) | bit (ADTS2); // Χρονοδιακόπτης/Μετρητής1 Σύγκριση πηγής σκανδάλης αντιστοίχισης Β ADCSRA | = bit (ADATE); // ενεργοποιήστε την αυτόματη ενεργοποίηση}

Δηλώνουμε τον χειριστή διακοπών που θα καλείται μετά από κάθε μετατροπή ADC για αποθήκευση των μετατρεπόμενων δεδομένων στον πίνακα vReal και εκκαθάριση της διακοπής

// Πλήρες ISR ADC

ISR (ADC_vect) {vReal [resultNumber ++] = ADC; εάν (resultNumber == δείγματα) {ADCSRA = 0? // απενεργοποίηση ADC}} EMPTY_INTERRUPT (TIMER1_COMPB_vect);

Μπορείτε να έχετε μια εξαντλητική εξήγηση σχετικά με τη μετατροπή ADC στο Arduino (analogRead).

3) Ρύθμιση

Στη συνάρτηση ρύθμισης καθαρίζουμε τον φανταστικό πίνακα δεδομένων και καλούμε το χρονόμετρο και τις λειτουργίες ρύθμισης ADC

μηδέν (); // μια συνάρτηση που ορίζει στο 0 όλα τα φανταστικά δεδομένα - εξηγείται στην προηγούμενη ενότητα

timer_setup (); adc_setup ();

3) Βρόχος

FFT.dcRemoval (); // Αφαιρέστε το στοιχείο DC αυτού του σήματος, επειδή το ADC αναφέρεται στη γείωση

FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward); // Ζυγίστε δεδομένα FFT.compute (FFTDirection:: Forward); // Υπολογισμός FFT FFT.complexToMagnitude (); // Υπολογισμός μεγεθών // εκτύπωση του φάσματος και της θεμελιώδους συχνότητας f0 PrintVector (vReal, (δείγματα >> 1), SCL_FREQUENCY); float x = FFT.majorPeak (); Serial.print ("f0 ="); Serial.print (x, 6); Serial.println ("Hz");

Αφαιρούμε το εξάρτημα DC επειδή το ADC αναφέρεται στη γείωση και το σήμα κεντράρεται περίπου στα 2,5 βολτ περίπου.

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

Βήμα 8: Ανάλυση πραγματικού σήματος - Αποτελέσματα

Ανάλυση πραγματικού σήματος - Αποτελέσματα
Ανάλυση πραγματικού σήματος - Αποτελέσματα

Πράγματι, βλέπουμε μόνο μία συχνότητα σε αυτό το απλό σήμα. Η υπολογισμένη θεμελιώδης συχνότητα είναι 440.118194 Hz. Και πάλι εδώ η τιμή είναι μια πολύ στενή προσέγγιση της πραγματικής συχνότητας.

Βήμα 9: Τι γίνεται με ένα κομμένο ημιτονοειδές σήμα;

Τι γίνεται με ένα κομμένο ημιτονοειδές σήμα
Τι γίνεται με ένα κομμένο ημιτονοειδές σήμα

Τώρα ας ξεπεράσουμε λίγο το ADC αυξάνοντας το πλάτος του σήματος πάνω από 5 βολτ, οπότε κόβεται. Μην πιέζετε πολύ για να μην καταστρέψετε την είσοδο ADC!

Μπορούμε να δούμε κάποιες αρμονικές να εμφανίζονται. Η αποκοπή του σήματος δημιουργεί εξαρτήματα υψηλής συχνότητας.

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

Συνιστάται: