Lo sketch Arduino e' interessante perche' non si tratta di leggere solo l'input A0 ma inserisce un bel po' di trucchetti come mandare l'ADC in modalita' free running per velocizzare al massimo il campionamento
-----------------------
/*
fht_adc.pde
guest openmusiclabs.com 9.5.12
example sketch for testing the fht library.
it takes in data on ADC0 (Analog0) and processes them
with the fht. the data is sent out over the serial
port at 115.2kb. there is a pure data patch for
visualizing the data.
*/
#define LOG_OUT 1 // use the log output function
#define FHT_N 256 // set to 256 point fht
#include <FHT.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 < FHT_N ; i++) { // 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
fht_input[i] = k; // put real data into bins
}
fht_window(); // window the data for better frequency response
fht_reorder(); // reorder the data before doing the fht
fht_run(); // process the data in the fht
fht_mag_log(); // take the output of the fht
sei();
Serial.write(255); // send a start byte
Serial.write(fht_log_out, FHT_N/2); // send out the data
}
}
-----------------------ci sono diversi tipi di rappresentazione del risultati (nell'esempio viene indicata la rappresentazione logaritmica).
La rappresentazione del formato di output e' descritta qui. In pratica nel caso in esempio sono sequenze di 256 byte in cui ciascuno rappresenta una suddivisione dello spettro di frequenze
Per calcolare quanto e' ampio un intervallo si deve conoscere il passo di campionamento secondo la regola
- Frequency(k) = (k)*(sample_rate)/(FHT_N)
Per modificare il passo di campionamento e' sufficiente lavorare sul valore di prescaler del convertitore analogico digitale
Di default il prescaler di ADC e' impostato a 128 il che porta ad un passo di campionamento di 9600 Hz (16.000 Hz/ 128 ovvero prescaler diviso di nuovo per 13 cicli processore per fare la conversione ADC)..in queste condizioni la massima frequenza analizzabile per il teorema di Nyiquist e' di 4800 KHz (il che va bene per suoni musicali)
In condizioni standard quindi ogni divisioni in frequenza e' larga 9600/256 =37.5Hz). Nel caso in esempio pero' tale valore e' modificato ed e' pari a 5 (gli ultimi 3 bit del valore esadecimale E5). Per variare il prescaler si deve agire sul registro ADCSRAIn pratica
#define CLOCK_PRESCALER_1 (0x0)
#define CLOCK_PRESCALER_2 (0x1)
#define CLOCK_PRESCALER_4 (0x2)
#define CLOCK_PRESCALER_8 (0x3)
#define CLOCK_PRESCALER_16 (0x4)
#define CLOCK_PRESCALER_32 (0x5)
#define CLOCK_PRESCALER_64 (0x6)
#define CLOCK_PRESCALER_128 (0x7)
#define CLOCK_PRESCALER_256 (0x8)
I dati che vengono inviati sulla porta seriale sono di tipo binario ed e' quindi necessario un programma per leggerli. Ho quindi installato Pure Data Extended e carico lo script di esempio arduinofft_display. Una volta settata la giusta porta seriale si vede il grafico popolarsi con i dati derivanti dalla Arduino
Sono stati suonati su una tastiera 3 Do a diversa altezza
NB: e' interessante leggere il codice sorgente di FHT.h perche' il codice e' quasi in tutto in ASM per ATMEGA
#define CLOCK_PRESCALER_4 (0x2)
#define CLOCK_PRESCALER_8 (0x3)
#define CLOCK_PRESCALER_16 (0x4)
#define CLOCK_PRESCALER_32 (0x5)
#define CLOCK_PRESCALER_64 (0x6)
#define CLOCK_PRESCALER_128 (0x7)
#define CLOCK_PRESCALER_256 (0x8)
I dati che vengono inviati sulla porta seriale sono di tipo binario ed e' quindi necessario un programma per leggerli. Ho quindi installato Pure Data Extended e carico lo script di esempio arduinofft_display. Una volta settata la giusta porta seriale si vede il grafico popolarsi con i dati derivanti dalla Arduino
NB: e' interessante leggere il codice sorgente di FHT.h perche' il codice e' quasi in tutto in ASM per ATMEGA