SunTracker_BLE_Remote

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 X_NUCLEO_IKS01A1 mbed

Fork of SunTracker_BLE_Remote by ST Expansion SW Team

This application is the BLE Remote Control for the SunTracker demo application that you can find here.
Please refer to that page for further information.

main.cpp

Committer:
fabiombed
Date:
2016-03-16
Revision:
4:17f96ffc073a
Parent:
3:b2bf47485f85
Child:
5:5e62f661a7ab

File content as of revision 4:17f96ffc073a:

/**
 ******************************************************************************
 * @file    main.cpp
 * @author  Fabio Brembilla
 * @version V2.0.0
 * @date    March, 2016
 * @brief   SunTracker + BLE (Client) + RemoteControl Vertical Application
 *          This application use IKS01A1, IDB0XA1 expansion boards
 ******************************************************************************
 * @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.
 *
 ******************************************************************************
 */

/* Define --------------------------------------------------------------------*/

#define Sensors     //IKS01A1 Option

/* Includes ------------------------------------------------------------------*/

#include "mbed.h"
#include "ble/BLE.h"
#include "ble/DiscoveredCharacteristic.h"
#include "ble/DiscoveredService.h"

#ifdef Sensors
    #include "DevI2C.h"
    #include "x_nucleo_iks01a1.h"
#endif

/* BlueTooth -----------------------------------------------------------------*/

#define SCAN_INT  0x30 // 30 ms = 48 * 0.625 ms
#define SCAN_WIND 0x30 // 30 ms = 48 * 0.625 ms

const Gap::Address_t  BLE_address_BE       = {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA};  // CLIENT address
const Gap::Address_t  BLE_peer_address_BE  = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};  // SERVER address (must be the same of SERVER)
//const Gap::Address_t  BLE_address_BE       = {0xCC, 0x00, 0x00, 0xE1, 0x80, 0x02};  // CLIENT address
//const Gap::Address_t  BLE_peer_address_BE  = {0xFD, 0x66, 0x05, 0x13, 0xBE, 0xBA};  // SERVER address (must be the same of SERVER)

DiscoveredCharacteristic userbutton_bleCharacteristic;
DiscoveredCharacteristic difference_bleCharacteristic;
DiscoveredCharacteristic position_bleCharacteristic;
DiscoveredCharacteristic sunpanel_bleCharacteristic;

uint8_t value_write = 1;
int32_t value_read = 0;

/* Initializations ------------------------------------------------------------*/

#ifdef Sensors    

// Initializing I2C bus
DevI2C dev_i2c(D14, D15);

// Initializing Sensors Component IKS01A1
static X_NUCLEO_IKS01A1 *mems;
MotionSensor *accelerometer;

int32_t acc_data[3];    // Accelerometer difference
int32_t diff=0;         // Accelerometer difference
#endif

InterruptIn mybutton(USER_BUTTON);

/* User_Button_Pressed -------------------------------------------------------*/

void User_Button_Pressed(void)
{
    userbutton_bleCharacteristic.write(1, &value_write);
}

/* Bluetooth CallBack ---------------------------------------------------------*/

void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
{    
    if (params->peerAddr[0] != BLE_peer_address_BE[0]) // return if miss the server MAC address
    { 
        printf("Missing Expected MAC Address");
        return; // exit from advertisementCallback
    }
    
//    printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
//           params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
//           params->rssi, params->isScanResponse, params->type);

    printf("Found Expected MAC Address: isScanResponse %u, AdvertisementType %u\r\n",params->isScanResponse, params->type);
    
    if(!params->isScanResponse)
    {
      BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_PUBLIC, NULL, NULL);
    }
}

void serviceDiscoveryCallback(const DiscoveredService *service)
{
    printf("Start Service Discovery\r\n");
/*
    if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT)
    {
        printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());
    }
    else
    {
        printf("S UUID-");
        const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
        for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++)
        {
            printf("%02X", longUUIDBytes[i]);
        }
        printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());
    }
*/    
}

void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP)
{   
    if (characteristicP->getUUID().getShortUUID() == 0xA001)
    {
        userbutton_bleCharacteristic = *characteristicP;
        printf("Found 0xA001 Characteristic\r\n");
    }
    
    if (characteristicP->getUUID().getShortUUID() == 0xB001)
    {
        difference_bleCharacteristic = *characteristicP;    
        printf("Found 0xB001 Characteristic\r\n");
    }
    
    if (characteristicP->getUUID().getShortUUID() == 0xB002)
    {
        position_bleCharacteristic = *characteristicP;
        printf("Found 0xB002 Characteristic\r\n");
    }
    
    if (characteristicP->getUUID().getShortUUID() == 0xB003)
    {
        sunpanel_bleCharacteristic = *characteristicP;
        printf("Found 0xB003 Characteristic\r\n");
    }
}

void discoveryTerminationCallback(Gap::Handle_t connectionHandle)
{
    //printf("discoveryTerminationCallback for handle %u\r\n", connectionHandle);
    printf("Stop Service Discovery\r\n\r\n");
}

