FFT Quadrature detector

What are you developing?
Post Reply
stan
Posts: 70
Joined: Wed Nov 11, 2020 7:40 pm

FFT Quadrature detector

Post by stan »

Hi
I am trying to build an code for quadrature detector.

The first step is to use analog pin - PA7 - as input instead of - //Example data: ?

Code: Select all

//Example data:
int data[64]={14, 30, 35, 34, 34, 40, 46, 45, 30, 4,  -26,  -48,  -55,  -49,  -37,
-28,  -24,  -22,  -13,  6,  32, 55, 65, 57, 38, 17, 1,  -6, -11,  -19,  -34,
-51,  -61,  -56,  -35,  -7, 18, 32, 35, 34, 35, 41, 46, 43, 26, -2, -31,  -50,
-55,  -47,  -35,  -27,  -24,  -21,  -10,  11, 37, 58, 64, 55, 34, 13, -1, -7};
here is FFT code which I want to modify.

Code: Select all

//Example data:
int data[64]={14, 30, 35, 34, 34, 40, 46, 45, 30, 4,  -26,  -48,  -55,  -49,  -37,
-28,  -24,  -22,  -13,  6,  32, 55, 65, 57, 38, 17, 1,  -6, -11,  -19,  -34,
-51,  -61,  -56,  -35,  -7, 18, 32, 35, 34, 35, 41, 46, 43, 26, -2, -31,  -50,
-55,  -47,  -35,  -27,  -24,  -21,  -10,  11, 37, 58, 64, 55, 34, 13, -1, -7};
 
 
 
//---------------------------------------------------------------------------//
byte sine_data [91]=
{
0, 
4,    9,    13,   18,   22,   27,   31,   35,   40,   44,
49,   53,   57,   62,   66,   70,   75,   79,   83,   87,
91,   96,   100,  104,  108,  112,  116,  120,  124,  127, 
131,  135,  139,  143,  146,  150,  153,  157,  160,  164, 
167,  171,  174,  177,  180,  183,  186,  189,  192,  195,       //Paste this at top of program
198,  201,  204,  206,  209,  211,  214,  216,  219,  221, 
223,  225,  227,  229,  231,  233,  235,  236,  238,  240, 
241,  243,  244,  245,  246,  247,  248,  249,  250,  251, 
252,  253,  253,  254,  254,  254,  255,  255,  255,  255
  };
float f_peaks[5]; // top 5 frequencies peaks in descending order
//---------------------------------------------------------------------------//
 
//*******************************************
void setup()
        {
        Serial.begin(250000);          
        }
 
       
void loop() {
//***************************************
 
//example
FFT(data,64,100);        //to get top five value of frequencies of X having 64 sample at 100Hz sampling
/*Serial.print(f_peaks[0]);
Serial.print("   ");
Serial.println(f_peaks[1]);
//delay(99999);
*/
delay(99);
 
 
 
/*
after ruing above FFT(), frequencies available at f_peaks[0],f_peaks[1],f_peaks[2],f_peaks[3],f_peaks[4],
*/          
            }
 
 
 
//-----------------------------FFT Function----------------------------------------------//
 
