Programma per monitoraggio del ponte con nodo sensore composto da IKS02A1 e modulo LoRaWAN
Dependencies: mbed X_NUCLEO_IKS01A2 mbed-dsp
main.cpp
- Committer:
- Ignazio
- Date:
- 2021-10-11
- Revision:
- 18:b35e44c016c2
- Parent:
- 13:fc873da5b445
File content as of revision 18:b35e44c016c2:
/**
******************************************************************************
* @file main.cpp
* @author CLab
* @version V1.0.0
* @date 2-December-2016
* @brief Simple Example application for using the X_NUCLEO_IKS01A1
* MEMS Inertial & Environmental Sensor Nucleo expansion board.
******************************************************************************
* @attention
*
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* 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);
static LSM6DSLSensor *acc_gyro = mems_expansion_board->acc_gyro;
//Seriali
Serial pc(USBTX, USBRX,115200);
I2C i2c(D14, D15);
/* 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
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];
/* Timer */
//Timer tempo, temp;
//Ticker tic;
void sample()
{
trig=1;
}
int calcolare_max(float* Vettore)
{
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;
}
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);
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)
void setup_lora()
{
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!=' ');
}
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));
// 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");
int len = sprintf(msg6,"AT+SEND=");
len += sprintf(msg6+len,"15");
len += sprintf(msg6+len,",");
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");
}