Prueba LoRa

Dependencies:   BLE_API SX1276Lib mbed nRF51822

Fork of BLE_Observer by Bluetooth Low Energy

main.cpp

Committer:
Javier117
Date:
2016-11-02
Revision:
8:3b30027c7e8f
Parent:
7:88f50499af9a

File content as of revision 8:3b30027c7e8f:

/* mbed Microcontroller Library
 * Copyright (c) 2006-2015 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mbed.h"
#include "ble/BLE.h"
#include "sx1276-hal.h"
#include "main.h"

//Configuración del radio LoRa
#define USE_MODEM_LORA 1

#define RF_FREQUENCY                                    915000000 //
#define TX_OUTPUT_POWER                                 14 //14 dBm

    #define LORA_BANDWIDTH                              1         // [0: 125 kHz,
                                                                  //  1: 250 kHz,
                                                                  //  2: 500 kHz,
                                                                  //  3: Reserved]
    #define LORA_SPREADING_FACTOR                       10         // [SF7..SF12]
    #define LORA_CODINGRATE                             1         // [1: 4/5,
                                                                  //  2: 4/6,
                                                                  //  3: 4/7,
                                                                  //  4: 4/8]
    #define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx
    #define LORA_SYMBOL_TIMEOUT                         5         // Symbols
    #define LORA_FIX_LENGTH_PAYLOAD_ON                  false
    #define LORA_FHSS_ENABLED                           true  
    #define LORA_NB_SYMB_HOP                            4     
    #define LORA_IQ_INVERSION_ON                        false
    #define LORA_CRC_ENABLED                            true
    
#define RX_TIMEOUT_VALUE                                3500000   // in us
#define BUFFER_SIZE                                     40        // Define the payload size here [min:1 max:255]

/*
 *  Global variables declarations
 */
typedef enum
{
    LOWPOWER = 0,
    IDLE,
    
    RX,
    RX_TIMEOUT,
    RX_ERROR,
    
    TX,
    TX_TIMEOUT,
    
    CAD,
    CAD_DONE
}AppStates_t;

volatile AppStates_t State = LOWPOWER;

/*!
 * Radio events function pointer
 */
static RadioEvents_t RadioEvents;

/*
 *  Global variables declarations
 */
SX1276MB1xAS Radio( NULL );

uint16_t BufferSize = BUFFER_SIZE;
uint8_t Buffer[BUFFER_SIZE];

int16_t RssiValue = 0.0;
int8_t SnrValue = 0.0;

DigitalOut led1(LED1, 1);
DigitalOut led(LED2, 1);
Ticker     ticker;
Serial pc(USBTX, USBRX);

const unsigned int nMax = 10;
const float dZero = 0.65; //Distancia de la señal de referencia
const float pdBZero = -55.0665; //Potencia de la señal de referencia
//const int coord[4][2] = {{0, 6}, {6, 6}, {0, 0}, {6, 0}}; //Coordenadas de dos beacons
const float coord[4][2] = {{0.55, 5}, {7.95, 5}, {7.95, 0.68}, {0.65, 0.68}}; //Coordenadas de dos beacons
//const int coord[2][2] = {{0, 6}, {6, 6}}; //Coordenadas de dos beacons
const int k = 1; //Grado de estimación
const int n = 4; //Índice de pérdidas por trayectoria  
const int nBeacons = 4; //Número de beacons
float d[nMax];
float w[nMax];

int8_t rssi[nMax];
int8_t dir[nMax];
int8_t addr[nMax];
int8_t dirAux[nMax];
int8_t rssiRcv[4] = {0};
uint8_t i = 0;
uint16_t cPqt = 1;

//Declaración de funciones
void printData();
void getCoord (float weigth[], int c);

void periodicCallback(void)
{
    led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
}

void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
{
    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)) {
        dir[i] = params->peerAddr[0];
        dirAux[i] = params->peerAddr[5];
        rssi[i] = params->rssi;
        //printf("Dir: [%d][%d], Iter: %d\r\n", dir[i], dirAux, i);
        i++;

        if (i==nMax) {
            for (int j = 0; j < nMax; j++) {
                if (dir[j] == -126 && dirAux[j] == -80) {
                    addr[j] = 4;
                    rssiRcv[3] = rssi[j];
                } else if (dir[j] == 0x01) {
                    addr[j] = 1;
                    rssiRcv[0] = rssi[j];
                } else if (dir[j] == 0x02) {
                    addr[j] = 3;
                    rssiRcv[2] = rssi[j];
                } else if (dir[j] == -126 && dirAux[j] == 104) {
                    addr[j] = 2;
                    rssiRcv[1] = rssi[j];
                }
                //printf("Dir: %02x RSSI: %d\r\n", addr[j], rssi[j]);
            }

            i=0;
            for (int u = 0; u < nBeacons; u++) {
                //printf("RSSI: %d\r\n", rssiRcv[u]);
                w[u] = 0;
                if (rssiRcv[u] != 0) {
                    //c++;
                    switch (u) {
                        case 0: // 82
                            d[0] = dZero*pow((float)10, ((pdBZero-rssiRcv[0])/(10*n)));
                            w[0] = pow(d[0], (float)(k*-1));
                            //printf("BLE 1, RSSI: %d, d: %f, w: %f\r\n", rssiRcv[0], d[0], w[0]);
                            break;
                        case 1: // 1
                            d[1] = dZero*pow((float)10, ((pdBZero-rssiRcv[1])/(10*n)));
                            w[1] = pow(d[1], (float)(k*-1));
                            //printf("BLE 2, RSSI: %d, d: %f, w: %f\r\n", rssiRcv[1], d[1], w[1]);
                            break;
                        case 2: //2
                            d[2] = dZero*pow((float)10, ((pdBZero-rssiRcv[2])/(10*n)));
                            w[2] = pow(d[2], (float)(k*-1));
                            //printf("BLE 3, RSSI: %d, d: %f, w: %f\r\n", rssiRcv[2], d[2], w[2]);
                            break;
                        case 3: //68
                            d[3] = dZero*pow((float)10, ((pdBZero-rssiRcv[3])/(10*n)));
                            w[3] = pow(d[3], (float)(k*-1));
                            //printf("BLE 4, RSSI: %d, d: %f, w: %f\r\n", rssiRcv[3], d[3], w[3]);
                            break;
                    }
                }

                rssiRcv[u] = 0;
            }

            getCoord(w, 4);
        }
    }
}

        /*

        #if DUMP_ADV_DATA
            for (unsigned index = 0; index < params->advertisingDataLen; index++) {
                printf("%02x ", params->advertisingData[index]);
            }
            printf("\r\n");
        #endif */ /* DUMP_ADV_DATA */

