Reputation: 1
I have been doing a signal processing project in Arduino due board. I have taken 7500 samples, sampled at 125Hz and need to find the respiratory rate. I have written a code but the output is taking too long to print in serial monitor. For this particular sample I am trying, it never shows the output. I don't know the reason.
Below code is the one I tried. Can anyone help me with this?
the sample value is downloaded from archive.physionet.org/cgi-bin/atm/ATM
bidmc dataset and the signal is bidmc03m, pleth, for 1min duration in seconds ,standard
#include <SPI.h>
#include <SD.h>
#define PI 3.1415926535897932384626433832795
/* https://archive.physionet.org/cgi-bin/atm/ATM */
void dft(const double inrealn[],double outreal[],double outimg[],double magi[],size_t n);//for n number of samples
float maxi(float a, float b);
double inreal[7500]={//the sample values can be downloaded from above link
};
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
// preprocessing
//mean
int n=7500;
double sum1=0;
for(int j=0;j<n;j++){
sum1=sum1+inreal[j];
}
//find mean
double mean=sum1/n;
for(int i=0;i<n;i++)
{
inreal[i]=inreal[i]-mean;
}
/*for(int i=0;i<n;i++)
{
Serial.println( inreal[i]);
}*/
//find max value
double maxVal = inreal[0];
for (int i = 1; i < n; i++) {
if (inreal[i] > maxVal) {
maxVal = inreal[i];
}
else{
//
}
}
//Serial.println(maxVal);
//normalise the signal
for(int j=0;j<n;j++){
inreal[j]=inreal[j]/maxVal;
//Serial.println(inreal[j]);
}
//this is for coefficient calculation for resonator
double a1=-2*0.997*cos(0.3*2*PI);
double a2=0.997*0.997;
double b=(1-0.997)*sqrt(1+(0.997*0.997)-2*0.997*cos(2*0.3));
//resonator
double inrealn[7500]={};
for(int j=2;j<n;j++){
inrealn[j]=-a1*inrealn[j-1]-a2*inrealn[j-2]+b*inreal[j];
}
//dft
//double inmg[250]={};
double outreal[7500]={};
double outimg[7500]={};
double magi[7500]={};
dft(inrealn,outreal,outimg,magi,n);//works good
//find maximum peak in spectrum
double fmaxi = -100000.00;
for (int i = 0; i < n; i++) {
fmaxi = maxi(magi[i],fmaxi);
}
//find breathing rate
double resp_rate=fmaxi*60;
Serial.println(resp_rate);
}
//for dft
void dft(const double inrealn[],double outreal[],double outimg[],double magi[],size_t n){//double inmg is removed ass it is asumed to be 0
for (int k=0;k<n;k++){
double sumreal=0;
double sumimg=0;
for (int t=0;t<n;t++){
double angles=2*PI*t*k/n;
sumreal+=inrealn[t]*cos(angles);
sumimg+=-inrealn[t]*sin(angles);
}
outreal[k]=sumreal;
outimg[k]=sumimg;
magi[k]=sqrt(pow(outreal[k],2)+pow(outimg[k],2));
}
}
float maxi(float a, float b){
if(a>b){
return a;
}
else{
return b;
}
}
Upvotes: -1
Views: 76
Reputation: 3739
Well, as you might know the DUE has only 96kB of RAM
If you have:
double inrealn[7500]={}; // 8B * 7500 = 60000B
double outreal[7500]={}; // 8B * 7500 = 60000B
double outimg[7500]={}; // 8B * 7500 = 60000B
double magi[7500]={}; // 8B * 7500 = 60000B
// total: 240000B
So now you can imagine what happens when you try to use 234kB of RAM when you only have 96kB available -> probably some hardfault and nice little while (1) {;} as error handler.
Even if it has 4 bytes (like float), it'd be too much
Upvotes: 0