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.

Revision:
4:17f96ffc073a
Parent:
3:b2bf47485f85
Child:
5:5e62f661a7ab
--- a/main.cpp	Fri Feb 26 11:09:13 2016 +0000
+++ b/main.cpp	Wed Mar 16 19:17:57 2016 +0000
@@ -1,117 +1,226 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2006-2013 ARM Limited
+/**
+ ******************************************************************************
+ * @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
  *
- * 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
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ * 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.
  *
- * 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.
+ * 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       = {0xCC, 0x00, 0x00, 0xE1, 0x80, 0x02};
-const Gap::Address_t  BLE_peer_address_BE  = {0xFD, 0x66, 0x05, 0x13, 0xBE, 0xBA};
+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 ledCharacteristic;
+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    
 
-uint8_t toggledValue = 0;
-enum {
-  READ = 0,
-  WRITE,
-  IDLE
-};
-static volatile unsigned int triggerOp = IDLE;
+// Initializing I2C bus
+DevI2C dev_i2c(D14, D15);
+
+// Initializing Sensors Component IKS01A1
+static X_NUCLEO_IKS01A1 *mems;
+MotionSensor *accelerometer;
 
-void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
+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)
 {
-    (void)params;
-    printf("disconnected\n\r");
+    userbutton_bleCharacteristic.write(1, &value_write);
 }
 
-void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {
-    if (params->peerAddr[0] != BLE_peer_address_BE[0]) {
-        return;
+/* 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("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) {
+    if(!params->isScanResponse)
+    {
       BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_PUBLIC, NULL, NULL);
     }
 }
 
-void discoveryTerminationCallback(Gap::Handle_t connectionHandle) {
-    printf("terminated SD for handle %u\r\n", connectionHandle);
-}
-
-void serviceDiscoveryCallback(const DiscoveredService *service) {
-    if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
+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 {
+    }
+    else
+    {
         printf("S UUID-");
         const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
-        for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+        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) {
-    //printf("  C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
-    if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */
-      //printf("  C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
-      ledCharacteristic = *characteristicP;
-      triggerOp = READ;
+
+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 connectionCallback(const Gap::ConnectionCallbackParams_t *params) {
-  uint16_t LED_SERVICE_UUID = 0xA000;
-  uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001;
-  
-  if (params->role == Gap::CENTRAL) {
-    BLE &ble = BLE::Instance();
-    ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
-    ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, LED_SERVICE_UUID, LED_STATE_CHARACTERISTIC_UUID);
-  }
+void discoveryTerminationCallback(Gap::Handle_t connectionHandle)
+{
+    //printf("discoveryTerminationCallback for handle %u\r\n", connectionHandle);
+    printf("Stop Service Discovery\r\n\r\n");
 }
 
-void triggerToggledWrite(const GattReadCallbackParams *response) {
-  if (response->handle == ledCharacteristic.getValueHandle()) {
-#if 0
-    printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len);
-    for (unsigned index = 0; index < response->len; index++) {
-      printf("%c[%02x]", response->data[index], response->data[index]);
+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]);
     }
-    printf("\r\n");
-#endif
+    
+    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]);
+    }
     
-    toggledValue = response->data[0] ^ 0x1;
-    triggerOp = WRITE;
-  }
+    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 triggerRead(const GattWriteCallbackParams *response) {
-  if (response->handle == ledCharacteristic.getValueHandle()) {
-    triggerOp = 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]);
+    }
 }
 
 /** 
@@ -122,6 +231,38 @@
     /* 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 
  */ 
@@ -130,16 +271,15 @@
     BLE&        ble   = params->ble;
     ble_error_t error = params->error;
 
-    if (error != BLE_ERROR_NONE) {
+    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;
-    }
+    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; }
 
     // Set BT Address
     ble.gap().setAddress(BLEProtocol::AddressType::PUBLIC, BLE_address_BE);
@@ -147,31 +287,54 @@
     ble.gap().onConnection(connectionCallback);
     ble.onDisconnection(disconnectionCallback);
        
-    ble.gattClient().onDataRead(triggerToggledWrite);
-    ble.gattClient().onDataWrite(triggerRead);
+    ble.gattClient().onDataRead(onDataReadCallback);
+    ble.gattClient().onDataWrite(myonDataWriteCallback);
 
     ble.gap().setScanParams(SCAN_INT, SCAN_WIND);
     ble.gap().startScan(advertisementCallback);
- 
-    // infinite loop
-    while (1) {
-      if (!ble.gattClient().isServiceDiscoveryActive()) {
-        switch(triggerOp) {
-        case READ:
-          triggerOp = IDLE;
-          ledCharacteristic.read();
-          break;
-        case WRITE:
-          triggerOp = IDLE;
-          ledCharacteristic.write(1, &toggledValue);
-          break;
+    
+    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();
+        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);
-}
\ No newline at end of file
+}