insist / Mbed 2 deprecated IKS02A1_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>&copy; 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");
}