rks
rks

Reputation: 1

Arduino due is extremely slow to show the output

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

Answers (1)

KIIV
KIIV

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

Related Questions