2013-04-09 29 views
5

Ho appena collegato un electret microphone a un Arduino, e mi piacerebbe provare tra le gamme di 1   kHz e 4   kHz.Un arduino può campionare l'audio in microsecondi per 1-4 kHz?

Capisco che questo è limitato al codice macchina e allo ADC, quindi sto cercando di mantenere il sketch semplice.

È possibile campionare tra queste frequenze con lo schizzo seguente?

const int analogPin = 0; 
int ledPin = 13; 

void setup() { 
    pinMode(ledPin, OUTPUT); 
} 

void loop() { 
    int mn = 1024; 
    int mx = 0; 
    for (int i = 0; i < 5; ++i) { 
     int val = analogRead(analogPin); 
     mn = min(mn, val); 
     mx = max(mx, val); 
    } 
    if (mx-mn >= 50) { 
     digitalWrite(ledPin, HIGH); 
    } 
    else { 
     digitalWrite(ledPin, LOW); 
    } 
} 
+0

Che tipo di Arduino stai usando? – angelatlarge

risposta

0

ho sentito, o meglio ricordare la lettura, che l'ADC in grado di gestire fino a 10k-campioni al secondo, quindi dovrebbe essere OK fino a 5 kHz  . Tuttavia, non ho provato questo né ho un link per il backup al momento.

Basta provare a vedere.

Ora so che alcune delle funzioni della libreria Arduino sono lente, in particolare DigitalRead/Write che ha un sovraccarico di centinaia di cicli. La maggior parte di questo è il controllo di integrità che consente alle persone di eseguire semplicemente DigitalRead/Write senza pensare molto a come impostare tutto.

Tuttavia, per spremere le massime prestazioni si potrebbe guardare nello scrivere il proprio AnalogRead che è ottimizzato per il vostro caso d'uso.

Almeno alcuni link sull'argomento:

+0

Ho provato la libreria FFT di Neurolecs solo per controllare http://neuroelec.com/2011/03/fft-library-for-arduino/ e quando il laboratorio era silenzioso avevo i seguenti risultati http://i45.tinypic.com/ dfaqts.jpg. Qualche idea su cosa potrebbe essere? Ho anche scollegato il microfono ed è ancora ruvido all'estremità superiore. Potrebbe essere solo rumore dal circuito? – user2119971

+0

Che frequenza hanno questi picchi? Bene quel picco ... –

1

Arduino è una piattaforma di prototipazione costituito da un numero di schede hardware più un livello di astrazione software. Per una domanda come questa, è utile considerare le capacità dell'hardware sottostante, in quanto forniscono i limiti finali. Immagino che tu stia usando Arduino Uno/Nano, la storia è diversa per Due.

Secondo la scheda tecnica, ogni lettura di ADC (oltre la prima) richiede 13 cicli di clock ADC. L'orologio ADC (diverso dall'MCU) viene calcolato dividendo l'orologio di sistema di un fattore, almeno 2. Quindi a 16 Mhz la scheda equivale a 0,6 milioni di campioni al secondo. Fin qui tutto bene. Tuttavia, non è la fine della storia, hai ancora bisogno di leggere i dati. Se si utilizzano gli interrupt, anche se si esegue un'operazione molto semplice, l'esperienza suggerisce che si perderà circa 100 clock per interrompere l'elaborazione. Ora sei giù fino a 126K campioni/secondo. Ma questo è un massimo teorico.

Il foglio dati indica che per la massima precisione per l'ADC è necessario un clock ADC da 50kHz a 200kHz. Nel codice Arduino (in wiring.c), un fattore di divisione di 128 viene scelto:

sbi(ADCSRA, ADPS2); 
sbi(ADCSRA, ADPS1); 
sbi(ADCSRA, ADPS0); 

Ciò significa che ogni conversione occupa 128 * 13 = 1764 orologi, che produce un massimo teorico di 10K campioni al secondo. È un po 'peggio di quello dato che la funzione readAnalog() fa qualcosa oltre a iniziare la conversione di ADC e aspetta che finisca, ma non dovrebbe essere molto peggio. Ciò non implica ovviamente il tuo codice: qualsiasi elaborazione effettuata sui risultati di readAnalog() renderà più difficile acquisire più campioni.Ma sì, per catturare a 4Khz dovrai assicurarti che il tuo codice spenda meno di 1.5k cicli/campioni di clock, il che dovrebbe essere fattibile. Nota che se stai facendo cinque letture come fai nel codice che hai postato, la massima velocità di acquisizione sarà 2kHz se il tuo codice fa veramente poco.


Per quanto riguarda il modo per catturare i dati, è necessario fare l'affare con il fatto che i microfoni senza amplificazione non vi darà 0-5V letture che ci si potrebbe aspettare se si utilizza analogRead(). In effetti, le tensioni di uscita del microfono oscillano da positive a negative, tuttavia, le tensioni negative non vengono rilevate dall'ADC e vengono visualizzate come zero, a meno che non si dia un offset di tensione al microfono.


Non sono esattamente sicuro di cosa stia facendo il codice che confronta l'ampiezza minima con l'ampiezza massima. Vuoi digitalizzare l'audio? In questo caso è necessario salvare tutte le letture dell'ampiezza raccolte da analogRead() e quindi eseguire FFT su di esse su un altro computer: Arduino probabilmente non sarà abbastanza veloce da eseguire analisi di frequenza sui dati.