valeria toffoli
/
COG4050_analogSensor
fft+analohADXL100x
Fork of COG4050_blink by
Revision 2:dbe2cc9e3b23, committed 2018-11-05
- Comitter:
- vtoffoli
- Date:
- Mon Nov 05 08:39:17 2018 +0000
- Parent:
- 1:f56db8105a6a
- Commit message:
- fft+analogADXL;
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ADXL100x/ADXL100x.cpp Mon Nov 05 08:39:17 2018 +0000 @@ -0,0 +1,108 @@ +// -------------------------------------------------------------------------------------------------------- +// +// September 2018 +// Author: Valeria Toffoli, Rohan Gurav +// +// -------------------------------------------------------------------------------------------------------- +// +// ADXL100x.h +// +// -------------------------------------------------------------------------------------------------------- +// +// This library provides all the functions necessary to interface the ADXL355 with EV-COG-AD3029 or +// EV-COG-AD4050 Board. Functions for reads and writes,and scaling are included. +// This library may be used for the entire ADXL100x family of devices +// with some modification. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// -------------------------------------------------------------------------------------------------------- + +#include <stdint.h> +#include <math.h> +#include "mbed.h" +#include "ADXL100x.h" + + + +/* Constructor with configurable ADXL1005 under study */ +ADXL100x::ADXL100x(PinName ST_pin , PinName STB_pin, PinName OR_pin , PinName Vout_pin, int device, double power): + st(ST_pin), stb(STB_pin), over(OR_pin), vout(Vout_pin) { // pins declarations + st = 0; stb = 0; + offset = power/2; + fact = 13e-3; // V/g + sens = 1/fact; // g/V + dyn = 200; // g + } +/* Low power mode - standby */ +void ADXL100x::standby(){ + stb = 1; + wait(0.001); + } +/* Wake up rutine: turn On Time <500us */ +void ADXL100x::wakeup(){ + stb = 0; + wait(0.001); + } +float ADXL100x::standard_dev(int bit){ + float sum, sd, mean; + float data[128]; + for (int j = 0; j < 128; j++){ + data[j] = accelScale(scanx(), bit); + sum += data[j]; + } + mean = sum / 128; + for (int j = 0; j < 128; j++){ + sd += pow(data[j] - mean, 2);; + } + return sqrt(sd/128); + } +/* Perform calibration over 1g and -1g*/ +void ADXL100x::calibrate1g(float value_p1g, float value_n1g){ + float m, b; + m = 2/(value_p1g-value_n1g); + b = -(value_p1g+value_n1g)/(value_p1g-value_n1g); + fact /= m; + sens = 1/fact; + offset -= b; + } +/* Perform the self test rutine: output takes approximately 300 μs to assenst*/ +bool ADXL100x::selftest(int bit, double power){ + double data0, data1, range; + st = 0; wait(0.3); + data0 = accelScale(scanx(), bit); + st = 1; wait(0.3); + data1 = accelScale(scanx(), bit); + st = 0; wait(0.3); + range = 0.1e-3+0.4e-3*(power-3)/2; + if ( abs(data1-data0-range) < 0.05e-3 ){return true;} + else {return false;} + } +/* Read data as 16bit from the ADUCM converter */ +uint16_t ADXL100x::scanx(){ + return vout.read_u16(); + } + /* Data conversion from 16bit to g. Need to specify the converter bit num */ +float ADXL100x::accelScale(uint16_t data, int bit){ + float result; + result = float(scanx())*(dyn*fact)/pow(2.0,double(bit)); + return (result -offset)*sens; + } +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ADXL100x/ADXL100x.h Mon Nov 05 08:39:17 2018 +0000 @@ -0,0 +1,70 @@ +// -------------------------------------------------------------------------------------------------------- +// +// September 2018 +// Author: Valeria Toffoli, Rohan Gurav +// +// -------------------------------------------------------------------------------------------------------- +// +// ADXL100x.h +// +// -------------------------------------------------------------------------------------------------------- +// +// This library provides all the functions necessary to interface the ADXL355 with EV-COG-AD3029 or +// EV-COG-AD4050 Board. Functions for reads, writes,and scaling are included. +// This library may be used for the entire ADXL100x family of devices +// with some modification. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// -------------------------------------------------------------------------------------------------------- + + +#ifndef ADXL100x_H_ +#define ADXL100x_H_ + +class ADXL100x +{ +public: + float sens; // sensitivity [g/V] + float fact; // conversion factor [V/g] + float offset; // offset [V] + int dyn; // dynamic range [g] + // -------------------------- // + // FUNCTIONS // + // -------------------------- // + // constructor + ADXL100x(PinName ST_pin, PinName STB_pin, PinName OR_pin, PinName Vout_pin, int device, double power); + void standby(); + void wakeup(); + float standard_dev(int bit); + void calibrate1g(float value_p1g, float value_n1g); + bool selftest(int bit, double power); + uint16_t scanx(); + float accelScale(uint16_t data, int bit); + +private: + DigitalOut st; DigitalOut stb; + DigitalIn over; + AnalogIn vout; + + +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FFT/FFT.cpp Mon Nov 05 08:39:17 2018 +0000 @@ -0,0 +1,111 @@ +// -------------------------------------------------------------------------------------------------------- +// +// September 2018 +// Author: Valeria Toffoli, Rohan Gurav +// -------------------------------------------------------------------------------------------------------- +// +// FFT.h +// +// -------------------------------------------------------------------------------------------------------- +// +// This library provides all the functions necessary to obtain the FFT form an analog ADXL connected with +// EV-COG-AD3029 or EV-COG-AD4050 Board. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// -------------------------------------------------------------------------------------------------------- + + + +#include <stdint.h> +#include <math.h> +#include <complex> +#include "mbed.h" +#include "FFT.h" + + +int FFT::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 FFT::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 FFT::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 FFT::order(complex<double>* f1, int N) //dispone gli elementi del vettore ordinandoli per reverse order +{ + complex<double> f2[N]; + 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 FFT::transform(complex<double>* f, int N) //calcola il vettore trasformato +{ + order(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::fourier(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 +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FFT/FFT.h Mon Nov 05 08:39:17 2018 +0000 @@ -0,0 +1,56 @@ +// -------------------------------------------------------------------------------------------------------- +// +// September 2018 +// Author: Valeria Toffoli, Rohan Gurav +// -------------------------------------------------------------------------------------------------------- +// +// FFT.h +// +// -------------------------------------------------------------------------------------------------------- +// +// This library provides all the functions necessary to obtain the FFT form an analog ADXL connected with +// EV-COG-AD3029 or EV-COG-AD4050 Board. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// -------------------------------------------------------------------------------------------------------- + + +#ifndef FFT_H_ +#define FFT_H_ + +class FFT +{ +public: + // constructor + int log2(int N); + int check(int n); + int reverse(int N, int n); + void order(complex<double>* f1, int N); + void transform(complex<double>* f, int N); + void fourier(complex<double>* f, int N, double d); + +private: + const static uint8_t MAX = 200; + const static double M_PI = 3.14159265358979323846; // reset code + +}; + +#endif
--- a/README.md Mon Aug 06 11:31:46 2018 +0000 +++ b/README.md Mon Nov 05 08:39:17 2018 +0000 @@ -1,57 +1,23 @@ -# Getting started with Blinky on mbed OS - -This guide reviews the steps required to get Blinky working on an mbed OS platform. - -Please install [mbed CLI](https://github.com/ARMmbed/mbed-cli#installing-mbed-cli). - -## Import the example application - -From the command-line, import the example: +The headers A1, A2, A3, A4 and A5 support the shields that are Arduino Uno compatible. +ADuCM4050 MCU integrates a 12-bit SAR ADC and VREF = 1.25V or 2.5V, maximum input 2.5 +A2 1 ADC0 + 2 EXT_ADC1 + 3 EXT_ADC2 + 4 ADC3 + 5 SPI2_CS3 + 6 EXT_GPIO42 +A5 3 VREF_ADC -``` -mbed import mbed-os-example-blinky -cd mbed-os-example-blinky -``` - -### Now compile - -Invoke `mbed compile`, and specify the name of your platform and your favorite toolchain (`GCC_ARM`, `ARM`, `IAR`). For example, for the ARM Compiler 5: - -``` -mbed compile -m K64F -t ARM -``` - -Your PC may take a few minutes to compile your code. At the end, you see the following result: -``` -[snip] -+----------------------------+-------+-------+------+ -| Module | .text | .data | .bss | -+----------------------------+-------+-------+------+ -| Misc | 13939 | 24 | 1372 | -| core/hal | 16993 | 96 | 296 | -| core/rtos | 7384 | 92 | 4204 | -| features/FEATURE_IPV4 | 80 | 0 | 176 | -| frameworks/greentea-client | 1830 | 60 | 44 | -| frameworks/utest | 2392 | 512 | 292 | -| Subtotals | 42618 | 784 | 6384 | -+----------------------------+-------+-------+------+ -Allocated Heap: unknown -Allocated Stack: unknown -Total Static RAM memory (data + bss): 7168 bytes -Total RAM memory (data + bss + heap + stack): 7168 bytes -Total Flash memory (text + data + misc): 43402 bytes -Image: .\.build\K64F\ARM\mbed-os-example-blinky.bin -``` +ADXL100x PIN info +Pin name Info EVAL Board +VDD supply voltage: 3 V +VSS gnd +STANDBY standby: active high +ST seld test: active high +OR overrange output +XOUT output -### Program your board - -1. Connect your mbed device to the computer over USB. -1. Copy the binary file to the mbed device. -1. Press the reset button to start the program. - -The LED on your platform turns on and off. - -## Troubleshooting - -If you have problems, you can review the [documentation](https://os.mbed.com/docs/latest/tutorials/debugging.html) for suggestions on what could be wrong and how to fix it. +FOR ADXL1005: +offset = VDD/2 = 3/2 = 1.5V +output dynamic range = 0.2V to 2.8V \ No newline at end of file
--- a/main.cpp Mon Aug 06 11:31:46 2018 +0000 +++ b/main.cpp Mon Nov 05 08:39:17 2018 +0000 @@ -1,15 +1,186 @@ +#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() { - while (true) { - double i; - led2 = !led2; - for(i=0.05; i<0.5; i=i+0.05){ - led1 = !led1; - wait(i);} - } -} \ No newline at end of file + 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"); +}