Prueba LoRa

Dependencies:   BLE_API SX1276Lib mbed nRF51822

Fork of BLE_Observer by Bluetooth Low Energy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include "ble/BLE.h"
00019 #include "sx1276-hal.h"
00020 #include "main.h"
00021 
00022 //Configuración del radio LoRa
00023 #define USE_MODEM_LORA 1
00024 
00025 #define RF_FREQUENCY                                    915000000 //
00026 #define TX_OUTPUT_POWER                                 14 //14 dBm
00027 
00028     #define LORA_BANDWIDTH                              1         // [0: 125 kHz,
00029                                                                   //  1: 250 kHz,
00030                                                                   //  2: 500 kHz,
00031                                                                   //  3: Reserved]
00032     #define LORA_SPREADING_FACTOR                       10         // [SF7..SF12]
00033     #define LORA_CODINGRATE                             1         // [1: 4/5,
00034                                                                   //  2: 4/6,
00035                                                                   //  3: 4/7,
00036                                                                   //  4: 4/8]
00037     #define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx
00038     #define LORA_SYMBOL_TIMEOUT                         5         // Symbols
00039     #define LORA_FIX_LENGTH_PAYLOAD_ON                  false
00040     #define LORA_FHSS_ENABLED                           true  
00041     #define LORA_NB_SYMB_HOP                            4     
00042     #define LORA_IQ_INVERSION_ON                        false
00043     #define LORA_CRC_ENABLED                            true
00044     
00045 #define RX_TIMEOUT_VALUE                                3500000   // in us
00046 #define BUFFER_SIZE                                     40        // Define the payload size here [min:1 max:255]
00047 
00048 /*
00049  *  Global variables declarations
00050  */
00051 typedef enum
00052 {
00053     LOWPOWER = 0,
00054     IDLE,
00055     
00056     RX,
00057     RX_TIMEOUT,
00058     RX_ERROR,
00059     
00060     TX,
00061     TX_TIMEOUT,
00062     
00063     CAD,
00064     CAD_DONE
00065 }AppStates_t;
00066 
00067 volatile AppStates_t State = LOWPOWER;
00068 
00069 /*!
00070  * Radio events function pointer
00071  */
00072 static RadioEvents_t RadioEvents;
00073 
00074 /*
00075  *  Global variables declarations
00076  */
00077 SX1276MB1xAS Radio( NULL );
00078 
00079 uint16_t BufferSize = BUFFER_SIZE;
00080 uint8_t Buffer[BUFFER_SIZE];
00081 
00082 int16_t RssiValue = 0.0;
00083 int8_t SnrValue = 0.0;
00084 
00085 DigitalOut led1(LED1, 1);
00086 DigitalOut led(LED2, 1);
00087 Ticker     ticker;
00088 Serial pc(USBTX, USBRX);
00089 
00090 const unsigned int nMax = 10;
00091 const float dZero = 0.65; //Distancia de la señal de referencia
00092 const float pdBZero = -55.0665; //Potencia de la señal de referencia
00093 //const int coord[4][2] = {{0, 6}, {6, 6}, {0, 0}, {6, 0}}; //Coordenadas de dos beacons
00094 const float coord[4][2] = {{0.55, 5}, {7.95, 5}, {7.95, 0.68}, {0.65, 0.68}}; //Coordenadas de dos beacons
00095 //const int coord[2][2] = {{0, 6}, {6, 6}}; //Coordenadas de dos beacons
00096 const int k = 1; //Grado de estimación
00097 const int n = 4; //Índice de pérdidas por trayectoria  
00098 const int nBeacons = 4; //Número de beacons
00099 float d[nMax];
00100 float w[nMax];
00101 
00102 int8_t rssi[nMax];
00103 int8_t dir[nMax];
00104 int8_t addr[nMax];
00105 int8_t dirAux[nMax];
00106 int8_t rssiRcv[4] = {0};
00107 uint8_t i = 0;
00108 uint16_t cPqt = 1;
00109 
00110 //Declaración de funciones
00111 void printData();
00112 void getCoord (float weigth[], int c);
00113 
00114 void periodicCallback(void)
00115 {
00116     led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
00117 }
00118 
00119 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
00120 {
00121     if ((params->peerAddr[0] == 0x82 && params->peerAddr[5] == 0x68 && i<=nMax) || (params->peerAddr[0] == 0x02 && params->peerAddr[5] == 0xb0 && i<=nMax) || (params->peerAddr[0] == 0x01 && params->peerAddr[5] == 0xc4 && i<=nMax) || (params->peerAddr[0] == 0x82 && params->peerAddr[5] == 0xb0 && i<=nMax)) {
00122         dir[i] = params->peerAddr[0];
00123         dirAux[i] = params->peerAddr[5];
00124         rssi[i] = params->rssi;
00125         //printf("Dir: [%d][%d], Iter: %d\r\n", dir[i], dirAux, i);
00126         i++;
00127 
00128         if (i==nMax) {
00129             for (int j = 0; j < nMax; j++) {
00130                 if (dir[j] == -126 && dirAux[j] == -80) {
00131                     addr[j] = 4;
00132                     rssiRcv[3] = rssi[j];
00133                 } else if (dir[j] == 0x01) {
00134                     addr[j] = 1;
00135                     rssiRcv[0] = rssi[j];
00136                 } else if (dir[j] == 0x02) {
00137                     addr[j] = 3;
00138                     rssiRcv[2] = rssi[j];
00139                 } else if (dir[j] == -126 && dirAux[j] == 104) {
00140                     addr[j] = 2;
00141                     rssiRcv[1] = rssi[j];
00142                 }
00143                 //printf("Dir: %02x RSSI: %d\r\n", addr[j], rssi[j]);
00144             }
00145 
00146             i=0;
00147             for (int u = 0; u < nBeacons; u++) {
00148                 //printf("RSSI: %d\r\n", rssiRcv[u]);
00149                 w[u] = 0;
00150                 if (rssiRcv[u] != 0) {
00151                     //c++;
00152                     switch (u) {
00153                         case 0: // 82
00154                             d[0] = dZero*pow((float)10, ((pdBZero-rssiRcv[0])/(10*n)));
00155                             w[0] = pow(d[0], (float)(k*-1));
00156                             //printf("BLE 1, RSSI: %d, d: %f, w: %f\r\n", rssiRcv[0], d[0], w[0]);
00157                             break;
00158                         case 1: // 1
00159                             d[1] = dZero*pow((float)10, ((pdBZero-rssiRcv[1])/(10*n)));
00160                             w[1] = pow(d[1], (float)(k*-1));
00161                             //printf("BLE 2, RSSI: %d, d: %f, w: %f\r\n", rssiRcv[1], d[1], w[1]);
00162                             break;
00163                         case 2: //2
00164                             d[2] = dZero*pow((float)10, ((pdBZero-rssiRcv[2])/(10*n)));
00165                             w[2] = pow(d[2], (float)(k*-1));
00166                             //printf("BLE 3, RSSI: %d, d: %f, w: %f\r\n", rssiRcv[2], d[2], w[2]);
00167                             break;
00168                         case 3: //68
00169                             d[3] = dZero*pow((float)10, ((pdBZero-rssiRcv[3])/(10*n)));
00170                             w[3] = pow(d[3], (float)(k*-1));
00171                             //printf("BLE 4, RSSI: %d, d: %f, w: %f\r\n", rssiRcv[3], d[3], w[3]);
00172                             break;
00173                     }
00174                 }
00175 
00176                 rssiRcv[u] = 0;
00177             }
00178 
00179             getCoord(w, 4);
00180         }
00181     }
00182 }
00183 
00184         /*
00185 
00186         #if DUMP_ADV_DATA
00187             for (unsigned index = 0; index < params->advertisingDataLen; index++) {
00188                 printf("%02x ", params->advertisingData[index]);
00189             }
00190             printf("\r\n");
00191         #endif */ /* DUMP_ADV_DATA */
00192 
00193 /* 
00194     Weighted Centroid Localization (WCL) Algorithm
00195 */
00196 void getCoord (float weigth[], int d)
00197 {
00198     int i, j;
00199     float nCoord[4][2] = {0};
00200     float c[2] = {0};
00201     float wAuxSum = 0;
00202     State = TX;
00203     for (i=0; i<4; i++)
00204     {
00205         wAuxSum += weigth[i];
00206         for (j=0; j<2; j++) {
00207             nCoord[i][j] = weigth[i]*coord[i][j];
00208             }
00209     }
00210     
00211     for (i=0; i<2; i++) {
00212         for (j=0; j<4; j++)
00213             c[i] += nCoord[j][i]/wAuxSum;
00214     }
00215 
00216     printf("Coordenadas: (%f, %f)\r\n", c[0], c[1]);
00217     sprintf((char*) Buffer, "Coordenadas: (%f, %f) No.%d", c[0], c[1], cPqt);  
00218     cPqt++;
00219     Radio.Send( Buffer, BufferSize );
00220     State = LOWPOWER;
00221 }
00222 
00223 
00224 
00225 /**
00226  * This function is called when the ble initialization process has failed
00227  */
00228 void onBleInitError(BLE &ble, ble_error_t error)
00229 {
00230     /* Initialization error handling should go here */
00231 }
00232 
00233 /**
00234  * Callback triggered when the ble initialization process has finished
00235  */
00236 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
00237 {
00238     BLE&        ble   = params->ble;
00239     ble_error_t error = params->error;
00240 
00241     if (error != BLE_ERROR_NONE) {
00242         /* In case of error, forward the error handling to onBleInitError */
00243         onBleInitError(ble, error);
00244         return;
00245     }
00246 
00247     /* Ensure that it is the default instance of BLE */
00248     if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
00249         return;
00250     }
00251 
00252     ble.gap().setScanParams(200 /* scan interval */, 200 /* scan window */);
00253     ble.gap().startScan(advertisementCallback);
00254 }
00255 
00256 int main(void)
00257 {
00258     // Configuración del radio LoRa
00259     bool isMaster = true;
00260     // Initialize Radio driver
00261     RadioEvents.TxDone = OnTxDone;
00262     RadioEvents.RxDone = OnRxDone;
00263     RadioEvents.RxError = OnRxError;
00264     RadioEvents.TxTimeout = OnTxTimeout;
00265     RadioEvents.RxTimeout = OnRxTimeout;
00266     RadioEvents.FhssChangeChannel = OnFhssChangeChannel;
00267     Radio.Init( &RadioEvents );
00268     ticker.attach(periodicCallback, 1);
00269 
00270     Radio.SetChannel( HoppingFrequencies[0] ); 
00271     
00272     Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
00273                        LORA_SPREADING_FACTOR, LORA_CODINGRATE,
00274                        LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
00275                        LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
00276                        LORA_IQ_INVERSION_ON, 4000000 );
00277 
00278     Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
00279                        LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
00280                        LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
00281                        LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
00282                        LORA_IQ_INVERSION_ON, true );
00283 
00284     BLE &ble = BLE::Instance();
00285     ble.init(bleInitComplete);
00286 
00287     pc.baud(9600);
00288     printf("Iniciando BLE Observer\r\n");
00289     
00290     //Transmisión de prueba LOL
00291     const uint8_t PingMsg[] = "TxRx";
00292     strcpy( ( char* )Buffer, ( char* )PingMsg );     
00293     Radio.Send( Buffer, BufferSize );
00294     
00295     wait(15);
00296 
00297     while (true) {
00298         ble.waitForEvent();
00299     }
00300 }
00301 
00302 
00303 void OnTxDone( void )
00304 {
00305     Radio.SetChannel( HoppingFrequencies[0] );
00306     Radio.Sleep( );
00307     State = TX;
00308     //debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" );
00309 }
00310 
00311 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
00312 {
00313     Radio.SetChannel( HoppingFrequencies[0] );
00314     Radio.Sleep( );
00315     BufferSize = size;
00316     memcpy( Buffer, payload, BufferSize );
00317     RssiValue = rssi;
00318     SnrValue = snr;
00319     State = RX;
00320     //debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" );
00321 }
00322 
00323 void OnTxTimeout( void )
00324 {
00325     Radio.SetChannel( HoppingFrequencies[0] );
00326     Radio.Sleep( );
00327     State = TX_TIMEOUT;
00328     //debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" );
00329 }
00330 
00331 void OnRxTimeout( void )
00332 {
00333     Radio.SetChannel( HoppingFrequencies[0] );
00334     Radio.Sleep( );
00335     Buffer[ BufferSize ] = 0;
00336     State = RX_TIMEOUT;
00337     //debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" );
00338 }
00339 
00340 void OnRxError( void )
00341 {
00342     Radio.SetChannel( HoppingFrequencies[0] );
00343     Radio.Sleep( );
00344     State = RX_ERROR;
00345     //debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" );
00346 }
00347 
00348 void OnFhssChangeChannel( uint8_t channelIndex )
00349 {
00350     Radio.SetChannel( HoppingFrequencies[channelIndex] );
00351     //debug_if( DEBUG_MESSAGE, "F%d-", channelIndex);
00352 }