Pages: [1] 2   Go Down
Author Topic: Problema con la libreria FFT  (Read 1690 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Edison Member
*
Karma: 33
Posts: 2265
azioni semplici per risultati complessi
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Brattain Member
*****
Karma: 258
Posts: 21502
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

il baudrate impostato nel sketch corrisponde con quello impostato nel terminale?
Ciao Uwe
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ecco il codice...

Code:
#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 Offline
Jr. Member
**
Karma: 0
Posts: 70
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22658
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
 
Code:
#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!  smiley-grin
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22658
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Non lo so, non so come funzioni quella lib.
Parliamo di questa lib?
http://code.google.com/p/neuroelec/downloads/list
Ho 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 Offline
Tesla Member
***
Karma: 125
Posts: 9334
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22658
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ma non è che forse spedisce i dati compressi?
Mi pare che accenni qualcosa qui:
http://wiki.openmusiclabs.com/wiki/ArduinoFFT
Ma non è che quel sito sia ricco di dettagli.

Logged


Battipaglia (SA)
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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  smiley-lol
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22658
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Tra 1.0 e 1.0.1 cambia poco.

Quote
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  smiley-lol
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 Offline
Tesla Member
***
Karma: 125
Posts: 9334
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Tesla Member
***
Karma: 125
Posts: 9334
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1] 2   Go Up
Jump to: