Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed X_NUCLEO_IKS01A2 mbed-dsp
Diff: main.cpp
- Revision:
- 18:b35e44c016c2
- Parent:
- 13:fc873da5b445
--- a/main.cpp Wed Sep 27 15:48:21 2017 +0000 +++ b/main.cpp Mon Oct 11 08:49:03 2021 +0000 @@ -4,7 +4,7 @@ * @author CLab * @version V1.0.0 * @date 2-December-2016 - * @brief Simple Example application for using the X_NUCLEO_IKS01A1 + * @brief Simple Example application for using the X_NUCLEO_IKS01A1 * MEMS Inertial & Environmental Sensor Nucleo expansion board. ****************************************************************************** * @attention @@ -34,111 +34,378 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** -*/ +*/ /* Includes */ #include "mbed.h" #include "XNucleoIKS01A2.h" +/* Include arm_math.h mathematic functions */ +#include "arm_math.h" +/* Include mbed-dsp libraries */ +#include "arm_common_tables.h" +#include "arm_const_structs.h" +#include "math_helper.h" + + +/* FFT settings */ +#define SAMPLES 4096 /* 2048 real party and 2048 imaginary parts */ +#define FFT_SIZE SAMPLES / 2 /* FFT size is always the same size as we have samples, so 256 in our case */ + +/* Variables FFT*/ +float InputX[SAMPLES],InputY[SAMPLES],InputZ[SAMPLES]; +//float Input_X[SAMPLES-2],Input_Y[SAMPLES-2],Input_Z[SAMPLES-2]; +float OutputX[FFT_SIZE],OutputY[FFT_SIZE],OutputZ[FFT_SIZE]; +float Output_X[FFT_SIZE-1],Output_Y[FFT_SIZE-1],Output_Z[FFT_SIZE-1]; +uint8_t cx_f, cy_f, cz_f; +uint8_t M_cx_f,M_cy_f,M_cz_f; +//int M_cx_f,M_cy_f,M_cz_f; +bool trig=0; + +/*Variabili accellerometro*/ +//int32_t axes[3]; +int16_t int_axes[3]; /* Instantiate the expansion board */ static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5); -/* Retrieve the composing elements of the expansion board */ -static LSM303AGRMagSensor *magnetometer = mems_expansion_board->magnetometer; -static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor; -static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor; static LSM6DSLSensor *acc_gyro = mems_expansion_board->acc_gyro; -static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer; + +//Seriali +Serial pc(USBTX, USBRX,115200); +I2C i2c(D14, D15); -/* Helper function for printing floats & doubles */ -static char *print_double(char* str, double v, int decimalDigits=2) -{ - int i = 1; - int intPart, fractPart; - int len; - char *ptr; - - /* prepare decimal digits multiplicator */ - for (;decimalDigits!=0; i*=10, decimalDigits--); +/* LoRaWAN */ +Serial lora(D8,D2,115200); +void setup_lora(void); +void modem_at_cmd(char*,int); +void wait4join(void); +void inviaMessaggio(float,uint8_t, float,uint8_t, float,uint8_t); +char c; +uint16_t i_M=351;// indice per invio messaggio - /* calculate integer & fractinal parts */ - intPart = (int)v; - fractPart = (int)((v-(double)(int)v)*i); +char* msg1 = {"AT"}; +char* msg2 = {"AT+APPEUI=1111111111111111"}; +char* msg3 = {"AT+AK=11111111111111111111111111111111"}; +char* msg4 = {"AT+JOIN=1"}; +//char* msg5 = {"AT+SEND=15,3031323334,0"}; +char msg5[64]; // = {"AT+SEND=15,3031323334,0"}; +char msg6[80]; - /* fill in integer part */ - sprintf(str, "%i.", intPart); +/* Timer */ +//Timer tempo, temp; +//Ticker tic; - /* prepare fill in of fractional part */ - len = strlen(str); - ptr = &str[len]; - /* fill in leading fractional zeros */ - for (i/=10;i>1; i/=10, ptr++) { - if (fractPart >= i) { - break; - } - *ptr = '0'; - } +void sample() +{ + trig=1; + +} +int calcolare_max(float* Vettore) +{ - /* fill in (rest of) fractional part */ - sprintf(ptr, "%i", fractPart); - - return str; + uint16_t I=0; + float max=Vettore[0]; + for(int w=0; w<=sizeof(Vettore); w++) + if(max<Vettore[w]) { + max=Vettore[w]; + I=w; + } + return I; } -/* Simple main function */ -int main() { - uint8_t id; - float value1, value2; - char buffer1[32], buffer2[32]; - int32_t axes[3]; - - /* Enable all sensors */ - hum_temp->enable(); - press_temp->enable(); - magnetometer->enable(); - accelerometer->enable(); - acc_gyro->enable_x(); - acc_gyro->enable_g(); - - printf("\r\n--- Starting new run ---\r\n"); + +int main() +{ + i2c.frequency(1000000); + float dato_final[3]; + float sens; + //sens =0.061; //FS= 2g + uint16_t imX, imY, imZ; + + float MaxValueX,MaxValueY,MaxValueZ; //Massimo valore dei vettoridei massimi di FFT in 1 ora + //arm_cfft_instance_f32 S; // ARM CFFT module + float maxValueX,maxValueY,maxValueZ; // Max FFT value is stored here + uint32_t maxIndexX,maxIndexY,maxIndexZ; // Index in Output array where max value is + float V_maxX[i_M],V_maxY[i_M],V_maxZ[i_M]; // Vettori contenente i max del FFT in un ora + float V_cx_f[i_M],V_cy_f[i_M], V_cz_f[i_M]; + i_M=0; + /* Enable accellerometro */ + acc_gyro->enable_x(); + acc_gyro->set_x_odr(1666.0); + acc_gyro->get_x_sensitivity(&sens); + //Inizializzazione comunicazione con modem LoRaWAN + setup_lora(); + + pc.printf("\r\n--- Starting new run ---\r\n"); + + while(1) { + pc.printf("Nuovo ciclo while \r\n"); + /* memset(V_maxX,0,360); + memset(V_maxY,0,360); + memset(V_maxZ,0,360); + + pc.printf("Vettore dei max di x: "); + for(int j=0; j<360; j++) { + pc.printf(" %f",V_maxX[j]); + } + pc.printf("\r\n"); + */ + /* + // azzera vettori + memset(InputX,0,SAMPLES*sizeof(float)); + //for(int j=0;j<SAMPLES;j++) + //printf(" %f%",InputX[j]); + memset(InputY,0,SAMPLES*sizeof(float)); + memset(InputZ,0,SAMPLES*sizeof(float)); + memset(OutputX,0,FFT_SIZE*sizeof(float)); + memset(OutputY,0,FFT_SIZE*sizeof(float)); + memset(OutputZ,0,FFT_SIZE*sizeof(float)); + */ + /* + float t=0; + tempo.start(); + tempo.reset(); + acc_gyro->get_x_axes_raw(int_axes); + t=tempo.read(); + printf("Tempo1: %f\r\n", t); + */ + //pc.printf("Fa partire tic\r\n"); + /* + float t0=0; + temp.start(); + temp.reset(); + */ + //printf("Acquisisco\r\n"); + Ticker tic; + tic.attach_us(&sample,5000); //5 ms 200Hz sampling rate + //pc.printf("Trig prima del for di acquisizione = %d\r\n",trig); + for (int i = 0; i < SAMPLES; i += 2) { + //printf("Dentro il for \r\n"); + while (trig==0); + //pc.printf("Trig = %d e i= %d\r\n",trig,i); + trig=0; + //printf("trig= %d\r\n",trig); + acc_gyro->get_x_axes_raw(int_axes); + //printf("Preso dato\r\n"); + dato_final[0]=float(int_axes[0]*sens);//mg //solo x + dato_final[1]=float(int_axes[1]*sens);//mg //solo y + dato_final[2]=float(int_axes[2]*sens);//mg //solo z + InputX[i] = dato_final[0]; //Real part NB removing DC offset + InputX[i + 1] = 0; //Imaginary Part set to zero + InputY[i] = dato_final[1]; + InputY[i + 1] = 0; + InputZ[i] = dato_final[2]; + InputZ[i + 1] = 0; + } + tic.detach(); + + /* + t0=temp.read(); + float t=0; + tempo.start(); + tempo.reset(); + */ + // azzera vettori + /* memset(Input_X,0,SAMPLES*sizeof(float)); + memset(Input_Y,0,SAMPLES*sizeof(float)); + memset(Input_Z,0,SAMPLES*sizeof(float)); + */ + //printf("Tolgo l'indice zero\r\n"); + //Tolgo l'indice zero che è quell della componete continua + /*for (int h=0; h<SAMPLES-2; h++) { + Input_X[h]=InputX[h+2]; + Input_Y[h]=InputY[h+2]; + Input_Z[h]=InputZ[h+2]; + }*/ + + // Init the Complex FFT module, intFlag = 0, doBitReverse = 1 + //NB using predefined arm_cfft_sR_f32_lenXXX, in this case XXX is 4096 + arm_cfft_f32(&arm_cfft_sR_f32_len2048, InputX, 0, 1); + arm_cfft_f32(&arm_cfft_sR_f32_len2048, InputY, 0, 1); + arm_cfft_f32(&arm_cfft_sR_f32_len2048, InputZ, 0, 1); + // Complex Magniture Module put results into Output(Half size of the Input) + arm_cmplx_mag_f32(InputX, OutputX, FFT_SIZE); + arm_cmplx_mag_f32(InputY, OutputY, FFT_SIZE); + arm_cmplx_mag_f32(InputZ, OutputZ, FFT_SIZE); + + for (int h=0; h<FFT_SIZE-1; h++) { + Output_X[h]=OutputX[h+1]; + Output_Y[h]=OutputY[h+1]; + Output_Z[h]=OutputZ[h+1]; + } + //Calculates maxValue and returns corresponding value + arm_max_f32(Output_X, FFT_SIZE-1, &maxValueX, &maxIndexX); + arm_max_f32(Output_Y, FFT_SIZE-1, &maxValueY, &maxIndexY); + arm_max_f32(Output_Z, FFT_SIZE-1, &maxValueZ, &maxIndexZ); + printf("Massimo valore di X e' : %f\r\n",maxValueX/2048*2/1000); + printf("Massimo valore di Y e' : %f\r\n",maxValueY/2048*2/1000); + printf("Massimo valore di Z e' : %f\r\n",maxValueZ/2048*2/1000); + + - hum_temp->read_id(&id); - printf("HTS221 humidity & temperature = 0x%X\r\n", id); - press_temp->read_id(&id); - printf("LPS22HB pressure & temperature = 0x%X\r\n", id); - magnetometer->read_id(&id); - printf("LSM303AGR magnetometer = 0x%X\r\n", id); - accelerometer->read_id(&id); - printf("LSM303AGR accelerometer = 0x%X\r\n", id); - acc_gyro->read_id(&id); - printf("LSM6DSL accelerometer & gyroscope = 0x%X\r\n", id); - - while(1) { - printf("\r\n"); + cx_f= maxIndexX*200/2048; + cy_f= maxIndexY*200/2048; + cz_f= maxIndexZ*200/2048; + /* if (maxValueX>142000 || maxValueY>213000 || maxValueZ>211000){ + printf("ALLARME, troppe vibrazioni!!!\r\n"); + inviaMessaggio(maxValueX,cx_f,maxValueY,cy_f,maxValueZ,cz_f); + i_M=0; + } + */ + //pc.printf("Valore del Max di x: %f e valore della sua componete frequenziale: %d\r\n",maxValueX,cx_f); + //printf("Valore del Max di y: %f e valore della sua componete frequenziale: %d\r\n",maxValueY,cy_f); + /* printf("Indice del max di x %d\r\n",maxIndexX); + printf("Valore del Max di x: %f e valore della sua componete frequenziale: %d\r\n",maxValueX,cx_f); + printf("Indice del max di y: %d\r\n",maxIndexY); + printf("Valore del Max di y: %f e valore della sua componete frequenziale: %d\r\n",maxValueY,cy_f); + printf("Indice del max di z: %d\r\n",maxIndexZ); + printf("Valore del Max di z: %f e valore della sua componete frequenziale: %d\r\n",maxValueZ,cz_f); + printf("\r\n"); + */ + /* t=tempo.read(); + printf("Tempo acquisizione: %f\r\n", t0); + printf("Tempo per FFT e max: %f\r\n", t); + */ + + V_maxX[i_M]=maxValueX/2048*2/1000; //Ai=bin/N*2 diviso 1000 per passare da mg a g + V_cx_f[i_M]=cx_f; + V_maxY[i_M]=maxValueY/2048*2/1000; + V_cy_f[i_M]=cy_f; + V_maxZ[i_M]=maxValueZ/2048*2/1000; + V_cz_f[i_M]=cz_f; + + + if(i_M==60 || V_maxX[i_M]>0.139 || V_maxY[i_M]>0.208 || V_maxZ[i_M]>0.206) { //360 circa un ora con precisione 351 + //X + /* + pc.printf("Vettore dei max di x: "); + for(int j=0; j<=i_M; j++) { + pc.printf(" %f",V_maxX[j]); + } + pc.printf("\r\n");*/ + imX=calcolare_max(V_maxX); + MaxValueX=V_maxX[imX]; + M_cx_f=V_cx_f[imX]; + pc.printf("Massimo di x rilevato in questo lasso temporale e' di : %f, componente frequenziale %d\r\n",MaxValueX,M_cx_f); + //Y + /* printf("Vettore dei max di y: "); + for(int j=0; j<=i_M; j++) { + printf(" %f",V_maxY[j]); + } + printf("\r\n"); */ + imY=calcolare_max(V_maxY); + MaxValueY=V_maxY[imY]; + M_cy_f=V_cy_f[calcolare_max(V_maxY)]; + printf("Massimo di y rilevato in questo lasso temporale e' di : %f, componente frequenziale %d\r\n",MaxValueY,M_cy_f); + + //Z + + /* printf("Vettore dei max di z: "); + for(int j=0; j<=i_M; j++) { + printf(" %f",V_maxZ[j]); + } + printf("\r\n"); */ + imZ=calcolare_max(V_maxZ); + MaxValueZ=V_maxZ[imZ]; + M_cz_f=V_cz_f[calcolare_max(V_maxZ)]; + printf("Massimo di z rilevato in questo lasso temporale e' di : %f, componente frequenziale %d\r\n",MaxValueZ,M_cz_f); + inviaMessaggio(MaxValueX,M_cx_f,MaxValueY,M_cy_f,MaxValueZ,M_cz_f); + + i_M=0; + printf("\r\n"); + } else{ + + i_M++; + } + pc.printf("Valore di i_M : %d\r\n",i_M); + } + +}//Fine while(1) + + - hum_temp->get_temperature(&value1); - hum_temp->get_humidity(&value2); - printf("HTS221: [temp] %7s C, [hum] %s%%\r\n", print_double(buffer1, value1), print_double(buffer2, value2)); - - press_temp->get_temperature(&value1); - press_temp->get_pressure(&value2); - printf("LPS22HB: [temp] %7s C, [press] %s mbar\r\n", print_double(buffer1, value1), print_double(buffer2, value2)); +void setup_lora() +{ - printf("---\r\n"); + pc.printf("Setup comunicazione LoRa\r\n"); + modem_at_cmd(msg1,(int)strlen(msg1)); + pc.printf("Inviato AT\r\n"); + wait(1); + modem_at_cmd(msg2,(int)strlen(msg2)); + pc.printf("Inviato EUI\r\n"); + wait(1); + modem_at_cmd(msg3,(int)strlen(msg3)); + pc.printf("Inviato AK\r\n"); + wait(1); + modem_at_cmd(msg4,(int)strlen(msg4)); + pc.printf("Inviato JOIN\r\n"); + wait4join(); + //pc.printf("+JoinAccepted\r\n"); + pc.printf("\r\n"); + //modem_at_cmd(msg5,(int)strlen(msg5)); + //pc.printf("Inviato send\r\n"); +} + +void modem_at_cmd(char* buffer, int n) +{ + for(uint8_t i=0; i<n; i++) { + lora.putc(buffer[i]); + pc.putc(buffer[i]); + } + lora.putc(13);//CR + pc.putc(13); + pc.printf("\n"); + c=0; + do { + if (lora.readable()) { + c = lora.getc(); + pc.putc(c); + } + } while(c!=' '); +} - magnetometer->get_m_axes(axes); - printf("LSM303AGR [mag/mgauss]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); - - accelerometer->get_x_axes(axes); - printf("LSM303AGR [acc/mg]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); +void wait4join() +{ + c=0; + do { + if (lora.readable()) { + c = lora.getc(); + pc.putc(c); + } + } while(c!='d');// Perchè il messaggio di successo è +JoinAccepted +} + +// invia messaggio +void inviaMessaggio(float maxValueX,uint8_t M_cx_f,float maxValueY,uint8_t M_cy_f, float maxValueZ,uint8_t M_cz_f) +{ + int i; + + + // azzera vettori + memset(msg5,0,64*sizeof(char)); + memset(msg6,0,80*sizeof(char)); - acc_gyro->get_x_axes(axes); - printf("LSM6DSL [acc/mg]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); + // comporre il JSON + + sprintf(msg5,"%f, %d; %f, %d; %f, %d;", maxValueX, M_cx_f, maxValueY, M_cy_f, maxValueZ, M_cz_f ); + //printf("Compongo msg5 \r\n"); + pc.printf(" Il messaggio da inviare e': %s\r\n",msg5); + + //pc.printf(msg5); + //printf("\r\n"); + //printf("Lunghezza messaggio %d",(int)strlen(msg5)); + //printf("\r\n"); - acc_gyro->get_g_axes(axes); - printf("LSM6DSL [gyro/mdps]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); + int len = sprintf(msg6,"AT+SEND="); + + len += sprintf(msg6+len,"15"); + len += sprintf(msg6+len,","); - wait(1.5); - } + for(i=0; i<strlen(msg5); i++) { + sprintf(msg6+len+2*i,"%X",*(msg5+i)); + } + sprintf(msg6+len+2*i,",0"); + modem_at_cmd(msg6,(int)strlen(msg6)); + pc.printf("Inviato send\r\n"); }