void onDataReadCallback(const GattReadCallbackParams *response)
{
    // Read SERVER --> CLIENT
    
    if (response->handle == userbutton_bleCharacteristic.getValueHandle())
    {                 
        printf("onDataRead userbutton (data[0] %x)\r\n", response->data[0]);
        printf("onDataRead userbutton (data[1] %x)\r\n", response->data[1]);
        printf("onDataRead userbutton (data[2] %x)\r\n", response->data[2]);
        printf("onDataRead userbutton (data[3] %x)\r\n\r\n", response->data[3]);
    }
    
    if (response->handle == difference_bleCharacteristic.getValueHandle())
    {         
        printf("onDataRead difference (data[0] %x)\r\n", response->data[0]);
        printf("onDataRead difference (data[1] %x)\r\n", response->data[1]);
        printf("onDataRead difference (data[2] %x)\r\n", response->data[2]);
        printf("onDataRead difference (data[3] %x)\r\n\r\n", response->data[3]);
    }
    
    if (response->handle == position_bleCharacteristic.getValueHandle())
    {          
        printf("onDataRead position (data[0] %x)\r\n", response->data[0]);
        printf("onDataRead position (data[1] %x)\r\n", response->data[1]);
        printf("onDataRead position (data[2] %x)\r\n", response->data[2]);
        printf("onDataRead position (data[3] %x)\r\n\r\n", response->data[3]);
    }
    
    if (response->handle == sunpanel_bleCharacteristic.getValueHandle())
    {            
        printf("onDataRead sunpanel (data[0] %x)\r\n", response->data[0]);
        printf("onDataRead sunpanel (data[1] %x)\r\n", response->data[1]);
        printf("onDataRead sunpanel (data[2] %x)\r\n", response->data[2]);
        printf("onDataRead sunpanel (data[3] %x)\r\n", response->data[3]);
        
        value_read = response->data[0]+response->data[1]+response->data[2]+response->data[3];       
        printf("onDataRead sunpanel (data %d)\r\n\r\n", value_read);
    }
}

void myonDataWriteCallback(const GattWriteCallbackParams *response)
{
    // Write CLIENT --> SERVER

    if (response->handle == userbutton_bleCharacteristic.getValueHandle())
    {
        printf("myonDataWrite userbutton (data[0] %x)\n\r", response->data[0]);
        printf("myonDataWrite userbutton (data[1] %x)\n\r", response->data[1]);
        printf("myonDataWrite userbutton (data[2] %x)\n\r", response->data[2]);
        printf("myonDataWrite userbutton (data[3] %x)\n\r\n\r", response->data[3]);
    }
}

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

void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
{
    //uint16_t CONTROL_SERVICE_UUID = 0xA000;
    //uint16_t USERBUTTON_CHARACTERISTIC_UUID = 0xA001;

    //uint16_t SENSORS_SERVICE_UUID = 0xB000;
    //uint16_t DIFFERENCE_CHARACTERISTIC_UUID = 0xB001;
    //uint16_t POSITION_CHARACTERISTIC_UUID = 0xB002;
    //uint16_t SUNPANEL_CHARACTERISTIC_UUID = 0xB003;    
    
    if (params->role == Gap::CENTRAL)
    {
        BLE &ble = BLE::Instance();
        ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
        // Discover all SERVICES and CHARACTERISTICS
        ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback);
        
        //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, CONTROL_SERVICE_UUID, USERBUTTON_CHARACTERISTIC_UUID);  
        //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, SENSORS_SERVICE_UUID, DIFFERENCE_CHARACTERISTIC_UUID);
        //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, SENSORS_SERVICE_UUID, POSITION_CHARACTERISTIC_UUID);
        //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, SENSORS_SERVICE_UUID, SUNPANEL_CHARACTERISTIC_UUID);
    }
    
    printf("Remote Connected\n\r");
}

void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    (void)params;
    printf("Remote Disconnected\n\r");
}

/** 
 * 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; }

    // Set BT Address
    ble.gap().setAddress(BLEProtocol::AddressType::PUBLIC, BLE_address_BE);

    ble.gap().onConnection(connectionCallback);
    ble.onDisconnection(disconnectionCallback);
       
    ble.gattClient().onDataRead(onDataReadCallback);
    ble.gattClient().onDataWrite(myonDataWriteCallback);

    ble.gap().setScanParams(SCAN_INT, SCAN_WIND);
    ble.gap().startScan(advertisementCallback);
    
    static int INTLOOP=0;
    
    // Main Loop
    while (true) {
        if (!ble.gattClient().isServiceDiscoveryActive()) // Until try to discover service don't enter
        {       
            INTLOOP++;
            if (INTLOOP==2000)
            {
                printf("\n\r");
                userbutton_bleCharacteristic.read();
                difference_bleCharacteristic.read();
                position_bleCharacteristic.read();
                sunpanel_bleCharacteristic.read();
                INTLOOP=0;
            }
            
        #ifdef Sensors    
            accelerometer->Get_X_Axes(acc_data);
            diff = acc_data[0];
            //printf("Send BLE Difference %d lux/mems\n\r", diff);
        #endif
                 
        }
        ble.waitForEvent();
    }
}

/* Main ----------------------------------------------------------------------*/

int main(void)
{
    printf("\r\n\r\nSunTracker Remote Control\r\n\r\n");
    
    #ifdef Sensors
    // Initializing Sensors Component
    mems=X_NUCLEO_IKS01A1::Instance(&dev_i2c);
    accelerometer = mems->GetAccelerometer();
    printf("Init Sensors OK\r\n");
    #endif
    
    mybutton.fall(&User_Button_Pressed);
    
    BLE::Instance().init(bleInitComplete);
}