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.

Committer:
fabiombed
Date:
Tue Apr 19 08:53:53 2016 +0000
Revision:
7:eb2215fe86b2
Parent:
6:ce0e5024e3fa
Child:
8:63b01a643f4d
Updated to BlueST Protocol

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fabiombed 4:17f96ffc073a 1 /**
fabiombed 4:17f96ffc073a 2 ******************************************************************************
fabiombed 4:17f96ffc073a 3 * @file main.cpp
fabiombed 4:17f96ffc073a 4 * @author Fabio Brembilla
fabiombed 4:17f96ffc073a 5 * @version V2.0.0
fabiombed 7:eb2215fe86b2 6 * @date April, 2016
fabiombed 5:5e62f661a7ab 7 * @brief SunTracker + BLE (Client) Vertical Application
fabiombed 4:17f96ffc073a 8 * This application use IKS01A1, IDB0XA1 expansion boards
fabiombed 4:17f96ffc073a 9 ******************************************************************************
fabiombed 4:17f96ffc073a 10 * @attention
apalmieri 0:2e972e7d3f64 11 *
fabiombed 4:17f96ffc073a 12 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
apalmieri 0:2e972e7d3f64 13 *
fabiombed 4:17f96ffc073a 14 * Redistribution and use in source and binary forms, with or without modification,
fabiombed 4:17f96ffc073a 15 * are permitted provided that the following conditions are met:
fabiombed 4:17f96ffc073a 16 * 1. Redistributions of source code must retain the above copyright notice,
fabiombed 4:17f96ffc073a 17 * this list of conditions and the following disclaimer.
fabiombed 4:17f96ffc073a 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
fabiombed 4:17f96ffc073a 19 * this list of conditions and the following disclaimer in the documentation
fabiombed 4:17f96ffc073a 20 * and/or other materials provided with the distribution.
fabiombed 4:17f96ffc073a 21 * 3. Neither the name of STMicroelectronics nor the names of its contributors
fabiombed 4:17f96ffc073a 22 * may be used to endorse or promote products derived from this software
fabiombed 4:17f96ffc073a 23 * without specific prior written permission.
apalmieri 0:2e972e7d3f64 24 *
fabiombed 4:17f96ffc073a 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
fabiombed 4:17f96ffc073a 26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
fabiombed 4:17f96ffc073a 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
fabiombed 4:17f96ffc073a 28 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
fabiombed 4:17f96ffc073a 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
fabiombed 4:17f96ffc073a 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
fabiombed 4:17f96ffc073a 31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
fabiombed 4:17f96ffc073a 32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
fabiombed 4:17f96ffc073a 33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
fabiombed 4:17f96ffc073a 34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
fabiombed 4:17f96ffc073a 35 *
fabiombed 4:17f96ffc073a 36 ******************************************************************************
apalmieri 0:2e972e7d3f64 37 */
fabiombed 4:17f96ffc073a 38
fabiombed 4:17f96ffc073a 39 /* Define --------------------------------------------------------------------*/
fabiombed 4:17f96ffc073a 40
fabiombed 4:17f96ffc073a 41 #define Sensors //IKS01A1 Option
fabiombed 4:17f96ffc073a 42
fabiombed 4:17f96ffc073a 43 /* Includes ------------------------------------------------------------------*/
fabiombed 4:17f96ffc073a 44
apalmieri 0:2e972e7d3f64 45 #include "mbed.h"
apalmieri 0:2e972e7d3f64 46
fabiombed 4:17f96ffc073a 47 #ifdef Sensors
fabiombed 4:17f96ffc073a 48 #include "DevI2C.h"
fabiombed 4:17f96ffc073a 49 #include "x_nucleo_iks01a1.h"
fabiombed 4:17f96ffc073a 50 #endif
fabiombed 4:17f96ffc073a 51
fabiombed 4:17f96ffc073a 52 /* BlueTooth -----------------------------------------------------------------*/
fabiombed 4:17f96ffc073a 53
fabiombed 7:eb2215fe86b2 54 #include "BLE.h"
fabiombed 7:eb2215fe86b2 55 #include "UUID.h"
fabiombed 7:eb2215fe86b2 56 #include "DiscoveredCharacteristic.h"
fabiombed 7:eb2215fe86b2 57 #include "DiscoveredService.h"
fabiombed 5:5e62f661a7ab 58 #include "Utils.h" // Need for STORE_LE_16 and STORE_LE_32
fabiombed 5:5e62f661a7ab 59
apalmieri 0:2e972e7d3f64 60 #define SCAN_INT 0x30 // 30 ms = 48 * 0.625 ms
apalmieri 0:2e972e7d3f64 61 #define SCAN_WIND 0x30 // 30 ms = 48 * 0.625 ms
apalmieri 0:2e972e7d3f64 62
fabiombed 7:eb2215fe86b2 63 // Not need to re-define it, it is already defined into UUID.h, just use UUID:: when you call it
fabiombed 7:eb2215fe86b2 64 //const unsigned LENGTH_OF_LONG_UUID = 16;
fabiombed 7:eb2215fe86b2 65 //typedef uint16_t ShortUUIDBytes_t;
fabiombed 7:eb2215fe86b2 66 //typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID];
fabiombed 7:eb2215fe86b2 67
fabiombed 7:eb2215fe86b2 68 //const Gap::Address_t BLE_address_BE = {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA}; // CLIENT address
fabiombed 7:eb2215fe86b2 69 //const Gap::Address_t BLE_peer_address_BE = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; // SERVER address (must be the same of SERVER)
fabiombed 7:eb2215fe86b2 70 const Gap::Address_t BLE_address_BE = {0xCC, 0x00, 0x00, 0xE1, 0x80, 0x02}; // CLIENT address
fabiombed 7:eb2215fe86b2 71 const Gap::Address_t BLE_peer_address_BE = {0xFD, 0x66, 0x05, 0x13, 0xBE, 0xBA}; // SERVER address (must be the same of SERVER)
apalmieri 0:2e972e7d3f64 72
fabiombed 7:eb2215fe86b2 73 //const UUID::ShortUUIDBytes_t CONTROL_COMMAND_CHAR_UUID = 0xA001;
fabiombed 7:eb2215fe86b2 74 //const UUID::ShortUUIDBytes_t SENS_STATUS_CHAR_UUID = 0xB001;
fabiombed 7:eb2215fe86b2 75 //const UUID::ShortUUIDBytes_t SENS_DIFFERENCE_CHAR_UUID = 0xB002;
fabiombed 7:eb2215fe86b2 76 //const UUID::ShortUUIDBytes_t SENS_POSITION_CHAR_UUID = 0xB003;
fabiombed 7:eb2215fe86b2 77 //const UUID::ShortUUIDBytes_t SENS_SUNPANEL_CHAR_UUID = 0xB004;
fabiombed 7:eb2215fe86b2 78 const UUID::LongUUIDBytes_t CONTROL_COMMAND_CHAR_UUID = {0x00,0x00,0x00,0x02,0x00,0x0F,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b};
fabiombed 7:eb2215fe86b2 79 const UUID::LongUUIDBytes_t SENS_STATUS_CHAR_UUID = {0x00,0x00,0x04,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b};
fabiombed 7:eb2215fe86b2 80 const UUID::LongUUIDBytes_t SENS_DIFFERENCE_CHAR_UUID = {0x00,0x00,0x08,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b};
fabiombed 7:eb2215fe86b2 81 const UUID::LongUUIDBytes_t SENS_POSITION_CHAR_UUID = {0x00,0x00,0x10,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b};
fabiombed 7:eb2215fe86b2 82 const UUID::LongUUIDBytes_t SENS_SUNPANEL_CHAR_UUID = {0x00,0x00,0x20,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b};
fabiombed 7:eb2215fe86b2 83
fabiombed 7:eb2215fe86b2 84 DiscoveredCharacteristic command_bleCharacteristic;
fabiombed 7:eb2215fe86b2 85 DiscoveredCharacteristic status_bleCharacteristic;
fabiombed 4:17f96ffc073a 86 DiscoveredCharacteristic difference_bleCharacteristic;
fabiombed 4:17f96ffc073a 87 DiscoveredCharacteristic position_bleCharacteristic;
fabiombed 4:17f96ffc073a 88 DiscoveredCharacteristic sunpanel_bleCharacteristic;
fabiombed 4:17f96ffc073a 89
fabiombed 7:eb2215fe86b2 90 #define COMMAND_DATA_LEN 2+4+1+2 // TimeStamp (only for Response) + Feature + Type + Data
fabiombed 5:5e62f661a7ab 91 // 1 byte 0xFF 8 bit int8
fabiombed 5:5e62f661a7ab 92 // 2 byte 0xFFFF 16 bit int16
fabiombed 5:5e62f661a7ab 93
fabiombed 7:eb2215fe86b2 94 uint8_t value_write[COMMAND_DATA_LEN];
fabiombed 7:eb2215fe86b2 95
fabiombed 7:eb2215fe86b2 96 #define FeatureStatus 0x00000400
fabiombed 7:eb2215fe86b2 97 #define FeatureDifference 0x00000800
fabiombed 7:eb2215fe86b2 98 #define FeaturePosition 0x00001000
fabiombed 7:eb2215fe86b2 99 #define FeatureSunPanel 0x00002000
fabiombed 5:5e62f661a7ab 100
fabiombed 5:5e62f661a7ab 101 /* Variables ------------------------------------------------------------------*/
fabiombed 5:5e62f661a7ab 102
fabiombed 5:5e62f661a7ab 103 enum {
fabiombed 5:5e62f661a7ab 104 IDLE = 0,
fabiombed 7:eb2215fe86b2 105 READ_STA = 1,
fabiombed 5:5e62f661a7ab 106 READ_DIF = 2,
fabiombed 5:5e62f661a7ab 107 READ_POS = 3,
fabiombed 5:5e62f661a7ab 108 READ_SUN = 4,
fabiombed 7:eb2215fe86b2 109 WRITE_STA = 5,
fabiombed 5:5e62f661a7ab 110 WRITE_DIF = 6
fabiombed 5:5e62f661a7ab 111 };
fabiombed 5:5e62f661a7ab 112 int trigger_Op = IDLE;
fabiombed 5:5e62f661a7ab 113 bool trigger_button = false;
fabiombed 5:5e62f661a7ab 114
fabiombed 7:eb2215fe86b2 115 int16_t Status=0; // Status Shown on Display: 0 = Idle, 1 = Motor Speed, 2 = Solar Panel Value, 3 = Manual Control [--> Receive BLE]
fabiombed 5:5e62f661a7ab 116 int16_t diff=0; // Babybear or Accelerometer difference [--> Receive BLE]
fabiombed 5:5e62f661a7ab 117 int16_t pos=0; // Motor Position [--> Receive BLE]
fabiombed 5:5e62f661a7ab 118 int16_t measure=0; // ADC Value from SunPanel [--> Receive BLE]
fabiombed 4:17f96ffc073a 119
fabiombed 4:17f96ffc073a 120 /* Initializations ------------------------------------------------------------*/
fabiombed 4:17f96ffc073a 121
fabiombed 7:eb2215fe86b2 122 #ifdef Sensors
apalmieri 0:2e972e7d3f64 123
fabiombed 4:17f96ffc073a 124 // Initializing I2C bus
fabiombed 4:17f96ffc073a 125 DevI2C dev_i2c(D14, D15);
fabiombed 4:17f96ffc073a 126
fabiombed 4:17f96ffc073a 127 // Initializing Sensors Component IKS01A1
fabiombed 4:17f96ffc073a 128 static X_NUCLEO_IKS01A1 *mems;
fabiombed 4:17f96ffc073a 129 MotionSensor *accelerometer;
apalmieri 0:2e972e7d3f64 130
fabiombed 4:17f96ffc073a 131 int32_t acc_data[3]; // Accelerometer difference
fabiombed 5:5e62f661a7ab 132 int16_t acc_diff=0; // Accelerometer difference
fabiombed 7:eb2215fe86b2 133
fabiombed 4:17f96ffc073a 134 #endif
fabiombed 4:17f96ffc073a 135
fabiombed 4:17f96ffc073a 136 InterruptIn mybutton(USER_BUTTON);
fabiombed 4:17f96ffc073a 137
fabiombed 4:17f96ffc073a 138 /* User_Button_Pressed -------------------------------------------------------*/
fabiombed 4:17f96ffc073a 139
fabiombed 4:17f96ffc073a 140 void User_Button_Pressed(void)
apalmieri 0:2e972e7d3f64 141 {
fabiombed 5:5e62f661a7ab 142 trigger_button = true;
fabiombed 7:eb2215fe86b2 143
fabiombed 7:eb2215fe86b2 144 Status++;
fabiombed 7:eb2215fe86b2 145
fabiombed 7:eb2215fe86b2 146 #ifdef Sensors
fabiombed 7:eb2215fe86b2 147 if (Status>3) { Status=1; }
fabiombed 7:eb2215fe86b2 148 #else
fabiombed 7:eb2215fe86b2 149 if (Status>2) { Status=1; }
fabiombed 7:eb2215fe86b2 150 #endif
fabiombed 7:eb2215fe86b2 151
apalmieri 0:2e972e7d3f64 152 }
apalmieri 0:2e972e7d3f64 153
fabiombed 4:17f96ffc073a 154 /* Bluetooth CallBack ---------------------------------------------------------*/
fabiombed 4:17f96ffc073a 155
fabiombed 4:17f96ffc073a 156 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
fabiombed 4:17f96ffc073a 157 {
fabiombed 4:17f96ffc073a 158 if (params->peerAddr[0] != BLE_peer_address_BE[0]) // return if miss the server MAC address
fabiombed 4:17f96ffc073a 159 {
fabiombed 6:ce0e5024e3fa 160 printf("Missing Expected MAC Address\n\r");
fabiombed 4:17f96ffc073a 161 return; // exit from advertisementCallback
apalmieri 0:2e972e7d3f64 162 }
apalmieri 0:2e972e7d3f64 163
fabiombed 4:17f96ffc073a 164 // printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
fabiombed 4:17f96ffc073a 165 // params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
fabiombed 4:17f96ffc073a 166 // params->rssi, params->isScanResponse, params->type);
fabiombed 4:17f96ffc073a 167
fabiombed 4:17f96ffc073a 168 printf("Found Expected MAC Address: isScanResponse %u, AdvertisementType %u\r\n",params->isScanResponse, params->type);
apalmieri 0:2e972e7d3f64 169
fabiombed 4:17f96ffc073a 170 if(!params->isScanResponse)
fabiombed 4:17f96ffc073a 171 {
apalmieri 0:2e972e7d3f64 172 BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_PUBLIC, NULL, NULL);
apalmieri 0:2e972e7d3f64 173 }
apalmieri 0:2e972e7d3f64 174 }
apalmieri 0:2e972e7d3f64 175
fabiombed 4:17f96ffc073a 176 void serviceDiscoveryCallback(const DiscoveredService *service)
fabiombed 4:17f96ffc073a 177 {
fabiombed 4:17f96ffc073a 178 printf("Start Service Discovery\r\n");
fabiombed 7:eb2215fe86b2 179
fabiombed 4:17f96ffc073a 180 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT)
fabiombed 4:17f96ffc073a 181 {
apalmieri 0:2e972e7d3f64 182 printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());
fabiombed 4:17f96ffc073a 183 }
fabiombed 4:17f96ffc073a 184 else
fabiombed 4:17f96ffc073a 185 {
apalmieri 0:2e972e7d3f64 186 printf("S UUID-");
apalmieri 0:2e972e7d3f64 187 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
fabiombed 4:17f96ffc073a 188 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++)
fabiombed 4:17f96ffc073a 189 {
apalmieri 0:2e972e7d3f64 190 printf("%02X", longUUIDBytes[i]);
apalmieri 0:2e972e7d3f64 191 }
apalmieri 0:2e972e7d3f64 192 printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());
apalmieri 0:2e972e7d3f64 193 }
fabiombed 7:eb2215fe86b2 194
apalmieri 0:2e972e7d3f64 195 }
fabiombed 4:17f96ffc073a 196
fabiombed 4:17f96ffc073a 197 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP)
fabiombed 4:17f96ffc073a 198 {
fabiombed 7:eb2215fe86b2 199 int COMMAND_CHAR_count=0, STATUS_CHAR_count=0, DIFFERENCE_CHAR_count=0, POSITION_CHAR_count=0, SUNPANEL_CHAR_count=0;
fabiombed 7:eb2215fe86b2 200 const uint8_t *longUUIDBytes = characteristicP->getUUID().getBaseUUID();
fabiombed 7:eb2215fe86b2 201
fabiombed 7:eb2215fe86b2 202 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++)
fabiombed 7:eb2215fe86b2 203 {
fabiombed 7:eb2215fe86b2 204 if (longUUIDBytes[i] == CONTROL_COMMAND_CHAR_UUID[i]) COMMAND_CHAR_count++;
fabiombed 7:eb2215fe86b2 205 if (longUUIDBytes[i] == SENS_STATUS_CHAR_UUID[i]) STATUS_CHAR_count++;
fabiombed 7:eb2215fe86b2 206 if (longUUIDBytes[i] == SENS_DIFFERENCE_CHAR_UUID[i]) DIFFERENCE_CHAR_count++;
fabiombed 7:eb2215fe86b2 207 if (longUUIDBytes[i] == SENS_POSITION_CHAR_UUID[i]) POSITION_CHAR_count++;
fabiombed 7:eb2215fe86b2 208 if (longUUIDBytes[i] == SENS_SUNPANEL_CHAR_UUID[i]) SUNPANEL_CHAR_count++;
fabiombed 4:17f96ffc073a 209 }
fabiombed 4:17f96ffc073a 210
fabiombed 7:eb2215fe86b2 211 //if (characteristicP->getUUID().getShortUUID() == CONTROL_COMMAND_CHAR_UUID)
fabiombed 7:eb2215fe86b2 212 if (COMMAND_CHAR_count == UUID::LENGTH_OF_LONG_UUID)
fabiombed 7:eb2215fe86b2 213 {
fabiombed 7:eb2215fe86b2 214 command_bleCharacteristic = *characteristicP;
fabiombed 7:eb2215fe86b2 215 printf("Found Command Characteristic\r\n");
fabiombed 7:eb2215fe86b2 216 }
fabiombed 7:eb2215fe86b2 217
fabiombed 7:eb2215fe86b2 218 //if (characteristicP->getUUID().getShortUUID() == SENS_STATUS_CHAR_UUID)
fabiombed 7:eb2215fe86b2 219 if (STATUS_CHAR_count == UUID::LENGTH_OF_LONG_UUID)
fabiombed 7:eb2215fe86b2 220 {
fabiombed 7:eb2215fe86b2 221 status_bleCharacteristic = *characteristicP;
fabiombed 7:eb2215fe86b2 222 printf("Found Status Characteristic\r\n");
fabiombed 7:eb2215fe86b2 223 }
fabiombed 7:eb2215fe86b2 224
fabiombed 7:eb2215fe86b2 225 //if (characteristicP->getUUID().getShortUUID() == SENS_DIFFERENCE_CHAR_UUID)
fabiombed 7:eb2215fe86b2 226 if (DIFFERENCE_CHAR_count == UUID::LENGTH_OF_LONG_UUID)
fabiombed 4:17f96ffc073a 227 {
fabiombed 4:17f96ffc073a 228 difference_bleCharacteristic = *characteristicP;
fabiombed 7:eb2215fe86b2 229 printf("Found Difference Characteristic\r\n");
fabiombed 4:17f96ffc073a 230 }
fabiombed 7:eb2215fe86b2 231
fabiombed 7:eb2215fe86b2 232 //if (characteristicP->getUUID().getShortUUID() == SENS_POSITION_CHAR_UUID)
fabiombed 7:eb2215fe86b2 233 if (POSITION_CHAR_count == UUID::LENGTH_OF_LONG_UUID)
fabiombed 4:17f96ffc073a 234 {
fabiombed 4:17f96ffc073a 235 position_bleCharacteristic = *characteristicP;
fabiombed 7:eb2215fe86b2 236 printf("Found Position Characteristic\r\n");
fabiombed 4:17f96ffc073a 237 }
fabiombed 7:eb2215fe86b2 238
fabiombed 7:eb2215fe86b2 239 //if (characteristicP->getUUID().getShortUUID() == SENS_SUNPANEL_CHAR_UUID)
fabiombed 7:eb2215fe86b2 240 if (SUNPANEL_CHAR_count == UUID::LENGTH_OF_LONG_UUID)
fabiombed 4:17f96ffc073a 241 {
fabiombed 4:17f96ffc073a 242 sunpanel_bleCharacteristic = *characteristicP;
fabiombed 7:eb2215fe86b2 243 printf("Found Sunpanel Characteristic\r\n");
apalmieri 0:2e972e7d3f64 244 }
apalmieri 0:2e972e7d3f64 245 }
apalmieri 0:2e972e7d3f64 246
fabiombed 4:17f96ffc073a 247 void discoveryTerminationCallback(Gap::Handle_t connectionHandle)
fabiombed 4:17f96ffc073a 248 {
fabiombed 4:17f96ffc073a 249 //printf("discoveryTerminationCallback for handle %u\r\n", connectionHandle);
fabiombed 4:17f96ffc073a 250 printf("Stop Service Discovery\r\n\r\n");
fabiombed 5:5e62f661a7ab 251
fabiombed 7:eb2215fe86b2 252 trigger_Op = READ_STA;
apalmieri 0:2e972e7d3f64 253 }
apalmieri 0:2e972e7d3f64 254
fabiombed 4:17f96ffc073a 255 void onDataReadCallback(const GattReadCallbackParams *response)
fabiombed 4:17f96ffc073a 256 {
fabiombed 4:17f96ffc073a 257 // Read SERVER --> CLIENT
fabiombed 4:17f96ffc073a 258
fabiombed 7:eb2215fe86b2 259 // From SERVER it receives a sensor in this format: TimeStamp (2) + Data (2)
fabiombed 7:eb2215fe86b2 260 uint16_t TimeStamp = response->data[0]<<8 | response->data[1];
fabiombed 7:eb2215fe86b2 261 int16_t Data = response->data[2] | response->data[3]<<8; // Return original value after inverted with STORE_LE_16 into SERVER before send by BLE
fabiombed 5:5e62f661a7ab 262
fabiombed 7:eb2215fe86b2 263 //printf("\r\n\ronDataReadCallback (TimeStamp %x)", TimeStamp);
fabiombed 7:eb2215fe86b2 264 //printf("\n\ronDataReadCallback (Data Hex %x)", Data);
fabiombed 7:eb2215fe86b2 265 //printf("\n\ronDataReadCallback (Data Dec %d)", Data);
fabiombed 5:5e62f661a7ab 266
fabiombed 7:eb2215fe86b2 267 if (response->handle == status_bleCharacteristic.getValueHandle())
fabiombed 5:5e62f661a7ab 268 {
fabiombed 7:eb2215fe86b2 269 Status = Data;
fabiombed 7:eb2215fe86b2 270 printf("\n\rReceive BLE Display Status %d\n\r", Status);
fabiombed 5:5e62f661a7ab 271
fabiombed 5:5e62f661a7ab 272 trigger_Op = READ_DIF;
fabiombed 4:17f96ffc073a 273 }
fabiombed 4:17f96ffc073a 274
fabiombed 4:17f96ffc073a 275 if (response->handle == difference_bleCharacteristic.getValueHandle())
fabiombed 5:5e62f661a7ab 276 {
fabiombed 7:eb2215fe86b2 277 diff = Data;
fabiombed 5:5e62f661a7ab 278 printf("Receive BLE Difference %d lux/mems\n\r", diff);
fabiombed 5:5e62f661a7ab 279
fabiombed 5:5e62f661a7ab 280 trigger_Op = READ_POS;
apalmieri 0:2e972e7d3f64 281 }
fabiombed 4:17f96ffc073a 282
fabiombed 4:17f96ffc073a 283 if (response->handle == position_bleCharacteristic.getValueHandle())
fabiombed 5:5e62f661a7ab 284 {
fabiombed 7:eb2215fe86b2 285 pos = Data;
fabiombed 5:5e62f661a7ab 286 printf("Receive BLE Position %d\n\r", pos);
fabiombed 5:5e62f661a7ab 287
fabiombed 5:5e62f661a7ab 288 trigger_Op = READ_SUN;
fabiombed 4:17f96ffc073a 289 }
apalmieri 0:2e972e7d3f64 290
fabiombed 4:17f96ffc073a 291 if (response->handle == sunpanel_bleCharacteristic.getValueHandle())
fabiombed 5:5e62f661a7ab 292 {
fabiombed 7:eb2215fe86b2 293 measure = Data;
fabiombed 5:5e62f661a7ab 294 printf("Receive BLE Sunpanel %d mV\n\r", measure);
fabiombed 4:17f96ffc073a 295
fabiombed 7:eb2215fe86b2 296 trigger_Op = WRITE_STA;
fabiombed 4:17f96ffc073a 297 }
apalmieri 0:2e972e7d3f64 298 }
apalmieri 0:2e972e7d3f64 299
fabiombed 4:17f96ffc073a 300 void myonDataWriteCallback(const GattWriteCallbackParams *response)
fabiombed 4:17f96ffc073a 301 {
fabiombed 4:17f96ffc073a 302 // Write CLIENT --> SERVER
fabiombed 4:17f96ffc073a 303
fabiombed 7:eb2215fe86b2 304 if (response->handle == command_bleCharacteristic.getValueHandle())
fabiombed 7:eb2215fe86b2 305 {
fabiombed 7:eb2215fe86b2 306
fabiombed 7:eb2215fe86b2 307 // From CLIENT it writes a command in this format: Feature (4) + Type (1) + Data (2)
fabiombed 7:eb2215fe86b2 308 uint32_t Feature = response->data[0]<<24 | response->data[1]<<16 | response->data[2]<<8 | response->data[3];
fabiombed 7:eb2215fe86b2 309 uint8_t Type = response->data[4];
fabiombed 7:eb2215fe86b2 310 int16_t Data = response->data[5]<<8 | response->data[6];
fabiombed 7:eb2215fe86b2 311
fabiombed 7:eb2215fe86b2 312 //printf("\r\nmyonDataWriteCallback (Feature %x)", Feature);
fabiombed 7:eb2215fe86b2 313 //printf("\r\nmyonDataWriteCallback (Type %x)", Type); // Not Used
fabiombed 7:eb2215fe86b2 314 //printf("\r\nmyonDataWriteCallback (Data Hex %x)", Data);
fabiombed 7:eb2215fe86b2 315 //printf("\r\nmyonDataWriteCallback (Data Dec %d)", Data);
fabiombed 5:5e62f661a7ab 316
fabiombed 7:eb2215fe86b2 317 switch(Feature)
fabiombed 7:eb2215fe86b2 318 {
fabiombed 7:eb2215fe86b2 319 case FeatureStatus:
fabiombed 7:eb2215fe86b2 320 printf("\r\nSend STATUS %d\r\n", Data);
fabiombed 7:eb2215fe86b2 321 Status = Data;
fabiombed 7:eb2215fe86b2 322 trigger_Op = WRITE_DIF;
fabiombed 7:eb2215fe86b2 323 break;
fabiombed 7:eb2215fe86b2 324
fabiombed 7:eb2215fe86b2 325 case FeatureDifference:
fabiombed 7:eb2215fe86b2 326 printf("\r\nSend DIFF %d\r\n", Data);
fabiombed 7:eb2215fe86b2 327 diff = Data;
fabiombed 7:eb2215fe86b2 328 trigger_Op = READ_STA;
fabiombed 7:eb2215fe86b2 329 break;
fabiombed 7:eb2215fe86b2 330
fabiombed 7:eb2215fe86b2 331 case FeaturePosition:
fabiombed 7:eb2215fe86b2 332 break;
fabiombed 7:eb2215fe86b2 333
fabiombed 7:eb2215fe86b2 334 case FeatureSunPanel:
fabiombed 7:eb2215fe86b2 335 break;
fabiombed 7:eb2215fe86b2 336
fabiombed 7:eb2215fe86b2 337 default:
fabiombed 7:eb2215fe86b2 338 break;
fabiombed 7:eb2215fe86b2 339 }
fabiombed 5:5e62f661a7ab 340
fabiombed 5:5e62f661a7ab 341 }
fabiombed 7:eb2215fe86b2 342
apalmieri 0:2e972e7d3f64 343 }
apalmieri 0:2e972e7d3f64 344
apalmieri 0:2e972e7d3f64 345 /**
apalmieri 0:2e972e7d3f64 346 * This function is called when the ble initialization process has failled
apalmieri 0:2e972e7d3f64 347 */
apalmieri 0:2e972e7d3f64 348 void onBleInitError(BLE &ble, ble_error_t error)
apalmieri 0:2e972e7d3f64 349 {
apalmieri 0:2e972e7d3f64 350 /* Initialization error handling should go here */
fabiombed 5:5e62f661a7ab 351
fabiombed 5:5e62f661a7ab 352 printf("Inizialization Error\n\r");
apalmieri 0:2e972e7d3f64 353 }
apalmieri 0:2e972e7d3f64 354
fabiombed 4:17f96ffc073a 355 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
fabiombed 4:17f96ffc073a 356 {
fabiombed 7:eb2215fe86b2 357 // Good only for Short UUID
fabiombed 7:eb2215fe86b2 358 //uint16_t CONTROL_SERVICE_UUID = 0x00,0x00,0x00,0x00,0x00,0x0F,0x11,0xe1,0x9a,0xb4,0x00,0x02,0xa5,0xd5,0xc5,0x1b;
fabiombed 7:eb2215fe86b2 359 //uint16_t COMMAND_CHARACTERISTIC_UUID = 0x00,0x00,0x00,0x02,0x00,0x0F,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b;
fabiombed 7:eb2215fe86b2 360 //uint16_t SENSORS_SERVICE_UUID = 0x00,0x00,0x00,0x00,0x00,0x01,0x11,0xe1,0x9a,0xb4,0x00,0x02,0xa5,0xd5,0xc5,0x1b;
fabiombed 7:eb2215fe86b2 361 //uint16_t STATUS_CHARACTERISTIC_UUID = 0x00,0x00,0x04,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b;
fabiombed 7:eb2215fe86b2 362 //uint16_t DIFFERENCE_CHARACTERISTIC_UUID = 0x00,0x00,0x08,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b;
fabiombed 7:eb2215fe86b2 363 //uint16_t POSITION_CHARACTERISTIC_UUID = 0x00,0x00,0x10,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b;
fabiombed 7:eb2215fe86b2 364 //uint16_t SUNPANEL_CHARACTERISTIC_UUID = 0x00,0x00,0x20,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b;
fabiombed 4:17f96ffc073a 365
fabiombed 4:17f96ffc073a 366 if (params->role == Gap::CENTRAL)
fabiombed 4:17f96ffc073a 367 {
fabiombed 4:17f96ffc073a 368 BLE &ble = BLE::Instance();
fabiombed 4:17f96ffc073a 369 ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
fabiombed 4:17f96ffc073a 370 // Discover all SERVICES and CHARACTERISTICS
fabiombed 4:17f96ffc073a 371 ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback);
fabiombed 4:17f96ffc073a 372
fabiombed 5:5e62f661a7ab 373 // Works only for one characteristic, if you need to discover all characteristic, use the above command
fabiombed 7:eb2215fe86b2 374 //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, CONTROL_SERVICE_UUID, COMMAND_CHARACTERISTIC_UUID);
fabiombed 7:eb2215fe86b2 375 //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, SENSORS_SERVICE_UUID, STATUS_CHARACTERISTIC_UUID);
fabiombed 4:17f96ffc073a 376 //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, SENSORS_SERVICE_UUID, DIFFERENCE_CHARACTERISTIC_UUID);
fabiombed 4:17f96ffc073a 377 //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, SENSORS_SERVICE_UUID, POSITION_CHARACTERISTIC_UUID);
fabiombed 4:17f96ffc073a 378 //ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, SENSORS_SERVICE_UUID, SUNPANEL_CHARACTERISTIC_UUID);
fabiombed 4:17f96ffc073a 379 }
fabiombed 4:17f96ffc073a 380
fabiombed 4:17f96ffc073a 381 printf("Remote Connected\n\r");
fabiombed 4:17f96ffc073a 382 }
fabiombed 4:17f96ffc073a 383
fabiombed 4:17f96ffc073a 384 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
fabiombed 4:17f96ffc073a 385 {
fabiombed 4:17f96ffc073a 386 (void)params;
fabiombed 5:5e62f661a7ab 387
fabiombed 4:17f96ffc073a 388 printf("Remote Disconnected\n\r");
fabiombed 4:17f96ffc073a 389 }
fabiombed 4:17f96ffc073a 390
apalmieri 0:2e972e7d3f64 391 /**
apalmieri 0:2e972e7d3f64 392 * Callback triggered when the ble initialization process has finished
apalmieri 0:2e972e7d3f64 393 */
apalmieri 0:2e972e7d3f64 394 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
apalmieri 0:2e972e7d3f64 395 {
apalmieri 0:2e972e7d3f64 396 BLE& ble = params->ble;
apalmieri 0:2e972e7d3f64 397 ble_error_t error = params->error;
apalmieri 0:2e972e7d3f64 398
fabiombed 4:17f96ffc073a 399 if (error != BLE_ERROR_NONE)
fabiombed 4:17f96ffc073a 400 {
apalmieri 0:2e972e7d3f64 401 /* In case of error, forward the error handling to onBleInitError */
apalmieri 0:2e972e7d3f64 402 onBleInitError(ble, error);
apalmieri 0:2e972e7d3f64 403 return;
apalmieri 0:2e972e7d3f64 404 }
apalmieri 0:2e972e7d3f64 405
apalmieri 0:2e972e7d3f64 406 /* Ensure that it is the default instance of BLE */
fabiombed 4:17f96ffc073a 407 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; }
apalmieri 0:2e972e7d3f64 408
apalmieri 0:2e972e7d3f64 409 // Set BT Address
apalmieri 1:e0f4bcce540c 410 ble.gap().setAddress(BLEProtocol::AddressType::PUBLIC, BLE_address_BE);
apalmieri 0:2e972e7d3f64 411
apalmieri 0:2e972e7d3f64 412 ble.gap().onConnection(connectionCallback);
apalmieri 0:2e972e7d3f64 413 ble.onDisconnection(disconnectionCallback);
apalmieri 0:2e972e7d3f64 414
fabiombed 4:17f96ffc073a 415 ble.gattClient().onDataRead(onDataReadCallback);
fabiombed 4:17f96ffc073a 416 ble.gattClient().onDataWrite(myonDataWriteCallback);
apalmieri 0:2e972e7d3f64 417
apalmieri 0:2e972e7d3f64 418 ble.gap().setScanParams(SCAN_INT, SCAN_WIND);
apalmieri 0:2e972e7d3f64 419 ble.gap().startScan(advertisementCallback);
fabiombed 7:eb2215fe86b2 420
fabiombed 4:17f96ffc073a 421 // Main Loop
fabiombed 7:eb2215fe86b2 422 while (true)
fabiombed 7:eb2215fe86b2 423 {
fabiombed 5:5e62f661a7ab 424
fabiombed 5:5e62f661a7ab 425 //if (!ble.gattClient().isServiceDiscoveryActive())
fabiombed 5:5e62f661a7ab 426 if (trigger_Op!=IDLE) // Wait until discoveryTerminationCallback
fabiombed 5:5e62f661a7ab 427 {
fabiombed 6:ce0e5024e3fa 428
fabiombed 5:5e62f661a7ab 429 // At present ARM BLE_API don't support Enable/Disable Notify from Client
fabiombed 7:eb2215fe86b2 430 //command_bleCharacteristic.notify();
fabiombed 5:5e62f661a7ab 431 //difference_bleCharacteristic.notify();
fabiombed 5:5e62f661a7ab 432 //position_bleCharacteristic.notify();
fabiombed 5:5e62f661a7ab 433 //sunpanel_bleCharacteristic.notify();
fabiombed 5:5e62f661a7ab 434
fabiombed 5:5e62f661a7ab 435 // Don't run more ble .read or .write in the same loop
fabiombed 5:5e62f661a7ab 436 // because the callback is an interrupt and it doesn't work correctly if overloaded
fabiombed 7:eb2215fe86b2 437
fabiombed 7:eb2215fe86b2 438 if (Status == 1 || Status == 2)
fabiombed 7:eb2215fe86b2 439 { if (trigger_Op == WRITE_DIF) trigger_Op = READ_STA; } // if Display 1 or 2, skip WRITE_DIF
fabiombed 5:5e62f661a7ab 440
fabiombed 7:eb2215fe86b2 441 if (Status == 3)
fabiombed 7:eb2215fe86b2 442 { if (trigger_Op == READ_DIF) trigger_Op = READ_POS; } // if Display 3, skip READ_DIF
fabiombed 7:eb2215fe86b2 443
fabiombed 5:5e62f661a7ab 444 switch(trigger_Op)
fabiombed 4:17f96ffc073a 445 {
fabiombed 7:eb2215fe86b2 446 case READ_STA:
fabiombed 7:eb2215fe86b2 447 status_bleCharacteristic.read();
fabiombed 5:5e62f661a7ab 448 trigger_Op = IDLE;
fabiombed 5:5e62f661a7ab 449 break;
fabiombed 5:5e62f661a7ab 450 case READ_DIF:
fabiombed 4:17f96ffc073a 451 difference_bleCharacteristic.read();
fabiombed 5:5e62f661a7ab 452 trigger_Op = IDLE;
fabiombed 5:5e62f661a7ab 453 break;
fabiombed 5:5e62f661a7ab 454 case READ_POS:
fabiombed 4:17f96ffc073a 455 position_bleCharacteristic.read();
fabiombed 5:5e62f661a7ab 456 trigger_Op = IDLE;
fabiombed 5:5e62f661a7ab 457 break;
fabiombed 5:5e62f661a7ab 458 case READ_SUN:
fabiombed 4:17f96ffc073a 459 sunpanel_bleCharacteristic.read();
fabiombed 5:5e62f661a7ab 460 trigger_Op = IDLE;
fabiombed 5:5e62f661a7ab 461 break;
fabiombed 7:eb2215fe86b2 462 case WRITE_STA:
fabiombed 5:5e62f661a7ab 463 if (trigger_button == true)
fabiombed 7:eb2215fe86b2 464 {
fabiombed 7:eb2215fe86b2 465 memset (value_write, 0, COMMAND_DATA_LEN);
fabiombed 7:eb2215fe86b2 466 //value_write = Feature (4) + Type (1) + Data (2)
fabiombed 7:eb2215fe86b2 467 value_write[0] = (FeatureStatus & 0xff000000) >> 24;
fabiombed 7:eb2215fe86b2 468 value_write[1] = (FeatureStatus & 0x00ff0000) >> 16;
fabiombed 7:eb2215fe86b2 469 value_write[2] = (FeatureStatus & 0x0000ff00) >> 8;
fabiombed 7:eb2215fe86b2 470 value_write[3] = (FeatureStatus & 0x000000ff);
fabiombed 7:eb2215fe86b2 471 value_write[4] = (0x00);
fabiombed 7:eb2215fe86b2 472 value_write[5] = (Status & 0xff00) >> 8;
fabiombed 7:eb2215fe86b2 473 value_write[6] = (Status & 0x00ff);
fabiombed 7:eb2215fe86b2 474 command_bleCharacteristic.write(COMMAND_DATA_LEN, value_write);
fabiombed 7:eb2215fe86b2 475
fabiombed 5:5e62f661a7ab 476 trigger_Op = IDLE;
fabiombed 5:5e62f661a7ab 477 trigger_button = false;
fabiombed 5:5e62f661a7ab 478 } else {
fabiombed 5:5e62f661a7ab 479 #ifdef Sensors
fabiombed 5:5e62f661a7ab 480 trigger_Op = WRITE_DIF;
fabiombed 5:5e62f661a7ab 481 #else
fabiombed 7:eb2215fe86b2 482 trigger_Op = READ_STA;
fabiombed 5:5e62f661a7ab 483 #endif
fabiombed 5:5e62f661a7ab 484 }
fabiombed 5:5e62f661a7ab 485 break;
fabiombed 5:5e62f661a7ab 486 case WRITE_DIF:
fabiombed 5:5e62f661a7ab 487 #ifdef Sensors
fabiombed 5:5e62f661a7ab 488 accelerometer->Get_X_Axes(acc_data);
fabiombed 5:5e62f661a7ab 489 acc_diff = acc_data[0];
fabiombed 5:5e62f661a7ab 490 //printf("Send BLE Difference %d lux/mems\n\r", acc_diff);
fabiombed 7:eb2215fe86b2 491
fabiombed 7:eb2215fe86b2 492 memset (value_write, 0, COMMAND_DATA_LEN);
fabiombed 7:eb2215fe86b2 493 //value_write = Feature (4) + Type (1) + Data (2)
fabiombed 7:eb2215fe86b2 494 value_write[0] = (FeatureDifference & 0xff000000) >> 24;
fabiombed 7:eb2215fe86b2 495 value_write[1] = (FeatureDifference & 0x00ff0000) >> 16;
fabiombed 7:eb2215fe86b2 496 value_write[2] = (FeatureDifference & 0x0000ff00) >> 8;
fabiombed 7:eb2215fe86b2 497 value_write[3] = (FeatureDifference & 0x000000ff);
fabiombed 7:eb2215fe86b2 498 value_write[4] = (0x00);
fabiombed 7:eb2215fe86b2 499 value_write[5] = (acc_diff & 0xff00) >> 8;
fabiombed 7:eb2215fe86b2 500 value_write[6] = (acc_diff & 0x00ff);
fabiombed 7:eb2215fe86b2 501 command_bleCharacteristic.write(COMMAND_DATA_LEN, value_write);
fabiombed 7:eb2215fe86b2 502
fabiombed 5:5e62f661a7ab 503 trigger_Op = IDLE;
fabiombed 5:5e62f661a7ab 504 #else
fabiombed 7:eb2215fe86b2 505 trigger_Op = READ_STA;
fabiombed 5:5e62f661a7ab 506 #endif
fabiombed 5:5e62f661a7ab 507 break;
fabiombed 5:5e62f661a7ab 508 default:
fabiombed 5:5e62f661a7ab 509 break;
fabiombed 4:17f96ffc073a 510 }
fabiombed 4:17f96ffc073a 511
apalmieri 0:2e972e7d3f64 512 }
fabiombed 4:17f96ffc073a 513 ble.waitForEvent();
fabiombed 7:eb2215fe86b2 514 }
apalmieri 0:2e972e7d3f64 515 }
apalmieri 0:2e972e7d3f64 516
fabiombed 5:5e62f661a7ab 517 /* Ticker --------------------------------------------------------------------*/
fabiombed 5:5e62f661a7ab 518 /*
fabiombed 5:5e62f661a7ab 519 void ticker_Callback(void)
fabiombed 5:5e62f661a7ab 520 {
fabiombed 5:5e62f661a7ab 521
fabiombed 5:5e62f661a7ab 522 }
fabiombed 5:5e62f661a7ab 523 */
fabiombed 4:17f96ffc073a 524 /* Main ----------------------------------------------------------------------*/
fabiombed 4:17f96ffc073a 525
apalmieri 0:2e972e7d3f64 526 int main(void)
apalmieri 0:2e972e7d3f64 527 {
fabiombed 7:eb2215fe86b2 528 printf("\r\n\r\nSunTracker Remote Control by Fabio Brembilla\r\n\r\n");
fabiombed 4:17f96ffc073a 529
fabiombed 4:17f96ffc073a 530 #ifdef Sensors
fabiombed 4:17f96ffc073a 531 // Initializing Sensors Component
fabiombed 4:17f96ffc073a 532 mems=X_NUCLEO_IKS01A1::Instance(&dev_i2c);
fabiombed 4:17f96ffc073a 533 accelerometer = mems->GetAccelerometer();
fabiombed 4:17f96ffc073a 534 printf("Init Sensors OK\r\n");
fabiombed 4:17f96ffc073a 535 #endif
fabiombed 5:5e62f661a7ab 536
fabiombed 5:5e62f661a7ab 537 //Ticker ticker;
fabiombed 5:5e62f661a7ab 538 //ticker.attach(ticker_Callback, 1); // every 1 second
fabiombed 4:17f96ffc073a 539
fabiombed 4:17f96ffc073a 540 mybutton.fall(&User_Button_Pressed);
fabiombed 4:17f96ffc073a 541
fabiombed 7:eb2215fe86b2 542 BLE::Instance().init(bleInitComplete);
fabiombed 7:eb2215fe86b2 543
fabiombed 4:17f96ffc073a 544 }