В настоящее время мы работаем с Arduino.arduino fft и matlab ifft
Я использую БПФ библиотеку «открытых музыкальные лаборатории FFT библиотеки»
Мой вопрос состоит из двух вещей.
Arduino код выдает
обратного БПФ в Matlab (С результатами FFT от Arduino)
следующего кода с использованием библиотеки Arduino FFT для быстрого преобразования Фурье (быстрое преобразование Фурье)
/* fft_adc_serial.pde guest openmusiclabs.com 7.7.14 example sketch for testing the fft library. it takes in data on ADC0 (Analog0) and processes them with the fft. the data is sent out over the serial port at 115.2kb. */ //#define LOG_OUT 1 // use the log output function #define FFT_N 256 // set to 256 point fft 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 for (int i = 0 ; i < 512 ; i += 2) { fft_input[i] = (fft_input[i] >> 8); fft_input[i+1] = -(fft_input[i+1] >> 8); } 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.print("start"); for (byte i = 0 ; i < FFT_N ; i+=2) { if (! ((i>=20 && i<=40) || (i>=FFT_N-40 && i<=FFT_N-20))) { fft_input[i] = 0; fft_input[i+1] = 0; } Serial.println(fft_input[i]); // send out the data } } }
matlab серийный код связи
clear all
clc
arduino=serial('COM22','BaudRate',115200);
fopen(arduino);
data = fread(arduino, 256);
ifft(data , 'symmetric');
fclose(arduino);
delete(instrfindall);
С помощью этого кода был проведен эксперимент. Но он не восстановился.
Выполните fft_run()
на Arduino, и я хотел бы получить обратный fft в matlab.
Есть много проблем.
Я хотел бы спросить, что именно.
Update
Я сделал изменения, основанные на SleuthEye's answer. Но есть проблема.
-arduino код-
/*
fft_adc_serial.pde
guest openmusiclabs.com 7.7.14
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.
*/
//#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
for (int i = 0 ; i < 512 ; i += 2) {
fft_input[i] = (fft_input[i] >> 8);
fft_input[i+1] = -(fft_input[i+1] >> 8);
}
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.println("start");
for (byte i = 0 ; i < FFT_N ; i+=2) {
Serial.write(fft_input[i]); // send out the real part
Serial.write(fft_input[i+1]); // send out the imaginary part
}
}
}
-matlab побочных
clear all
clc
arduino=serial('COM22','BaudRate',115200);
fopen(arduino);
header = fread(arduino, 5); % skip "start" header
data = fread(arduino, 512); % read actual data
% now rearrange the data
rearranged = data(1:2:end) + 1i * data(2:2:end);
recoverd = ifft(rearranged, 'symmetric');
fclose(arduino);
delete(instrfindall);
Моей проблема: она удаляет часть фильтра.
Arduino отправляет данные в MATLAB. 512 данных от Arduino. (FFT_N-real 256 и мнимой 256.)
Неточное восстановление. Выполнение ifft в matlab, а не исходные данные.
Возникла проблема с формой данных.
Эта форма данных, как представляется, проблема в общении. (Arduino в MATLAB)
data = fread(arduino, 512); % read actual data.
Но мое предположение. Точной причины не было найдено.
ОБНОВЛЕНИЕ
Благодарим за отзыв.
for (int i = 0 ; i < 512 ; i += 2) {
fft_input[i] = (fft_input[i] >> 8);
fft_input[i+1] = -(fft_input[i+1] >> 8);
}
Этот код не найден.
for (byte i = 0 ; i < FFT_N ; i+=2) {
Serial.write(fft_input[i]); // send out the real part
Serial.write(fft_input[i+1]); // send out the imaginary part
}
Моя трудность в том, Когда вы сделаете этот код, часть OUTPUT составляет 256 РЕАЛ и 256 IMAGINARY.
но
header = fread(arduino, 5); % skip "start" header
data = fread(arduino, 1024); % read actual data sent in binary form
% now rearrange the data
rearranged = (data(1:4:end) + 256*data(2:4:end)) + 1i *(data(3:4:end) + 256*data(4:4:end));
recovered = ifft(rearranged, 'symmetric');
"SIZE * ТОЧНОСТЬ должно быть меньше или равно InputBufferSize .."
Проблема размера буфера ...
Так что попробуйте еще раз. Мне пришлось изменить код, как вы сказали.
/*
fft_adc_serial.pde
guest openmusiclabs.com 7.7.14
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.
*/
//#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 respons
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.println("start"); // header send
for (byte i = 0 ; i < FFT_N ; i+=2) {
Serial.write(fft_input[i]); // send out the real part
Serial.write(fft_input[i+1]); // send out the imaginary part
}
}
}
Ваш ответ заставляет меня заняться. Делает активным. хороший ответ.
Какие проблемы? Что не вызвало? Вы должны быть более конкретными об ошибках, с которыми вы сталкиваетесь. Мы не ясновидцы, и мы не понимаем. – rayryeng
@rayryeng Хотя я бы хотел иметь умение читать: D – GameOfThrows
@GameOfThrows вы и я оба мой друг;) – rayryeng