float FFT(int in[],byte N,float Frequency)
{
/*
Code to perform FFT on arduino,
setup:
paste sine_data [91] at top of program [global variable], paste FFT function at end of program
Term:
1. in[]     : Data array,
2. N        : Number of sample (recommended sample size 2,4,8,16,32,64,128...)
3. Frequency: sampling frequency required as input (Hz)
 
If sample size is not in power of 2 it will be clipped to lower side of number.
i.e, for 150 number of samples, code will consider first 128 sample, remaining sample  will be omitted.
For Arduino nano, FFT of more than 128 sample not possible due to mamory limitation (64 recomended)
For higher Number of sample may arise Mamory related issue,
Code by ABHILASH
Contact: abhilashpatel121@gmail.com
Documentation:https://www.instructables.com/member/abhilash_patel/instructables/
*/
 
unsigned int data[13]={1,2,4,8,16,32,64,128,256,512,1024,2048};
int a,c1,f,o,x;
a=N; 
                                 
      for(int i=0;i<12;i++)                 //calculating the levels
         { if(data[i]<=a){o=i;} }
     
int in_ps[data[o]]={};     //input for sequencing
float out_r[data[o]]={};   //real part of transform
float out_im[data[o]]={};  //imaginory part of transform
          
x=0; 
      for(int b=0;b<o;b++)                     // bit reversal
         {
          c1=data[b];
          f=data[o]/(c1+c1);
                for(int j=0;j<c1;j++)
                    {
                     x=x+1;
                     in_ps[x]=in_ps[j]+f;
                    }
         }
 
      for(int i=0;i<data[o];i++)            // update input array as per bit reverse order
         {
          if(in_ps[i]<a)
          {out_r[i]=in[in_ps[i]];}
          if(in_ps[i]>a)
          {out_r[i]=in[in_ps[i]-a];}     
         }
 
 
int i10,i11,n1;
float e,c,s,tr,ti;
 
    for(int i=0;i<o;i++)                                    //fft
    {
     i10=data[i];              // overall values of sine/cosine  :
     i11=data[o]/data[i+1];    // loop with similar sine cosine:
     e=360/data[i+1];
     e=0-e;
     n1=0;
 
          for(int j=0;j<i10;j++)
          {
          c=cosine(e*j);
          s=sine(e*j);   
          n1=j;
         
                for(int k=0;k<i11;k++)
                 {
                 tr=c*out_r[i10+n1]-s*out_im[i10+n1];
                 ti=s*out_r[i10+n1]+c*out_im[i10+n1];
         
                 out_r[n1+i10]=out_r[n1]-tr;
                 out_r[n1]=out_r[n1]+tr;
         
                 out_im[n1+i10]=out_im[n1]-ti;
                 out_im[n1]=out_im[n1]+ti;         
          
                 n1=n1+i10+i10;
                  }      
             }
     }
 
 
for(int i=0;i<data[o];i++)
/*
/////////////////////////////////////////////
{
Serial.print(out_r[i]);
Serial.print("\t");                                     // un comment to print RAW o/p   
Serial.println(out_im[i]);
//Serial.println("i");     
}
///////////////////////////////////////////////
*/
 
//---> here onward out_r contains amplitude and our_in conntains frequency (Hz)
    for(int i=0;i<data[o-1];i++)               // getting amplitude from compex number
        {
         out_r[i]=sqrt(out_r[i]*out_r[i]+out_im[i]*out_im[i]); // to  increase the speed delete sqrt
         out_im[i]=i*Frequency/N;        
         Serial.print(out_im[i]);
         //Serial.print("Hz");
         Serial.print("\t");                            // un comment to print freuency bin   
         Serial.println(out_r[i]);
            
        }
 
 
 
 
x=0;       // peak detection
   for(int i=1;i<data[o-1]-1;i++)
      {
      if(out_r[i]>out_r[i-1] && out_r[i]>out_r[i+1])
      {in_ps[x]=i;    //in_ps array used for storage of peak number
      x=x+1;}   
      }
 
 
s=0;
c=0;
    for(int i=0;i<x;i++)             // re arraange as per magnitude
    {
        for(int j=c;j<x;j++)
        {
            if(out_r[in_ps[i]]<out_r[in_ps[j]])
                {s=in_ps[i];
                in_ps[i]=in_ps[j];
                in_ps[j]=s;}
        }
    c=c+1;
    }
 
 
 
    for(int i=0;i<5;i++)     // updating f_peak array (global variable)with descending order
    {
    f_peaks[i]=out_im[in_ps[i]];
    }
 
 
 
}
   
 
float sine(int i)
{
  int j=i;
  float out;
  while(j<0){j=j+360;}
  while(j>360){j=j-360;}
  if(j>-1   && j<91){out= sine_data[j];}
  else if(j>90  && j<181){out= sine_data[180-j];}
  else if(j>180 && j<271){out= -sine_data[j-180];}
  else if(j>270 && j<361){out= -sine_data[360-j];}
  return (out/255);
}
 
float cosine(int i)
{
  int j=i;
  float out;
  while(j<0){j=j+360;}
  while(j>360){j=j-360;}
  if(j>-1   && j<91){out= sine_data[90-j];}
  else if(j>90  && j<181){out= -sine_data[j-90];}
  else if(j>180 && j<271){out= -sine_data[270-j];}
  else if(j>270 && j<361){out= sine_data[j-270];}
  return (out/255);
}
 
//------------------------------------------------------------------------------------//
Last edited by stan on Mon Nov 23, 2020 5:54 pm, edited 1 time in total.
stan
Posts: 70
Joined: Wed Nov 11, 2020 7:40 pm

Re: FFT Quadrature detector

Post by stan »

How to replace the data by this ?

Code: Select all

 int valuePin = PA7;
 
