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 May 04 10:43:36 2017 +0000
Revision:
9:d1861b00e0fd
Parent:
8:ff7fdd152f14
Child:
10:248b81efda00
Fix UART to LCM MCU Pull up issue

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 9:d1861b00e0fd 36 //char* ECHO_SERVER_ADDRESS = "10.0.1.13";
sog_yang 9:d1861b00e0fd 37 char* ECHO_SERVER_ADDRESS = "192.168.2.184";
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("");
sog_yang 9:d1861b00e0fd 143 pc.printf("*HR=%03d#", hrm.hrm.hreat_rate);
sog_yang 9:d1861b00e0fd 144 i=0;
sog_yang 9:d1861b00e0fd 145 } i++;
sog_yang 9:d1861b00e0fd 146 }
sog_yang 7:06495d54d107 147 /* GATT Command 0xA1 Cloud Data Transfer*/
sog_yang 8:ff7fdd152f14 148 if (BLE_RX_CMD == 0xA1){
sog_yang 8:ff7fdd152f14 149 ADV_manuf[5] = 0xF1;
sog_yang 8:ff7fdd152f14 150 if (isWiFiEnable == true){
sog_yang 8:ff7fdd152f14 151 if (isConnect == true) {
sog_yang 9:d1861b00e0fd 152 #if 1
sog_yang 9:d1861b00e0fd 153 if (j > 2){
sog_yang 9:d1861b00e0fd 154 pc.printf("");
sog_yang 9:d1861b00e0fd 155 pc.printf("*HR=%03d#", hrm.hrm.hreat_rate);
sog_yang 9:d1861b00e0fd 156 j = 0;
sog_yang 9:d1861b00e0fd 157 }j++;
sog_yang 9:d1861b00e0fd 158 #endif
sog_yang 8:ff7fdd152f14 159 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 160 sock_tcp.send_all(out_buffer, sizeof(out_buffer) - 1);
sog_yang 8:ff7fdd152f14 161 isCloudFiling = true;
sog_yang 7:06495d54d107 162 } else {
sog_yang 8:ff7fdd152f14 163 if (sock_tcp.connect(ECHO_SERVER_ADDRESS, ECHO_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 9:d1861b00e0fd 217 //wifi.setNetwork(M2M_WIFI_SEC_WPA_PSK, "SOG", "0227322327");
sog_yang 9:d1861b00e0fd 218 wifi.setNetwork(M2M_WIFI_SEC_WPA_PSK, "20-4F-5_Guest", "11223344");
sog_yang 8:ff7fdd152f14 219 eth.connect();
sog_yang 8:ff7fdd152f14 220 while(true) {
sog_yang 8:ff7fdd152f14 221 if (wifi.is_AP_connected()==1) break;
sog_yang 8:ff7fdd152f14 222 }
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 8:ff7fdd152f14 243 if (sock_tcp.connect(ECHO_SERVER_ADDRESS, ECHO_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 }