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:
Tue May 02 08:47:57 2017 +0000
Revision:
6:4ca0aa131d20
Parent:
5:ffe1a4c4881e
Child:
7:06495d54d107
BLEWiFi&BioSensor

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sog_yang 5:ffe1a4c4881e 1 #include "mbed.h"
sog_yang 5:ffe1a4c4881e 2 #include "rtos.h"
sog_yang 5:ffe1a4c4881e 3 #include <events/mbed_events.h>
sog_yang 5:ffe1a4c4881e 4
sog_yang 5:ffe1a4c4881e 5 #include "ble/BLE.h"
sog_yang 5:ffe1a4c4881e 6 #include "ble/Gap.h"
sog_yang 5:ffe1a4c4881e 7 #include "ble/services/BatteryService.h"
sog_yang 5:ffe1a4c4881e 8 #include "DOORService.h"
sog_yang 5:ffe1a4c4881e 9 #include "BNO055.h"
sog_yang 5:ffe1a4c4881e 10 #include "AS7000.h"
sog_yang 5:ffe1a4c4881e 11 #include "EthernetInterface.h"
sog_yang 5:ffe1a4c4881e 12 #include "WIFIDevice.h"
sog_yang 5:ffe1a4c4881e 13
sog_yang 5:ffe1a4c4881e 14 BNO055 imu(p0,p30);
sog_yang 5:ffe1a4c4881e 15 AS7000 hrm(p0,p30);
sog_yang 5:ffe1a4c4881e 16 Serial pc(USBTX, USBRX);
sog_yang 5:ffe1a4c4881e 17
sog_yang 5:ffe1a4c4881e 18 Semaphore two_slots(2);
sog_yang 5:ffe1a4c4881e 19 //static Thread t1;
sog_yang 5:ffe1a4c4881e 20 static Thread t2;
sog_yang 5:ffe1a4c4881e 21 static Ticker ticker;
sog_yang 5:ffe1a4c4881e 22
sog_yang 5:ffe1a4c4881e 23 const static char DEVICE_NAME[] = "DOORCTL";
sog_yang 5:ffe1a4c4881e 24 static uint8_t ADV_manuf[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
sog_yang 5:ffe1a4c4881e 25 static char out_buffer_tt[] = "hrm:120 yaw:250.2 pitch:359.1 roll:180.2\n";
sog_yang 5:ffe1a4c4881e 26 static uint8_t BLE_RX_CMD = 0xFF;
sog_yang 5:ffe1a4c4881e 27 static uint8_t doorStatusPayload[2] = {0xFF,};
sog_yang 5:ffe1a4c4881e 28 union IP {
sog_yang 5:ffe1a4c4881e 29 unsigned int ip;
sog_yang 5:ffe1a4c4881e 30 struct {
sog_yang 5:ffe1a4c4881e 31 unsigned char d;
sog_yang 5:ffe1a4c4881e 32 unsigned char c;
sog_yang 5:ffe1a4c4881e 33 unsigned char b;
sog_yang 5:ffe1a4c4881e 34 unsigned char a;
sog_yang 5:ffe1a4c4881e 35 } ip2;
sog_yang 5:ffe1a4c4881e 36 };
sog_yang 5:ffe1a4c4881e 37
sog_yang 5:ffe1a4c4881e 38 char ips[20];
sog_yang 5:ffe1a4c4881e 39 IP ip;
sog_yang 5:ffe1a4c4881e 40 unsigned short a, b, c, d;
sog_yang 5:ffe1a4c4881e 41 BLEDevice ble;
sog_yang 5:ffe1a4c4881e 42 EthernetInterface eth;
sog_yang 5:ffe1a4c4881e 43 WIFIDevice wifi;
sog_yang 5:ffe1a4c4881e 44 TCPSocketConnection sock_tcp;
sog_yang 5:ffe1a4c4881e 45 //UDPSocket sock_udp;
sog_yang 5:ffe1a4c4881e 46 //Endpoint echo_server;
sog_yang 5:ffe1a4c4881e 47
sog_yang 5:ffe1a4c4881e 48 static DOORService *doorServicePtr;
sog_yang 5:ffe1a4c4881e 49 static EventQueue eventQueue(
sog_yang 5:ffe1a4c4881e 50 /* event count */ 16 * /* event size */ 32
sog_yang 5:ffe1a4c4881e 51 );
sog_yang 5:ffe1a4c4881e 52 static char* ECHO_SERVER_ADDRESS = "192.168.2.110";
sog_yang 5:ffe1a4c4881e 53 static int ECHO_SERVER_PORT = 1030;
sog_yang 5:ffe1a4c4881e 54 static bool triggerTempValueUpdate = false;
sog_yang 5:ffe1a4c4881e 55
sog_yang 5:ffe1a4c4881e 56 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
sog_yang 5:ffe1a4c4881e 57 {
sog_yang 5:ffe1a4c4881e 58 BLE::Instance().gap().startAdvertising();
sog_yang 5:ffe1a4c4881e 59 }
sog_yang 5:ffe1a4c4881e 60
sog_yang 5:ffe1a4c4881e 61 void onDataWrittenCallback(const GattWriteCallbackParams *params) {
sog_yang 5:ffe1a4c4881e 62
sog_yang 5:ffe1a4c4881e 63
sog_yang 5:ffe1a4c4881e 64 if ((params->handle == doorServicePtr->getValueHandle()) && (params->len == 1)) {
sog_yang 5:ffe1a4c4881e 65 {
sog_yang 5:ffe1a4c4881e 66 BLE_RX_CMD = *(params->data);
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 void ble_thread() {
sog_yang 5:ffe1a4c4881e 72 while (true) {
sog_yang 5:ffe1a4c4881e 73 switch (BLE_RX_CMD) {
sog_yang 5:ffe1a4c4881e 74 case 0x00:
sog_yang 5:ffe1a4c4881e 75 if ( ADV_manuf[5]== 0xA1) {
sog_yang 5:ffe1a4c4881e 76 eth.disconnect();
sog_yang 5:ffe1a4c4881e 77 sock_tcp.close();
sog_yang 5:ffe1a4c4881e 78 wifi.sleep();
sog_yang 5:ffe1a4c4881e 79 }
sog_yang 5:ffe1a4c4881e 80
sog_yang 5:ffe1a4c4881e 81 BLE_RX_CMD = 0xFF;
sog_yang 5:ffe1a4c4881e 82 doorStatusPayload[0]=0xF0;
sog_yang 5:ffe1a4c4881e 83 ADV_manuf[5] = 0xF0;
sog_yang 5:ffe1a4c4881e 84
sog_yang 5:ffe1a4c4881e 85 eth.init();
sog_yang 5:ffe1a4c4881e 86 wifi.setNetwork(M2M_WIFI_SEC_WPA_PSK, "20-4F-5_Guest", "11223344");
sog_yang 5:ffe1a4c4881e 87 eth.connect();
sog_yang 5:ffe1a4c4881e 88 /*
sog_yang 5:ffe1a4c4881e 89 if(wifi.is_AP_connected())
sog_yang 5:ffe1a4c4881e 90 printf("Connect Success! \n");
sog_yang 5:ffe1a4c4881e 91 else
sog_yang 5:ffe1a4c4881e 92 printf("Connect Fail! \n");
sog_yang 5:ffe1a4c4881e 93
sog_yang 5:ffe1a4c4881e 94 printf("MAC: %s\n", eth.getMACAddress());
sog_yang 5:ffe1a4c4881e 95 printf("IP: %s\n", eth.getIPAddress());
sog_yang 5:ffe1a4c4881e 96 printf("Gateway: %s\n", eth.getGateway());
sog_yang 5:ffe1a4c4881e 97 printf("NetworkMask: %s\n", eth.getNetworkMask());
sog_yang 5:ffe1a4c4881e 98 */
sog_yang 5:ffe1a4c4881e 99 while (sock_tcp.connect(ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT) < 0) {
sog_yang 6:4ca0aa131d20 100 //printf("Unable to connect to (%s) on port (%d)\n", ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT);
sog_yang 5:ffe1a4c4881e 101 wait(1);
sog_yang 5:ffe1a4c4881e 102 }
sog_yang 5:ffe1a4c4881e 103 //printf("Connected to Server at %s\n",ECHO_SERVER_ADDRESS);
sog_yang 5:ffe1a4c4881e 104
sog_yang 5:ffe1a4c4881e 105 snprintf(ips, sizeof(ips), "%s",eth.getIPAddress());
sog_yang 5:ffe1a4c4881e 106 unsigned short a, b, c, d;
sog_yang 5:ffe1a4c4881e 107 sscanf(ips, "%hu.%hu.%hu.%hu", &a, &b, &c, &d);
sog_yang 5:ffe1a4c4881e 108 sprintf(ips, "%x.%x.%x.%x", a, b, c, d);
sog_yang 5:ffe1a4c4881e 109 ADV_manuf[0] = a;
sog_yang 5:ffe1a4c4881e 110 ADV_manuf[1] = b;
sog_yang 5:ffe1a4c4881e 111 ADV_manuf[2] = c;
sog_yang 5:ffe1a4c4881e 112 ADV_manuf[3] = d;
sog_yang 5:ffe1a4c4881e 113 break;
sog_yang 5:ffe1a4c4881e 114
sog_yang 5:ffe1a4c4881e 115 case 0x02:
sog_yang 5:ffe1a4c4881e 116 if ( ADV_manuf[5]== 0xA1) {
sog_yang 5:ffe1a4c4881e 117 eth.disconnect();
sog_yang 5:ffe1a4c4881e 118 sock_tcp.close();
sog_yang 5:ffe1a4c4881e 119 wifi.sleep();
sog_yang 5:ffe1a4c4881e 120 }
sog_yang 5:ffe1a4c4881e 121 BLE_RX_CMD = 0xFF;
sog_yang 5:ffe1a4c4881e 122
sog_yang 5:ffe1a4c4881e 123 ADV_manuf[0] = 0x00;
sog_yang 5:ffe1a4c4881e 124 ADV_manuf[1] = 0x00;
sog_yang 5:ffe1a4c4881e 125 ADV_manuf[2] = 0x00;
sog_yang 5:ffe1a4c4881e 126 ADV_manuf[3] = 0x00;
sog_yang 5:ffe1a4c4881e 127
sog_yang 5:ffe1a4c4881e 128 ADV_manuf[5] = 0xF2;
sog_yang 5:ffe1a4c4881e 129 doorStatusPayload[0]=0xF2;
sog_yang 5:ffe1a4c4881e 130
sog_yang 5:ffe1a4c4881e 131 break;
sog_yang 5:ffe1a4c4881e 132
sog_yang 5:ffe1a4c4881e 133 case 0xA1:
sog_yang 5:ffe1a4c4881e 134 //BLE_RX_CMD = 0xFF;
sog_yang 5:ffe1a4c4881e 135 sprintf(out_buffer_tt,"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 5:ffe1a4c4881e 136 sock_tcp.send_all(out_buffer_tt, sizeof(out_buffer_tt) - 1);
sog_yang 5:ffe1a4c4881e 137 ADV_manuf[5] = 0xA1;
sog_yang 5:ffe1a4c4881e 138 doorStatusPayload[0]=0xA1;
sog_yang 5:ffe1a4c4881e 139 break;
sog_yang 5:ffe1a4c4881e 140 }
sog_yang 5:ffe1a4c4881e 141
sog_yang 5:ffe1a4c4881e 142 if (ble.getGapState().connected) {
sog_yang 5:ffe1a4c4881e 143 ble.updateCharacteristicValue((doorServicePtr->getValueHandle()),doorStatusPayload, 1);
sog_yang 5:ffe1a4c4881e 144 }
sog_yang 5:ffe1a4c4881e 145 }
sog_yang 5:ffe1a4c4881e 146 }
sog_yang 5:ffe1a4c4881e 147
sog_yang 5:ffe1a4c4881e 148
sog_yang 5:ffe1a4c4881e 149
sog_yang 5:ffe1a4c4881e 150 /**
sog_yang 5:ffe1a4c4881e 151 * This function is called when the ble initialization process has failled
sog_yang 5:ffe1a4c4881e 152 */
sog_yang 5:ffe1a4c4881e 153 void onBleInitError(BLE &ble, ble_error_t error)
sog_yang 5:ffe1a4c4881e 154 {
sog_yang 5:ffe1a4c4881e 155 /* Initialization error handling should go here */
sog_yang 5:ffe1a4c4881e 156 }
sog_yang 5:ffe1a4c4881e 157
sog_yang 5:ffe1a4c4881e 158 /**
sog_yang 5:ffe1a4c4881e 159 * Callback triggered when the ble initialization process has finished
sog_yang 5:ffe1a4c4881e 160 */
sog_yang 5:ffe1a4c4881e 161 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
sog_yang 5:ffe1a4c4881e 162 {
sog_yang 5:ffe1a4c4881e 163 BLE& ble = params->ble;
sog_yang 5:ffe1a4c4881e 164 ble_error_t error = params->error;
sog_yang 5:ffe1a4c4881e 165
sog_yang 5:ffe1a4c4881e 166 if (error != BLE_ERROR_NONE) {
sog_yang 5:ffe1a4c4881e 167 /* In case of error, forward the error handling to onBleInitError */
sog_yang 5:ffe1a4c4881e 168 onBleInitError(ble, error);
sog_yang 5:ffe1a4c4881e 169 return;
sog_yang 5:ffe1a4c4881e 170 }
sog_yang 5:ffe1a4c4881e 171
sog_yang 5:ffe1a4c4881e 172 /* Ensure that it is the default instance of BLE */
sog_yang 5:ffe1a4c4881e 173 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
sog_yang 5:ffe1a4c4881e 174 return;
sog_yang 5:ffe1a4c4881e 175 }
sog_yang 5:ffe1a4c4881e 176
sog_yang 5:ffe1a4c4881e 177 ble.gap().onDisconnection(disconnectionCallback);
sog_yang 5:ffe1a4c4881e 178 ble.gattServer().onDataWritten(onDataWrittenCallback);
sog_yang 5:ffe1a4c4881e 179
sog_yang 5:ffe1a4c4881e 180 /* Setup primary services */
sog_yang 5:ffe1a4c4881e 181 uint8_t initialValueForDOORCharacteristic = 0xFF;
sog_yang 5:ffe1a4c4881e 182 doorServicePtr = new DOORService(ble, initialValueForDOORCharacteristic);
sog_yang 5:ffe1a4c4881e 183
sog_yang 5:ffe1a4c4881e 184 /* Setup advertising */
sog_yang 5:ffe1a4c4881e 185 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
sog_yang 5:ffe1a4c4881e 186 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, ADV_manuf, sizeof(ADV_manuf));
sog_yang 5:ffe1a4c4881e 187 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
sog_yang 5:ffe1a4c4881e 188 ble.gap().setAdvertisingInterval(200); /* 1000ms */
sog_yang 5:ffe1a4c4881e 189 ble.gap().startAdvertising();
sog_yang 5:ffe1a4c4881e 190 }
sog_yang 5:ffe1a4c4881e 191
sog_yang 5:ffe1a4c4881e 192 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
sog_yang 5:ffe1a4c4881e 193 BLE &ble = BLE::Instance();
sog_yang 5:ffe1a4c4881e 194 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
sog_yang 5:ffe1a4c4881e 195 }
sog_yang 5:ffe1a4c4881e 196
sog_yang 5:ffe1a4c4881e 197 void network_thread(void const *name) {
sog_yang 5:ffe1a4c4881e 198 while (true) {
sog_yang 5:ffe1a4c4881e 199 two_slots.wait();
sog_yang 5:ffe1a4c4881e 200 //printf("%s\n\r", (const char*)name);
sog_yang 5:ffe1a4c4881e 201 ble_thread();
sog_yang 5:ffe1a4c4881e 202 /*
sog_yang 5:ffe1a4c4881e 203 wait_ms(5);
sog_yang 5:ffe1a4c4881e 204 imu.get_angles(); //query the i2c device
sog_yang 5:ffe1a4c4881e 205 //printf("get angles\n");
sog_yang 5:ffe1a4c4881e 206 wait_ms(5);
sog_yang 5:ffe1a4c4881e 207 hrm.hr_only();
sog_yang 5:ffe1a4c4881e 208 //printf("get hrm\n");
sog_yang 5:ffe1a4c4881e 209 */
sog_yang 6:4ca0aa131d20 210 wait_ms(100);
sog_yang 5:ffe1a4c4881e 211 two_slots.release();
sog_yang 5:ffe1a4c4881e 212 }
sog_yang 5:ffe1a4c4881e 213 }
sog_yang 5:ffe1a4c4881e 214
sog_yang 5:ffe1a4c4881e 215 void periodicCallback(void){
sog_yang 5:ffe1a4c4881e 216 triggerTempValueUpdate = true;
sog_yang 5:ffe1a4c4881e 217 }
sog_yang 5:ffe1a4c4881e 218
sog_yang 5:ffe1a4c4881e 219 int main (void) {
sog_yang 5:ffe1a4c4881e 220 pc.baud(38400);
sog_yang 5:ffe1a4c4881e 221 hrm.enable();
sog_yang 5:ffe1a4c4881e 222 imu.reset();
sog_yang 5:ffe1a4c4881e 223 imu.setmode(OPERATION_MODE_NDOF);
sog_yang 5:ffe1a4c4881e 224
sog_yang 5:ffe1a4c4881e 225
sog_yang 5:ffe1a4c4881e 226 BLE &ble = BLE::Instance();
sog_yang 5:ffe1a4c4881e 227 ble.onEventsToProcess(scheduleBleEventsProcessing);
sog_yang 5:ffe1a4c4881e 228 ble.init(bleInitComplete);
sog_yang 5:ffe1a4c4881e 229
sog_yang 5:ffe1a4c4881e 230 // t1.start(callback(sensor_thread, (void *)"Sensor Thread"));
sog_yang 5:ffe1a4c4881e 231 t2.start(callback(network_thread, (void *)"BLE-WIFI CTL Thread"));
sog_yang 5:ffe1a4c4881e 232
sog_yang 5:ffe1a4c4881e 233
sog_yang 5:ffe1a4c4881e 234 ticker.attach(periodicCallback, 1); // blink LED every 1 second
sog_yang 5:ffe1a4c4881e 235
sog_yang 5:ffe1a4c4881e 236
sog_yang 5:ffe1a4c4881e 237 while (true) {
sog_yang 5:ffe1a4c4881e 238 if (triggerTempValueUpdate) {
sog_yang 5:ffe1a4c4881e 239 /* Do blocking calls or whatever hardware-specific action is
sog_yang 5:ffe1a4c4881e 240 * necessary to poll the sensor. */
sog_yang 5:ffe1a4c4881e 241 BLE::Instance(BLE::DEFAULT_INSTANCE).gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, ADV_manuf, sizeof(ADV_manuf));
sog_yang 5:ffe1a4c4881e 242 printf("*HR=%03d#", hrm.hrm.hreat_rate);
sog_yang 5:ffe1a4c4881e 243 triggerTempValueUpdate = false;
sog_yang 5:ffe1a4c4881e 244 }
sog_yang 5:ffe1a4c4881e 245 hrm.hr_only();
sog_yang 5:ffe1a4c4881e 246 wait_ms(15);
sog_yang 5:ffe1a4c4881e 247 imu.get_angles(); //query the i2c device
sog_yang 5:ffe1a4c4881e 248 wait_ms(15);
sog_yang 5:ffe1a4c4881e 249 ble.waitForEvent();
sog_yang 5:ffe1a4c4881e 250 }
sog_yang 5:ffe1a4c4881e 251 }