Offline
Newbie
Karma: 0
Posts: 5
|
 |
« on: November 12, 2012, 06:04:01 pm » |
Salve a tutti, sono un nuovo arrivato appassionato di programmazione ed elettronica. Ultimamente mi sono interessato all' analisi in frequenza di un segnale . Dopo essermi informato ho tentato di utilizzare il mio Arduino Uno con la libreria FFT. Ho provato a utilizzare il programma di esempio che si trova nella libreria per fare alcune prove,collegando alla porta analogica A0 un potenziometro e variando manualmente la tensione. Il programma di esempio dovrebbe mostrare i valori determinati dalla FFT sul monitor seriale ma nel mio caso mostra strane lettere e parentesi che si ripetono ad intermittenza, perchè? Grazie a tutti e scusate l' ignoranza!!!
|
|
|
|
|
Logged
|
|
|
|
|
Marche
Offline
Edison Member
Karma: 25
Posts: 2059
|
 |
« Reply #1 on: November 12, 2012, 06:07:19 pm » |
Posta lo sketch, probabilmente o hai impostato male il baud rate oppure hai inizializzato male la variabile che contiene i valori del potenziometro. Ciao
|
|
|
|
|
Logged
|
|
|
|
|
BZ (I)
Offline
Brattain Member
Karma: 162
Posts: 15732
+39 349 2158303
|
 |
« Reply #2 on: November 12, 2012, 06:35:13 pm » |
il baudrate impostato nel sketch corrisponde con quello impostato nel terminale? Ciao Uwe
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 5
|
 |