/* 
    Weighted Centroid Localization (WCL) Algorithm
*/
void getCoord (float weigth[], int d)
{
    int i, j;
    float nCoord[4][2] = {0};
    float c[2] = {0};
    float wAuxSum = 0;
    State = TX;
    for (i=0; i<4; i++)
    {
        wAuxSum += weigth[i];
        for (j=0; j<2; j++) {
            nCoord[i][j] = weigth[i]*coord[i][j];
            }
    }
    
    for (i=0; i<2; i++) {
        for (j=0; j<4; j++)
            c[i] += nCoord[j][i]/wAuxSum;
    }

    printf("Coordenadas: (%f, %f)\r\n", c[0], c[1]);
    sprintf((char*) Buffer, "Coordenadas: (%f, %f) No.%d", c[0], c[1], cPqt);  
    cPqt++;
    Radio.Send( Buffer, BufferSize );
    State = LOWPOWER;
}



/**
 * This function is called when the ble initialization process has failed
 */
void onBleInitError(BLE &ble, ble_error_t error)
{
    /* Initialization error handling should go here */
}

/**
 * Callback triggered when the ble initialization process has finished
 */
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{
    BLE&        ble   = params->ble;
    ble_error_t error = params->error;

    if (error != BLE_ERROR_NONE) {
        /* In case of error, forward the error handling to onBleInitError */
        onBleInitError(ble, error);
        return;
    }

    /* Ensure that it is the default instance of BLE */
    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
        return;
    }

    ble.gap().setScanParams(200 /* scan interval */, 200 /* scan window */);
    ble.gap().startScan(advertisementCallback);
}

int main(void)
{
    // Configuración del radio LoRa
    bool isMaster = true;
    // Initialize Radio driver
    RadioEvents.TxDone = OnTxDone;
    RadioEvents.RxDone = OnRxDone;
    RadioEvents.RxError = OnRxError;
    RadioEvents.TxTimeout = OnTxTimeout;
    RadioEvents.RxTimeout = OnRxTimeout;
    RadioEvents.FhssChangeChannel = OnFhssChangeChannel;
    Radio.Init( &RadioEvents );
    ticker.attach(periodicCallback, 1);

    Radio.SetChannel( HoppingFrequencies[0] ); 
    
    Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
                       LORA_SPREADING_FACTOR, LORA_CODINGRATE,
                       LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
                       LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
                       LORA_IQ_INVERSION_ON, 4000000 );

    Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
                       LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
                       LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
                       LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
                       LORA_IQ_INVERSION_ON, true );

    BLE &ble = BLE::Instance();
    ble.init(bleInitComplete);

    pc.baud(9600);
    printf("Iniciando BLE Observer\r\n");
    
    //Transmisión de prueba LOL
    const uint8_t PingMsg[] = "TxRx";
    strcpy( ( char* )Buffer, ( char* )PingMsg );     
    Radio.Send( Buffer, BufferSize );
    
    wait(15);

    while (true) {
        ble.waitForEvent();
    }
}


void OnTxDone( void )
{
    Radio.SetChannel( HoppingFrequencies[0] );
    Radio.Sleep( );
    State = TX;
    //debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" );
}

void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
{
    Radio.SetChannel( HoppingFrequencies[0] );
    Radio.Sleep( );
    BufferSize = size;
    memcpy( Buffer, payload, BufferSize );
    RssiValue = rssi;
    SnrValue = snr;
    State = RX;
    //debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" );
}

void OnTxTimeout( void )
{
    Radio.SetChannel( HoppingFrequencies[0] );
    Radio.Sleep( );
    State = TX_TIMEOUT;
    //debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" );
}

void OnRxTimeout( void )
{
    Radio.SetChannel( HoppingFrequencies[0] );
    Radio.Sleep( );
    Buffer[ BufferSize ] = 0;
    State = RX_TIMEOUT;
    //debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" );
}

void OnRxError( void )
{
    Radio.SetChannel( HoppingFrequencies[0] );
    Radio.Sleep( );
    State = RX_ERROR;
    //debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" );
}

void OnFhssChangeChannel( uint8_t channelIndex )
{
    Radio.SetChannel( HoppingFrequencies[channelIndex] );
    //debug_if( DEBUG_MESSAGE, "F%d-", channelIndex);
}