void setup() {
 pinMode(PA7, INPUT); 

}

void loop() {
 Value = analogRead(valuePin);

}
mlundin
Posts: 57
Joined: Wed Nov 04, 2020 1:20 pm
Answers: 6
Location: Sweden

Re: FFT Quadrature detector

Post by mlundin »

How many samples do you propose to process at a time, and what sample frequency do you want ?

Seriously, using example code and adapting it to your own project is a good way to learn coding and to get a project up and running, but unless you plan to follow the instructables to the letter, you must first make sure you understand how the example code works, you must also learn the basic programming techniques and the platform specific libraries for your board. This is probably best done with simple tests and not while trying to modify complex code.

I am not saying that there is one 'perfect way' of doing this but you surely must get to know the basics one way or the other. Throwing up a set of messy coding and saying "This doesnt work" is not going to to get you very far. You have to prove you have done your part of the work and also tried seriously to understand the answers you get, or very soon you will get no answers at all.

Good luck.
stan
Posts: 70
Joined: Wed Nov 11, 2020 7:40 pm

Re: FFT Quadrature detector

Post by stan »

This is what I did.

Code: Select all

#define SAMPLES 128
#define SAMPLING_FREQUENCY 1000
int valuePin = PA7;
int Value ;


void setup()
{
  pinMode(PA7, INPUT);
  Serial.begin(250000);
}

void loop() {
  int i;
 
 Value[i] = analogRead(valuePin);
 for(int i=0; i<SAMPLES; i++)
 {
 //FFT(data, 64, 100);      //to get top five value of frequencies of X having 64 sample at 100Hz sampling
 FFT(Value[i], 128, 1000);
  
 }
  /*Serial.print(f_peaks[0]);
    Serial.print("   ");
    Serial.println(f_peaks[1]);
    //delay(99999);
  */
  delay(99);
}



//-----------------------------FFT Function----------------------------------------------//