« Reply #3 on: November 13, 2012, 07:03:31 am » |
Ecco il codice... #define LOG_OUT 1 // use the log output function #define FFT_N 256 // set to 256 point fft
#include <FFT.h> // include the library
void setup() { Serial.begin(115200); // use the serial port TIMSK0 = 0; // turn off timer0 for lower jitter ADCSRA = 0xe5; // set the adc to free running mode ADMUX = 0x40; // use adc0 DIDR0 = 0x01; // turn off the digital input for adc0 }
void loop() { while(1) { // reduces jitter cli(); // UDRE interrupt slows this way down on arduino1.0 for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples while(!(ADCSRA & 0x10)); // wait for adc to be ready ADCSRA = 0xf5; // restart adc byte m = ADCL; // fetch adc data byte j = ADCH; int k = (j << 8) | m; // form into an int k -= 0x0200; // form into a signed int k <<= 6; // form into a 16b signed int fft_input[i] = k; // put real data into even bins fft_input[i+1] = 0; // set odd bins to 0 } fft_window(); // window the data for better frequency response fft_reorder(); // reorder the data before doing the fft fft_run(); // process the data in the fft fft_mag_log(); // take the output of the fft sei(); Serial.write(255); // send a start byte Serial.write(fft_log_out, 128); // send out the data } }
|
|
|
|
|
Logged
|
|
|
|
|
Battipaglia (SA)
Offline
Jr. Member
Karma: 0
Posts: 52
|
 |
« Reply #4 on: November 13, 2012, 07:13:38 am » |
Lo sketch che hai postato, invia sulla seriale il valore di ciascun byte fft_log_out. Questo array contiene dati binari, non dati ASCII.
Il serial monitor si aspetta che i dati in arrivo siano ASCII. Mi spiego meglio, se vede arrivare un byte = 65 lui stampa la lettera A perchè 65 è il codice ASCII di questa lettera. Nel tuo caso invece il numero 65 che arriva significa proprio 65 cioè il valore numerico.
Probabilmente lo sketch originale da cui sei partito, era fatto per comunicare ad un PC lo spettro calcolato da Arduino tramite la FFT. Ma il programma in ascolto sul PC era scritto ad hoc e si aspettava dati binari.
Un'altra cosa, che non riguarda il problema specifico da te riscontrato. La FFT calcola lo spettro di un segnale analogico, ossia l'ampiezza delle frequenza che lo costituiscono. Se colleghi semplicemente un potenziometro all'ingresso, ho idea che il risultato non sia esattamente quello che ti aspetti. Forse dovresti collegare, per esempio, un segnale audio.
Ciao. Vittorio.
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16479
Don't know what I do
|
 |
« Reply #5 on: November 13, 2012, 07:42:32 am » |
C'è un'altra cosa. Sicuro che quello sketch sia compatibile con l'IDE 1.x? A partire dalla versione 1.0 la seriale viene gestita tramite interrupt, se mandi in stampa dei dati e poi disattivi ed attivi gli interrupt, mi sembra logico che ci siano problemi di trasmissione.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 5
|
 |
« Reply #6 on: November 13, 2012, 06:22:14 pm » |
Grazie a tutti per i consigli!! Ora sto riscrivendo lo sketch ma rileggendo le istruzioni sulla funzione fft_run() ( http://wiki.openmusiclabs.com/wiki/FFTFunctions ), non capisco bene cosa voglia dire che in ingresso sono necessari un blocco di dati già in SRAM. Ecco la bozza del codice: #define LOG_OUT 1 #define FFT_N 256
#include <FFT.h>
void setup() { Serial.begin(115200); }
void loop () { int sensorvoltage = analogRead(A0); float voltage = sensorvoltage * (5.0 / 1023.0); for( int i=0 ; i< 512 ; i += 2) { fft_input[i] = voltage; fft_input[i+1] = 0; } fft_window(); fft_reorder(); fft_run(); fft_mag_log(); Serial.write(255); Serial.write(fft_log_out, 128); } Grazie ancora! 
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16479
Don't know what I do
|
 |
« Reply #7 on: November 14, 2012, 12:22:32 am » |
Non lo so, non so come funzioni quella lib. Parliamo di questa lib? http://code.google.com/p/neuroelec/downloads/listHo visto che esistono 2 versioni, di cui 1 appositamente per l'IDE 1.0 ma che contiene un esempio diverso da quello che hai pubblicato tu. Stiamo parlando della stessa lib? Ma tu quale IDE usi?
|
|
|
|
|
Logged
|
|
|
|
|
Rome (Italy)
Offline
Tesla Member
Karma: 74
Posts: 7372
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #8 on: November 14, 2012, 12:27:07 am » |
Parliamo di questa lib?
Sembra di no, lui sta usando la libreria che si trova sul sito che ha linkato, a quanto pare non è una fft generica, è un caso limitato e di uso ristretto, da quello che ho visto non c'è nemmeno un programma pc per la visualizzazione dei dati ottenuti che sono sotto forma di array binario.
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16479
Don't know what I do
|
 |
« Reply #9 on: November 14, 2012, 12:35:46 am » |
Ma non è che forse spedisce i dati compressi? Mi pare che accenni qualcosa qui: http://wiki.openmusiclabs.com/wiki/ArduinoFFTMa non è che quel sito sia ricco di dettagli.
|
|
|
|
|
Logged
|
|
|
|
|
Battipaglia (SA)
Offline
Jr. Member
Karma: 0
Posts: 52
|
 |
« Reply #10 on: November 14, 2012, 05:22:32 am » |
Scusami, magari mi sbaglio, ma io continuo a pensare che ci sia un problema di fondo che avevo già accennato nel mio primo intervento.
Cerco di fare un brevissimo riassunto sulla trasformata per capirci. Magari sarà anche molto approssimativo dal punto di vista matematico perchè si tratta di reminiscenze universitarie.
La trasformata di Fourier consente scomporre un segnale complesso nelle componenti sinusoidali (ossia le loro frequenze) che lo compongono determinando l'ampiezza di ciascuna di esse.
Partiamo da un segnale campionato con una frequenza Fc. Questo significa che abbiamo acquisito N campioni ciascuno ad un intervallo di tempo pari a 1/Fc secondi. Il teorema fondamentale del campionamento afferma che Fc deve essere maggiore o uguale del doppio della massima frequenza contenuta nel segnale da campionare. Quindi, se stiamo campionando una voce umana (che va da 500Hz a 2 KHz) dobbiamo campionare almeno a 4 Khz cioè 4000 campioni al secondo.
Questi campioni costituiscono il tuo vettore di input ossia fft_input. Il calcolo della FFT ti restituisce un nuovo vettore in cui la metà dei valori rappresenta l'ampiezza di N/2 (N erano il numero di campioni) sinusoidi che compongono il segnale originale. Il primo valore è l'ampiezza della componente continua, il valore all'indice N/2 è il valore della massima frequenza campionabile (nel nostro esempio 2KHz), i valori intermedi sono equispaziati. Se avessimo raccolto 1024 campioni (la FFT funziona con un numero di campioni pari ad una potenza di 2) allora il valore all'indice 512 rappresenta l'ampiezza della sinusoide a 2KHz i valori precedenti rappresentano l'ampiezza delle sinusoidi di frequenza pari a 0Hz (componente continua del segnale), 3.8Hz, 7.6Hz, 11.4Hz e così via.
Nel tuo caso, stai campionando un segnale continuo ossia il valore della tensione presente sul centrale del potenziometro. Mi aspetto quindi che in output tu ottenga un unico valore diverso da zero e cioè il primo valore del vettore di output che, come detto, rappresenta l'ampiezza della componente continua del segnale di ingresso.
Scusami per la lunghezza dell'intervento... alla fine la domanda è: ma cosa devi fare? Se ce lo dici forse riusciamo a ragionare insieme sulla implementazione.
Ciao. Vittorio.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 5
|
 |
« Reply #11 on: November 14, 2012, 06:00:45 am » |
Ora rispondo a tutte le domande 1) L' IDE che sto usando è 1.0.1 ma credo che la libreria del sito http://code.google.com/p/neuroelec/downloads/detail?name=ffft_Library.zip&can=2&q= sia solo per 1.0 2) il mio progetto è quello di costruire un analizzatore di campi magnetici che attraverso una sonda di hall mi determini l' intensità del campo e la frequenza delle onde magnetiche. Per la determinazione dell' intensità del campo non penso di avere problemi, ma per portare il segnale dal dominio del tempo a quello della frequenza è necessario utilizzare la FFT sulle differenti tensioni inviate dalla sonda di hall ad Arduino. Grazie ancora per tutti questi consigli 
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16479
Don't know what I do
|
 |
« Reply #12 on: November 14, 2012, 06:05:44 am » |
Tra 1.0 e 1.0.1 cambia poco. 2) il mio progetto è quello di costruire un analizzatore di campi magnetici che attraverso una sonda di hall mi determini l' intensità del campo e la frequenza delle onde magnetiche. Per la determinazione dell' intensità del campo non penso di avere problemi, ma per portare il segnale dal dominio del tempo a quello della frequenza è necessario utilizzare la FFT sulle differenti tensioni inviate dalla sonda di hall ad Arduino. Grazie ancora per tutti questi consigli  Non so se ti può tornare utile, ma l'autore ha sviluppato una nuova lib che dice essere può performante della FFT, la FHT. Forse, essendo rivista e più recente, ha meno problemi.
|
|
|
|
|
Logged
|
|
|
|
|
Rome (Italy)
Offline
Tesla Member
Karma: 74
Posts: 7372
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #13 on: November 14, 2012, 06:14:36 am » |
Nel tuo caso, stai campionando un segnale continuo ossia il valore della tensione presente sul centrale del potenziometro. Mi aspetto quindi che in output tu ottenga un unico valore diverso da zero e cioè il primo valore del vettore di output che, come detto, rappresenta l'ampiezza della componente continua del segnale di ingresso.
Quoto al 100%, infatti iniettando sul ADC una tensione continua, invece di un segnale che varia nel tempo, in uscita dalla FFT ottieni solo un valore costante.
|
|
|
|
|
Logged
|
|
|
|
|
Rome (Italy)
Offline
Tesla Member
Karma: 74
Posts: 7372
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #14 on: November 14, 2012, 06:18:57 am » |
sulle differenti tensioni inviate dalla sonda di hall ad Arduino.
Non tensioni, ma segnale che varia nel tempo in ampiezza e in frequenza altrimenti la FFT non serve nulla.
|
|
|
|
|
Logged
|
|
|
|
|
|