fft+analohADXL100x

Dependencies:   COG4050_ADT7420

Fork of COG4050_blink by valeria toffoli

main.cpp

Committer:
vtoffoli
Date:
2018-11-05
Revision:
2:dbe2cc9e3b23
Parent:
1:f56db8105a6a

File content as of revision 2:dbe2cc9e3b23:

#include <stdio.h>
#include <complex>
#include <math.h>
#include "mbed.h"
#include "ADXL100x.h"
#include "FFT.h"

FFT fft; 
ADXL100x accl(D6, D7, D8, ADC_VIN0, 5, 3); 
Serial pc(USBTX, USBRX);    // tx, rx

// Interrupt and timer
Timer t;   
Ticker tck;

// Const
const float sample_time = 0.03;
const int sample_num = 128; 
#define M_PI 3.14159265358979323846 // Pi constant with double precision
uint16_t result;

// Pin
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalIn btn1(PB0); 
DigitalIn btn2(PB1); 

// Variable
double data_array[sample_num];
double time_array[sample_num];
double dt_array[sample_num+1];
complex<double> fft_array[sample_num];
int index = 0;
bool alarm = false;

/* -------------------------------------------------------------------------- */
/* FFT ---------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*
int log2(int N)    //funzione per calcolare il logaritmo in base 2 di un intero
{
  int k = N, i = 0;
  while(k) {
    k >>= 1;
    i++;
  }
  return i - 1;
}

int check(int n)    //usato per controllare se il numero di componenti del vettore di input è una potenza di 2
{
  return n > 0 && (n & (n - 1)) == 0;
}

int reverse(int N, int n)    //calcola il reverse number di ogni intero n rispetto al numero massimo N
{
  int j, p = 0;
  for(j = 1; j <= log2(N); j++) {
    if(n & (1 << (log2(N) - j)))
      p |= 1 << (j - 1);
  }
  return p;
}

void ordina(complex<double>* f1, int N)     //dispone gli elementi del vettore ordinandoli per reverse order
{
  complex<double> f2[sample_num];
  for(int i = 0; i < N; i++)
    f2[i] = f1[reverse(N, i)];
  for(int j = 0; j < N; j++)
    f1[j] = f2[j];
}

void transform(complex<double>* f, int N)     //calcola il vettore trasformato
{
  ordina(f, N);    //dapprima lo ordina col reverse order
  complex<double> W[N / 2]; //vettore degli zeri dell'unità.
                            //Prima N/2-1 ma genera errore con ciclo for successivo
                           //in quanto prova a copiare in una zona non allocata "W[N/2-1]"
  W[1] = polar(1., -2. * M_PI / N);
  W[0] = 1;
  for(int i = 2; i < N / 2; i++)
    W[i] = pow(W[1], i);
  int n = 1;
  int a = N / 2;
  for(int j = 0; j < log2(N); j++) {
    for(int i = 0; i < N; i++) {
      if(!(i & n)) {
        //ad ogni step di raddoppiamento di n, vengono utilizzati gli indici 
        //'i' presi alternativamente a gruppetti di n, una volta si e una no.
        complex<double> temp = f[i];
        complex<double> Temp = W[(i * a) % (n * a)] * f[i + n];
        f[i] = temp + Temp;
        f[i + n] = temp - Temp;
      }
    }
    n *= 2;
    a = a / 2;
  }
}

void FFT(complex<double>* f, int N, double d)
{
  transform(f, N);
  for(int i = 0; i < N; i++)
    f[i] *= d; //moltiplica il vettore per il passo in modo da avere il vettore trasformato effettivo
}
*/
/* -------------------------------------------------------------------------- */

void check_accel(){
    uint16_t result = accl.scanx();
    pc.printf("%12d \t %6f \t \r\n", result, accl.accelScale(result, 12));
    result = accl.standard_dev(12);    
    pc.printf("standard dev: %6f \t \r\n", result);
}
        
void check_fft(){
        /*if (!btn1) { 
            // collect data
            t.start();
            for(int j = 0; j < 128; j++){
                 data_array[j]= ain0.read_u16();
                 t.stop();
                 time_array[j]= t.read();
                 t.start();}
            // plot x[t] data        
            double time=time_array[0];
            double dt=0;
            pc.printf("data \t \r\n");
            for(int j = 1; j < 128; j++){ 
                dt = (dt + (time_array[j]-time ))/2;
                time = time_array[j];
                pc.printf("%6f \t %f \t %6f \t \r\n", data_array[j].real(), data_array[j].imag(), time_array[j]);}
            // compute FFT
            pc.printf("fft \t \r\n");
            FFT(data_array, 128, dt);
            for(int j = 0; j < 128; j++){ pc.printf("X[f] value: 0x%04X  \r\n", data_array[j]);}
            }*/
}

void fill_array(){
    if (index >= 128){}
    else {index = index +1;}
    }
    
void clear_array(double* f, int N){
    for (int i=0; i<N; i++){f[i] = 0;}
    }
/* -------------------------------------------------------------------------- */

int main() {
    pc.baud(9600);
    pc.printf("Analog AD sensor Demo: START\n"); 
    while(true){
        t.start();
        if(!btn1){ // COLLECT DATA
            pc.printf("Data collecting, please wait 3 minute \t\r\n");
            index=0; clear_array(data_array, sample_num);
            tck.attach(&fill_array, sample_time); // the address of the function to be attached (array_fill) and the interval (1 seconds) 
            while(index <= 127){
                result = accl.scanx();
                data_array[index] = accl.accelScale(result, 12);
                time_array[index] = t.read();
                //pc.printf("Data index %d \t \r\n", index);
                }
            tck.attach(NULL, 10); // stop to call the function (array_fill)
            for(int j = 0; j < 128; j++){ dt_array[j+1] = time_array[j+1]-time_array[j];}
            pc.printf("data \t \r\n");
            for(int j = 0; j < 128; j++){ pc.printf("%6f \t %6f \t %6f \t \r\n", data_array[j], time_array[j], dt_array[j+1]);}
            }
        t.stop(); 
        if(!btn2){ // PERFORM FFT
            led2 = !led2 ;
            pc.printf("x[n] data fft \t \r\n");
            for(int j = 0; j < 128; j++){ 
                fft_array[j] = data_array[j];
                pc.printf("real part \t %6f \t imaginary part \t %6f \t \r\n", fft_array[j].real(), fft_array[j].imag());}
            fft.fourier(fft_array, 128, sample_time);
            pc.printf("X[f] data fft \t \r\n");
            for(int j = 0; j < 128; j++){ 
                pc.printf("real part \t %6f \t imaginary part \t %6f \t \r\n", fft_array[j].real(), fft_array[j].imag());}
           }
        }
    pc.printf("Analog AD sensor Demo: STOP\n"); 
}