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:
Sat May 06 00:08:06 2017 +0000
Revision:
10:248b81efda00
Parent:
9:d1861b00e0fd
Child:
11:54a1a576df9f
Add TCP none-blocking feature.

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