BLE-WiFi with BIOSensors

Dependencies:   AS7000 BNO055 NNN50_WIFI_API

DELTA NNN50 (Bluetooth LE 4.X & 802.11 b/g/n) with Bio Sensor (HRM, 9DoF motion Sensor) reference design.

Env. Setup step by step.

  1. Download or build a TCP Server on you host computer
    1. Please find out the TCP server code or install TCP server application in your host computer.
  2. Import this sample application and setup these information about AP & TCP Server
    1. *char* AP_SSID = "SOG";
    2. *char* AP_PWD = "1122334455667788";
    3. *char* TCP_SERVER_ADDRESS = "10.0.1.13";
    4. *int TCP_SERVER_PORT = 1030;
  3. Compiler your code and download to your mBed device.
  4. Control your mBed device
    1. Please use NORDSemi nRF Tool and setup and watch these information: GATT CMD: 0x00 (connect to AP, TCP Server, and create TCP socket), 0x02 disconnection TCP server, close socket, and WiFi sleep), 0xA1 (send sensor data to tcp server from out_buffer[]) and Status will be update by Bluetooth LE adv through manufacturing information
0x000x020xA1
WiFi,AP&TCP Server connectWiFi,AP, & TCP Server disconnectSend sensor data to TCP Server
Committer:
sog_yang
Date:
Thu Jun 01 07:43:55 2017 +0000
Revision:
14:eacafd9e019f
Parent:
13:a777cab6c218
Child:
15:d22f450bb909
Interrupts command update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sog_yang 5:ffe1a4c4881e 1 #include "mbed.h"
sog_yang 7:06495d54d107 2 #include "BNO055.h"
sog_yang 7:06495d54d107 3 #include "AS7000.h"
sog_yang 5:ffe1a4c4881e 4 #include "ble/BLE.h"
sog_yang 5:ffe1a4c4881e 5 #include "ble/Gap.h"
sog_yang 5:ffe1a4c4881e 6 #include "ble/services/BatteryService.h"
sog_yang 5:ffe1a4c4881e 7 #include "DOORService.h"
sog_yang 5:ffe1a4c4881e 8 #include "EthernetInterface.h"
sog_yang 5:ffe1a4c4881e 9 #include "WIFIDevice.h"
sog_yang 5:ffe1a4c4881e 10
sog_yang 8:ff7fdd152f14 11 #define DEBUG_LOG 0
sog_yang 5:ffe1a4c4881e 12
sog_yang 5:ffe1a4c4881e 13 union IP {
sog_yang 5:ffe1a4c4881e 14 unsigned int ip;
sog_yang 5:ffe1a4c4881e 15 struct {
sog_yang 5:ffe1a4c4881e 16 unsigned char d;
sog_yang 5:ffe1a4c4881e 17 unsigned char c;
sog_yang 5:ffe1a4c4881e 18 unsigned char b;
sog_yang 5:ffe1a4c4881e 19 unsigned char a;
sog_yang 5:ffe1a4c4881e 20 } ip2;
sog_yang 5:ffe1a4c4881e 21 };
sog_yang 5:ffe1a4c4881e 22
sog_yang 5:ffe1a4c4881e 23 char ips[20];
sog_yang 5:ffe1a4c4881e 24 IP ip;
sog_yang 7:06495d54d107 25
sog_yang 7:06495d54d107 26 DOORService *doorServicePtr;
sog_yang 7:06495d54d107 27
sog_yang 7:06495d54d107 28 BNO055 imu(p0,p30);
sog_yang 7:06495d54d107 29 AS7000 hrm(p0,p30);
sog_yang 7:06495d54d107 30 Serial pc(USBTX, USBRX);
sog_yang 9:d1861b00e0fd 31 DigitalInOut myOutputPin(USBTX);
sog_yang 5:ffe1a4c4881e 32 EthernetInterface eth;
sog_yang 5:ffe1a4c4881e 33 WIFIDevice wifi;
sog_yang 7:06495d54d107 34
sog_yang 5:ffe1a4c4881e 35 TCPSocketConnection sock_tcp;
sog_yang 11:54a1a576df9f 36 char* AP_SSID = "SOG";
sog_yang 11:54a1a576df9f 37 char* AP_PWD = "1122334455667788";
sog_yang 11:54a1a576df9f 38 char* TCP_SERVER_ADDRESS = "10.0.1.13";
sog_yang 11:54a1a576df9f 39 int TCP_SERVER_PORT = 1030;
sog_yang 5:ffe1a4c4881e 40
sog_yang 7:06495d54d107 41 uint8_t initialValueForDOORCharacteristic = 0xFF;
sog_yang 7:06495d54d107 42 uint8_t BLE_RX_CMD = 0xFF;
sog_yang 8:ff7fdd152f14 43 const char DEVICE_NAME[] = "FITNCTL";
sog_yang 7:06495d54d107 44 uint8_t ADV_manuf[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
sog_yang 11:54a1a576df9f 45 char out_buffer[45];
sog_yang 5:ffe1a4c4881e 46 static EventQueue eventQueue(
sog_yang 5:ffe1a4c4881e 47 /* event count */ 16 * /* event size */ 32
sog_yang 5:ffe1a4c4881e 48 );
sog_yang 7:06495d54d107 49
sog_yang 7:06495d54d107 50 bool isConnect = false;
sog_yang 7:06495d54d107 51 bool isWiFiEnable = false;
sog_yang 8:ff7fdd152f14 52 bool isCloudFiling = false;
sog_yang 7:06495d54d107 53
sog_yang 5:ffe1a4c4881e 54
sog_yang 5:ffe1a4c4881e 55 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
sog_yang 5:ffe1a4c4881e 56 {
sog_yang 5:ffe1a4c4881e 57 BLE::Instance().gap().startAdvertising();
sog_yang 5:ffe1a4c4881e 58 }
sog_yang 5:ffe1a4c4881e 59
sog_yang 5:ffe1a4c4881e 60 void onDataWrittenCallback(const GattWriteCallbackParams *params) {
sog_yang 5:ffe1a4c4881e 61
sog_yang 5:ffe1a4c4881e 62
sog_yang 5:ffe1a4c4881e 63 if ((params->handle == doorServicePtr->getValueHandle()) && (params->len == 1)) {
sog_yang 5:ffe1a4c4881e 64 {
sog_yang 7:06495d54d107 65 BLE_RX_CMD = *(params->data);
sog_yang 5:ffe1a4c4881e 66 }
sog_yang 5:ffe1a4c4881e 67 }
sog_yang 5:ffe1a4c4881e 68 }
sog_yang 5:ffe1a4c4881e 69
sog_yang 5:ffe1a4c4881e 70 /**
sog_yang 5:ffe1a4c4881e 71 * This function is called when the ble initialization process has failled
sog_yang 5:ffe1a4c4881e 72 */
sog_yang 5:ffe1a4c4881e 73 void onBleInitError(BLE &ble, ble_error_t error)
sog_yang 5:ffe1a4c4881e 74 {
sog_yang 5:ffe1a4c4881e 75 /* Initialization error handling should go here */
sog_yang 5:ffe1a4c4881e 76 }
sog_yang 5:ffe1a4c4881e 77
sog_yang 5:ffe1a4c4881e 78 /**
sog_yang 5:ffe1a4c4881e 79 * Callback triggered when the ble initialization process has finished
sog_yang 5:ffe1a4c4881e 80 */
sog_yang 5:ffe1a4c4881e 81 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
sog_yang 5:ffe1a4c4881e 82 {
sog_yang 5:ffe1a4c4881e 83 BLE& ble = params->ble;
sog_yang 5:ffe1a4c4881e 84 ble_error_t error = params->error;
sog_yang 5:ffe1a4c4881e 85
sog_yang 5:ffe1a4c4881e 86 if (error != BLE_ERROR_NONE) {
sog_yang 5:ffe1a4c4881e 87 /* In case of error, forward the error handling to onBleInitError */
sog_yang 5:ffe1a4c4881e 88 onBleInitError(ble, error);
sog_yang 5:ffe1a4c4881e 89 return;
sog_yang 5:ffe1a4c4881e 90 }
sog_yang 5:ffe1a4c4881e 91
sog_yang 5:ffe1a4c4881e 92 /* Ensure that it is the default instance of BLE */
sog_yang 5:ffe1a4c4881e 93 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
sog_yang 5:ffe1a4c4881e 94 return;
sog_yang 5:ffe1a4c4881e 95 }
sog_yang 5:ffe1a4c4881e 96
sog_yang 5:ffe1a4c4881e 97 ble.gap().onDisconnection(disconnectionCallback);
sog_yang 5:ffe1a4c4881e 98 ble.gattServer().onDataWritten(onDataWrittenCallback);
sog_yang 5:ffe1a4c4881e 99
sog_yang 5:ffe1a4c4881e 100 /* Setup primary services */
sog_yang 5:ffe1a4c4881e 101 doorServicePtr = new DOORService(ble, initialValueForDOORCharacteristic);
sog_yang 5:ffe1a4c4881e 102
sog_yang 5:ffe1a4c4881e 103 /* Setup advertising */
sog_yang 5:ffe1a4c4881e 104 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
sog_yang 5:ffe1a4c4881e 105 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, ADV_manuf, sizeof(ADV_manuf));
sog_yang 5:ffe1a4c4881e 106 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
sog_yang 7:06495d54d107 107 ble.gap().setAdvertisingInterval(150); /* 1000ms */
sog_yang 5:ffe1a4c4881e 108 ble.gap().startAdvertising();
sog_yang 5:ffe1a4c4881e 109 }
sog_yang 5:ffe1a4c4881e 110
sog_yang 5:ffe1a4c4881e 111 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
sog_yang 5:ffe1a4c4881e 112 BLE &ble = BLE::Instance();
sog_yang 5:ffe1a4c4881e 113 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
sog_yang 5:ffe1a4c4881e 114 }
sog_yang 7:06495d54d107 115
sog_yang 7:06495d54d107 116
sog_yang 5:ffe1a4c4881e 117 int main (void) {
sog_yang 9:d1861b00e0fd 118 myOutputPin.mode(PullUp);
sog_yang 9:d1861b00e0fd 119 pc.baud(38400);
sog_yang 5:ffe1a4c4881e 120 hrm.enable();
sog_yang 7:06495d54d107 121 imu.reset();
sog_yang 5:ffe1a4c4881e 122 imu.setmode(OPERATION_MODE_NDOF);
sog_yang 5:ffe1a4c4881e 123
sog_yang 5:ffe1a4c4881e 124
sog_yang 5:ffe1a4c4881e 125 BLE &ble = BLE::Instance();
sog_yang 5:ffe1a4c4881e 126 ble.onEventsToProcess(scheduleBleEventsProcessing);
sog_yang 5:ffe1a4c4881e 127 ble.init(bleInitComplete);
sog_yang 7:06495d54d107 128
sog_yang 9:d1861b00e0fd 129 int i = 0;
sog_yang 9:d1861b00e0fd 130 int j = 0;
sog_yang 9:d1861b00e0fd 131 BLE_RX_CMD = 0xFF;
sog_yang 9:d1861b00e0fd 132 wait_ms(10);
sog_yang 9:d1861b00e0fd 133 sprintf(out_buffer,"\r\n");
sog_yang 9:d1861b00e0fd 134
sog_yang 9:d1861b00e0fd 135
sog_yang 5:ffe1a4c4881e 136 while (true) {
sog_yang 9:d1861b00e0fd 137 wait_ms(2);
sog_yang 13:a777cab6c218 138 __disable_irq(); // Disable Interrupts
sog_yang 7:06495d54d107 139 imu.get_angles(); //query the i2c device
sog_yang 14:eacafd9e019f 140 hrm.hr_only();
sog_yang 14:eacafd9e019f 141 __ensable_irq();// Enable Interrupts
sog_yang 9:d1861b00e0fd 142 wait_ms(8);
sog_yang 9:d1861b00e0fd 143 if (BLE_RX_CMD != 0xA1) {
sog_yang 9:d1861b00e0fd 144 if (i > 40){
sog_yang 9:d1861b00e0fd 145 pc.printf("*HR=%03d#", hrm.hrm.hreat_rate);
sog_yang 9:d1861b00e0fd 146 i=0;
sog_yang 9:d1861b00e0fd 147 } i++;
sog_yang 9:d1861b00e0fd 148 }
sog_yang 7:06495d54d107 149 /* GATT Command 0xA1 Cloud Data Transfer*/
sog_yang 8:ff7fdd152f14 150 if (BLE_RX_CMD == 0xA1){
sog_yang 8:ff7fdd152f14 151 ADV_manuf[5] = 0xF1;
sog_yang 8:ff7fdd152f14 152 if (isWiFiEnable == true){
sog_yang 10:248b81efda00 153 if (isConnect == true) {
sog_yang 9:d1861b00e0fd 154 if (j > 2){
sog_yang 9:d1861b00e0fd 155 pc.printf("*HR=%03d#", hrm.hrm.hreat_rate);
sog_yang 9:d1861b00e0fd 156 j = 0;
sog_yang 10:248b81efda00 157 }j++;
sog_yang 8:ff7fdd152f14 158 sprintf(out_buffer,"hrm:%03d yaw:%6.2f pitch:%6.2f roll:%6.2f\n", hrm.hrm.hreat_rate, imu.euler.yaw, imu.euler.pitch, imu.euler.roll);
sog_yang 8:ff7fdd152f14 159 sock_tcp.send_all(out_buffer, sizeof(out_buffer) - 1);
sog_yang 10:248b81efda00 160 sock_tcp.set_blocking(false, 200);// Timeout after 0.2s
sog_yang 8:ff7fdd152f14 161 isCloudFiling = true;
sog_yang 7:06495d54d107 162 } else {
sog_yang 11:54a1a576df9f 163 if (sock_tcp.connect(TCP_SERVER_ADDRESS, TCP_SERVER_PORT) < 0) {
sog_yang 8:ff7fdd152f14 164 isConnect = false;
sog_yang 8:ff7fdd152f14 165 BLE_RX_CMD = 0xFF;
sog_yang 8:ff7fdd152f14 166 #if DEBUG_LOG
sog_yang 8:ff7fdd152f14 167 pc.printf("Unable to connect to (%s) on port (%d)\n", ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT);
sog_yang 8:ff7fdd152f14 168 #endif
sog_yang 8:ff7fdd152f14 169 ADV_manuf[4] = 0xCF;
sog_yang 8:ff7fdd152f14 170 BLE_RX_CMD = 0xFF;
sog_yang 8:ff7fdd152f14 171 } else {
sog_yang 8:ff7fdd152f14 172 isConnect = true;
sog_yang 8:ff7fdd152f14 173 ADV_manuf[4] = 0xF1;
sog_yang 8:ff7fdd152f14 174 #if DEBUG_LOG
sog_yang 8:ff7fdd152f14 175 pc.printf("Connected to Server at %s\n",ECHO_SERVER_ADDRESS);
sog_yang 8:ff7fdd152f14 176 #endif
sog_yang 8:ff7fdd152f14 177 }
sog_yang 7:06495d54d107 178 }
sog_yang 7:06495d54d107 179 }
sog_yang 7:06495d54d107 180 }
sog_yang 7:06495d54d107 181 /* GATT Command 0x02 WiFI & Cloud Connection Close*/
sog_yang 7:06495d54d107 182 if (BLE_RX_CMD == 0x02){
sog_yang 9:d1861b00e0fd 183 BLE_RX_CMD = 0xFF;
sog_yang 7:06495d54d107 184 ADV_manuf[5] = 0xF2;
sog_yang 7:06495d54d107 185 if ( isConnect == true ) {
sog_yang 7:06495d54d107 186 sock_tcp.close();
sog_yang 7:06495d54d107 187 isConnect = false;
sog_yang 5:ffe1a4c4881e 188 }
sog_yang 7:06495d54d107 189 if ( isWiFiEnable == true ) {
sog_yang 7:06495d54d107 190 eth.disconnect();
sog_yang 7:06495d54d107 191 wifi.sleep();
sog_yang 7:06495d54d107 192 isWiFiEnable = false;
sog_yang 7:06495d54d107 193 }
sog_yang 9:d1861b00e0fd 194 while(true) {
sog_yang 9:d1861b00e0fd 195 if (wifi.is_AP_connected()==0) break; //make sure wifi disconnect
sog_yang 9:d1861b00e0fd 196 }
sog_yang 8:ff7fdd152f14 197 if (isConnect == true) isConnect = false;
sog_yang 8:ff7fdd152f14 198 isConnect = false;
sog_yang 8:ff7fdd152f14 199 isWiFiEnable = false;
sog_yang 9:d1861b00e0fd 200 isCloudFiling = false;
sog_yang 9:d1861b00e0fd 201
sog_yang 7:06495d54d107 202 ADV_manuf[0] = 0x00;
sog_yang 7:06495d54d107 203 ADV_manuf[1] = 0x00;
sog_yang 7:06495d54d107 204 ADV_manuf[2] = 0x00;
sog_yang 8:ff7fdd152f14 205 ADV_manuf[3] = 0x00;
sog_yang 9:d1861b00e0fd 206 ADV_manuf[4] = 0x00;
sog_yang 9:d1861b00e0fd 207 sprintf(out_buffer,"\n");
sog_yang 7:06495d54d107 208 }
sog_yang 7:06495d54d107 209 /* GATT Command 0x0 init WiFI & Cloud Connection*/
sog_yang 7:06495d54d107 210 if (BLE_RX_CMD == 0x00){
sog_yang 8:ff7fdd152f14 211 if(isCloudFiling == false) {
sog_yang 8:ff7fdd152f14 212 BLE_RX_CMD = 0xFF;
sog_yang 8:ff7fdd152f14 213 ADV_manuf[5] = 0xF0;
sog_yang 7:06495d54d107 214
sog_yang 8:ff7fdd152f14 215 if (isWiFiEnable == false) {
sog_yang 8:ff7fdd152f14 216 eth.init();
sog_yang 11:54a1a576df9f 217 wifi.setNetwork(M2M_WIFI_SEC_WPA_PSK, AP_SSID, AP_PWD);
sog_yang 8:ff7fdd152f14 218 eth.connect();
sog_yang 8:ff7fdd152f14 219 while(true) {
sog_yang 8:ff7fdd152f14 220 if (wifi.is_AP_connected()==1) break;
sog_yang 8:ff7fdd152f14 221 }
sog_yang 10:248b81efda00 222 sock_tcp.set_blocking(false, 1200);// Timeout after 1.2s
sog_yang 8:ff7fdd152f14 223 #if DEBUG_LOG
sog_yang 8:ff7fdd152f14 224 pc.printf("Connect Success! \n");
sog_yang 8:ff7fdd152f14 225 pc.printf("MAC: %s\n", eth.getMACAddress());
sog_yang 8:ff7fdd152f14 226 pc.printf("IP: %s\n", eth.getIPAddress());
sog_yang 8:ff7fdd152f14 227 pc.printf("Gateway: %s\n", eth.getGateway());
sog_yang 8:ff7fdd152f14 228 pc.printf("NetworkMask: %s\n", eth.getNetworkMask());
sog_yang 8:ff7fdd152f14 229 #endif
sog_yang 8:ff7fdd152f14 230 snprintf(ips, sizeof(ips), "%s",eth.getIPAddress());
sog_yang 8:ff7fdd152f14 231 unsigned short a, b, c, d;
sog_yang 8:ff7fdd152f14 232 sscanf(ips, "%hu.%hu.%hu.%hu", &a, &b, &c, &d);
sog_yang 8:ff7fdd152f14 233 sprintf(ips, "%x.%x.%x.%x", a, b, c, d);
sog_yang 8:ff7fdd152f14 234 ADV_manuf[0] = a;
sog_yang 8:ff7fdd152f14 235 ADV_manuf[1] = b;
sog_yang 8:ff7fdd152f14 236 ADV_manuf[2] = c;
sog_yang 8:ff7fdd152f14 237 ADV_manuf[3] = d;
sog_yang 8:ff7fdd152f14 238 isWiFiEnable = true;
sog_yang 8:ff7fdd152f14 239 }
sog_yang 8:ff7fdd152f14 240
sog_yang 8:ff7fdd152f14 241 if (isConnect == false) {
sog_yang 8:ff7fdd152f14 242 if (isWiFiEnable == true) {
sog_yang 11:54a1a576df9f 243 if (sock_tcp.connect(TCP_SERVER_ADDRESS, TCP_SERVER_PORT) < 0) {
sog_yang 8:ff7fdd152f14 244 #if DEBUG_LOG
sog_yang 8:ff7fdd152f14 245 pc.printf("Unable to connect to (%s) on port (%d)\n", ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT);
sog_yang 8:ff7fdd152f14 246 #endif
sog_yang 8:ff7fdd152f14 247 sock_tcp.close();
sog_yang 8:ff7fdd152f14 248 ADV_manuf[4] = 0xCF;
sog_yang 8:ff7fdd152f14 249 } else {
sog_yang 8:ff7fdd152f14 250 isConnect = true;
sog_yang 8:ff7fdd152f14 251 isCloudFiling = false;
sog_yang 8:ff7fdd152f14 252 ADV_manuf[4] = 0xF1;
sog_yang 8:ff7fdd152f14 253 #if DEBUG_LOG
sog_yang 8:ff7fdd152f14 254 pc.printf("Connected to Server at %s\n",ECHO_SERVER_ADDRESS);
sog_yang 8:ff7fdd152f14 255 #endif
sog_yang 8:ff7fdd152f14 256 }
sog_yang 8:ff7fdd152f14 257 }
sog_yang 8:ff7fdd152f14 258 }
sog_yang 7:06495d54d107 259 }
sog_yang 7:06495d54d107 260 }
sog_yang 8:ff7fdd152f14 261 BLE::Instance(BLE::DEFAULT_INSTANCE).gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, ADV_manuf, sizeof(ADV_manuf));
sog_yang 8:ff7fdd152f14 262 ble.waitForEvent();
sog_yang 5:ffe1a4c4881e 263 }
sog_yang 7:06495d54d107 264 }