float FFT(int in[], byte N, float Frequency)
{


  unsigned int data[13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
  int a, c1, f, o, x;
  a = N;

  for (int i = 0; i < 12; i++)          //calculating the levels
  {
    if (data[i] <= a) {
      o = i;
    }
  }

  int in_ps[data[o]] = {};   //input for sequencing
  float out_r[data[o]] = {}; //real part of transform
  float out_im[data[o]] = {}; //imaginory part of transform

  x = 0;
  for (int b = 0; b < o; b++)              // bit reversal
  {
    c1 = data[b];
    f = data[o] / (c1 + c1);
    for (int j = 0; j < c1; j++)
    {
      x = x + 1;
      in_ps[x] = in_ps[j] + f;
    }
  }

  for (int i = 0; i < data[o]; i++)     // update input array as per bit reverse order
  {
    if (in_ps[i] < a)
    {
      out_r[i] = in[in_ps[i]];
    }
    if (in_ps[i] > a)
    {
      out_r[i] = in[in_ps[i] - a];
    }
  }


  int i10, i11, n1;
  float e, c, s, tr, ti;

  for (int i = 0; i < data[o]; i++)
    /*
      /////////////////////////////////////////////
      {
      Serial.print(out_r[i]);
      Serial.print("\t");                                     // un comment to print RAW o/p
      Serial.println(out_im[i]);
      //Serial.println("i");
      }
      ///////////////////////////////////////////////
    */

    //---> here onward out_r contains amplitude and our_in conntains frequency (Hz)
    for (int i = 0; i < data[o - 1]; i++)      // getting amplitude from compex number
    {
      out_r[i] = sqrt(out_r[i] * out_r[i] + out_im[i] * out_im[i]); // to  increase the speed delete sqrt
      out_im[i] = i * Frequency / N;
      Serial.print(out_im[i]);
      //Serial.print("Hz");
      Serial.print("\t");                            // un comment to print freuency bin
      Serial.println(out_r[i]);

    }




  x = 0;     // peak detection
  for (int i = 1; i < data[o - 1] - 1; i++)
  {
    if (out_r[i] > out_r[i - 1] && out_r[i] > out_r[i + 1])
    { in_ps[x] = i;  //in_ps array used for storage of peak number
      x = x + 1;
    }
  }


  s = 0;
  c = 0;
  for (int i = 0; i < x; i++)      // re arraange as per magnitude
  {
    for (int j = c; j < x; j++)
    {
      if (out_r[in_ps[i]] < out_r[in_ps[j]])
      { s = in_ps[i];
        in_ps[i] = in_ps[j];
        in_ps[j] = s;
      }
    }
    c = c + 1;
  }

}

Not sure about loop = 2 errors

ft_quadrature_2:16:9: error: invalid types 'int[int]' for array subscript
Value = analogRead(valuePin);
^
fft_quadrature_2:20:13: error: invalid types 'int[int]' for array subscript
FFT(Value, 128, 1000);
Bambo
Posts: 50
Joined: Wed Jan 15, 2020 8:36 pm

Re: FFT Quadrature detector

Post by Bambo »

stan wrote:
Mon Nov 23, 2020 5:25 pm
This is what I did.

Code: Select all

#define SAMPLES 128
#define SAMPLING_FREQUENCY 1000
int valuePin = PA7;
int Value ;


void setup()
{
  pinMode(PA7, INPUT);
  Serial.begin(250000);
}

void loop() {
  int i;
 
 Value[i] = analogRead(valuePin);
 for(int i=0; i<SAMPLES; i++)
 {
 //FFT(data, 64, 100);      //to get top five value of frequencies of X having 64 sample at 100Hz sampling
 FFT(Value[i], 128, 1000);
  
 }
  /*Serial.print(f_peaks[0]);
    Serial.print("   ");
    Serial.println(f_peaks[1]);
    //delay(99999);
  */
  delay(99);
}



//-----------------------------FFT Function----------------------------------------------//

float FFT(int in[], byte N, float Frequency)
{


  unsigned int data[13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
  int a, c1, f, o, x;
  a = N;

  for (int i = 0; i < 12; i++)          //calculating the levels
  {
    if (data[i] <= a) {
      o = i;
    }
  }

  int in_ps[data[o]] = {};   //input for sequencing
  float out_r[data[o]] = {}; //real part of transform
  float out_im[data[o]] = {}; //imaginory part of transform

  x = 0;
  for (int b = 0; b < o; b++)              // bit reversal
  {
    c1 = data[b];
    f = data[o] / (c1 + c1);
    for (int j = 0; j < c1; j++)
    {
      x = x + 1;
      in_ps[x] = in_ps[j] + f;
    }
  }

  for (int i = 0; i < data[o]; i++)     // update input array as per bit reverse order
  {
    if (in_ps[i] < a)
    {
      out_r[i] = in[in_ps[i]];
    }
    if (in_ps[i] > a)
    {
      out_r[i] = in[in_ps[i] - a];
    }
  }


  int i10, i11, n1;
  float e, c, s, tr, ti;

  for (int i = 0; i < data[o]; i++)
    /*
      /////////////////////////////////////////////
      {
      Serial.print(out_r[i]);
      Serial.print("\t");                                     // un comment to print RAW o/p
      Serial.println(out_im[i]);
      //Serial.println("i");
      }
      ///////////////////////////////////////////////
    */

    //---> here onward out_r contains amplitude and our_in conntains frequency (Hz)
    for (int i = 0; i < data[o - 1]; i++)      // getting amplitude from compex number
    {
      out_r[i] = sqrt(out_r[i] * out_r[i] + out_im[i] * out_im[i]); // to  increase the speed delete sqrt
      out_im[i] = i * Frequency / N;
      Serial.print(out_im[i]);
      //Serial.print("Hz");
      Serial.print("\t");                            // un comment to print freuency bin
      Serial.println(out_r[i]);

    }




  x = 0;     // peak detection
  for (int i = 1; i < data[o - 1] - 1; i++)
  {
    if (out_r[i] > out_r[i - 1] && out_r[i] > out_r[i + 1])
    { in_ps[x] = i;  //in_ps array used for storage of peak number
      x = x + 1;
    }
  }


  s = 0;
  c = 0;
  for (int i = 0; i < x; i++)      // re arraange as per magnitude
  {
    for (int j = c; j < x; j++)
    {
      if (out_r[in_ps[i]] < out_r[in_ps[j]])
      { s = in_ps[i];
        in_ps[i] = in_ps[j];
        in_ps[j] = s;
      }
    }
    c = c + 1;
  }

}

Not sure about loop = 2 errors

ft_quadrature_2:16:9: error: invalid types 'int[int]' for array subscript
Value = analogRead(valuePin);
^
fft_quadrature_2:20:13: error: invalid types 'int[int]' for array subscript
FFT(Value, 128, 1000);


Hey, FFT functions are in the CMSIS api, see here: https://arm-software.github.io/CMSIS_5/ ... index.html
Post Reply

Return to “Projects”