Hi, I need some help with the following problem: During a Arduino-based electromyographic feedback session I stored raw-data output on a SD card as .txt file using println (Fig1, output of 2 channels are separated by a comma). At the same time, visual feedback about muscle activity was given after performing a FFT.
However FFT output was not saved and now I would like to reproduce the output based on the SD-card raw data, whereas always 64 data points should be used to perform one FFT (1-64, 65-128,…). I could load the raw data from SD card and show it in the serial plotter/monitor using Serial.println(dataFile.readStringUntil('\n'). Unfortunately, I couldn’t read/store (without using println) the data and use it in the FFT (I think its because its ASC II?). However, I only would like to plot the FFT output separate for both channels in the serial monitor/plotter.
Can anybody help me?
ACTUAL CODE (not separated in channels):
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
#include "arduinoFFT.h"
#define SAMPLES 64 //Must be a power of 2
#define SAMPLING_FREQUENCY 1000 //Hz, must be less than 10000 due to ADC
arduinoFFT FFT = arduinoFFT();
unsigned int sampling_period_us;
unsigned long microseconds;
double vReal[SAMPLES];
double vImag[SAMPLES];
double vReal2[SAMPLES];
double vImag2[SAMPLES];
void setup()
{
Serial.begin(115200);
Serial.setTimeout(1);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
}
}
void loop(){
File dataFile = SD.open("myfile.txt");
int actual=0;
for(int i=actual; i<64; i++) {
vReal[i]=Serial.println(dataFile.readStringUntil('\n'));
actual=i;
}
/*FFT*/
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
int total1=0;
for(int i=4; i<7; i++)
{
total1 += vReal[i];
}
int gesamt1=(total1/3);
Serial.print(gesamt1);
Serial.print(" ");
}
ORIGINAL FEEDBACK CODE (without saving SSD card)
unsigned long startMillis1; //some global variables available anywhere in the program
unsigned long currentMillis1;
const unsigned long period1 = 400; //the value is a number of milliseconds
unsigned long startMillis2; //some global variables available anywhere in the program
unsigned long currentMillis2;
const unsigned long period2 = 10; //period for SD card
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
#include "arduinoFFT.h"
#define SAMPLES 64 //Must be a power of 2
#define SAMPLING_FREQUENCY 1000 //Hz, must be less than 10000 due to ADC
arduinoFFT FFT = arduinoFFT();
unsigned int sampling_period_us;
unsigned long microseconds;
double vReal[SAMPLES];
double vImag[SAMPLES];
double vReal2[SAMPLES];
double vImag2[SAMPLES];
void setup()
{
Serial.begin(115200);
Serial.setTimeout(1);
startMillis1 = millis(); //initial start time
startMillis2 = millis(); //initial start time
sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
while (!Serial)
{
; // wait for serial port to connect. Needed for native USB port only
}
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
}
File dataFile = SD.open("myoware.txt", O_CREAT | O_APPEND | O_WRITE);
dataFile.println("Messungsbeginn");
dataFile.close();
}
void loop(){
currentMillis1 = millis(); //get the current "time" (actually the number of milliseconds since the program started)
if (currentMillis1 - startMillis1 >= period1) //test whether the period has elapsed
{
for(int i=0; i<SAMPLES; i++)
{
microseconds = micros(); //Overflows after around 70 minutes!
vReal[i] = analogRead(0);
vImag[i] = 0;
vReal2[i] = analogRead(1);
vImag2[i] = 0;
while(micros() < (microseconds + sampling_period_us)){
}
}
/*FFT*/
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
FFT.Windowing(vReal2, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal2, vImag2, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal2, vImag2, SAMPLES);
int total1=0;
int total2=0;
for(int i=4; i<7; i++)
{
total1 += vReal[i];
total2 += vReal2[i];
}
int gesamt1=(total1/3);
int gesamt2=(total2/3);
Serial.print(gesamt1);
Serial.print(" ");
Serial.print(gesamt2);
Serial.println();
startMillis1 = currentMillis1; //IMPORTANT to save the start time of the current LED state.
}
}