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.
- Download or build a TCP Server on you host computer
- Please find out the TCP server code or install TCP server application in your host computer.
- Import this sample application and setup these information about AP & TCP Server
- *char* AP_SSID = "SOG";
- *char* AP_PWD = "1122334455667788";
- *char* TCP_SERVER_ADDRESS = "10.0.1.13";
- *int TCP_SERVER_PORT = 1030;
- Compiler your code and download to your mBed device.
- Control your mBed device
- 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
0x00 | 0x02 | 0xA1 |
---|---|---|
WiFi,AP&TCP Server connect | WiFi,AP, & TCP Server disconnect | Send sensor data to TCP Server |
main.cpp@8:ff7fdd152f14, 2017-05-04 (annotated)
- Committer:
- sog_yang
- Date:
- Thu May 04 05:08:42 2017 +0000
- Revision:
- 8:ff7fdd152f14
- Parent:
- 7:06495d54d107
- Child:
- 9:d1861b00e0fd
DEMO version - 4MAY'17
Who changed what in which revision?
User | Revision | Line number | New 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 | 5:ffe1a4c4881e | 31 | EthernetInterface eth; |
sog_yang | 5:ffe1a4c4881e | 32 | WIFIDevice wifi; |
sog_yang | 7:06495d54d107 | 33 | |
sog_yang | 5:ffe1a4c4881e | 34 | TCPSocketConnection sock_tcp; |
sog_yang | 7:06495d54d107 | 35 | char* ECHO_SERVER_ADDRESS = "10.0.1.13"; |
sog_yang | 7:06495d54d107 | 36 | int ECHO_SERVER_PORT = 1030; |
sog_yang | 5:ffe1a4c4881e | 37 | |
sog_yang | 7:06495d54d107 | 38 | uint8_t initialValueForDOORCharacteristic = 0xFF; |
sog_yang | 7:06495d54d107 | 39 | uint8_t BLE_RX_CMD = 0xFF; |
sog_yang | 8:ff7fdd152f14 | 40 | const char DEVICE_NAME[] = "FITNCTL"; |
sog_yang | 7:06495d54d107 | 41 | 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 | 42 | char out_buffer[45]; |
sog_yang | 5:ffe1a4c4881e | 43 | static EventQueue eventQueue( |
sog_yang | 5:ffe1a4c4881e | 44 | /* event count */ 16 * /* event size */ 32 |
sog_yang | 5:ffe1a4c4881e | 45 | ); |
sog_yang | 7:06495d54d107 | 46 | |
sog_yang | 7:06495d54d107 | 47 | bool isConnect = false; |
sog_yang | 7:06495d54d107 | 48 | bool isWiFiEnable = false; |
sog_yang | 8:ff7fdd152f14 | 49 | bool isCloudFiling = false; |
sog_yang | 7:06495d54d107 | 50 | |
sog_yang | 5:ffe1a4c4881e | 51 | |
sog_yang | 5:ffe1a4c4881e | 52 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) |
sog_yang | 5:ffe1a4c4881e | 53 | { |
sog_yang | 5:ffe1a4c4881e | 54 | BLE::Instance().gap().startAdvertising(); |
sog_yang | 5:ffe1a4c4881e | 55 | } |
sog_yang | 5:ffe1a4c4881e | 56 | |
sog_yang | 5:ffe1a4c4881e | 57 | void onDataWrittenCallback(const GattWriteCallbackParams *params) { |
sog_yang | 5:ffe1a4c4881e | 58 | |
sog_yang | 5:ffe1a4c4881e | 59 | |
sog_yang | 5:ffe1a4c4881e | 60 | if ((params->handle == doorServicePtr->getValueHandle()) && (params->len == 1)) { |
sog_yang | 5:ffe1a4c4881e | 61 | { |
sog_yang | 7:06495d54d107 | 62 | BLE_RX_CMD = *(params->data); |
sog_yang | 5:ffe1a4c4881e | 63 | } |
sog_yang | 5:ffe1a4c4881e | 64 | } |
sog_yang | 5:ffe1a4c4881e | 65 | } |
sog_yang | 5:ffe1a4c4881e | 66 | |
sog_yang | 5:ffe1a4c4881e | 67 | /** |
sog_yang | 5:ffe1a4c4881e | 68 | * This function is called when the ble initialization process has failled |
sog_yang | 5:ffe1a4c4881e | 69 | */ |
sog_yang | 5:ffe1a4c4881e | 70 | void onBleInitError(BLE &ble, ble_error_t error) |
sog_yang | 5:ffe1a4c4881e | 71 | { |
sog_yang | 5:ffe1a4c4881e | 72 | /* Initialization error handling should go here */ |
sog_yang | 5:ffe1a4c4881e | 73 | } |
sog_yang | 5:ffe1a4c4881e | 74 | |
sog_yang | 5:ffe1a4c4881e | 75 | /** |
sog_yang | 5:ffe1a4c4881e | 76 | * Callback triggered when the ble initialization process has finished |
sog_yang | 5:ffe1a4c4881e | 77 | */ |
sog_yang | 5:ffe1a4c4881e | 78 | void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) |
sog_yang | 5:ffe1a4c4881e | 79 | { |
sog_yang | 5:ffe1a4c4881e | 80 | BLE& ble = params->ble; |
sog_yang | 5:ffe1a4c4881e | 81 | ble_error_t error = params->error; |
sog_yang | 5:ffe1a4c4881e | 82 | |
sog_yang | 5:ffe1a4c4881e | 83 | if (error != BLE_ERROR_NONE) { |
sog_yang | 5:ffe1a4c4881e | 84 | /* In case of error, forward the error handling to onBleInitError */ |
sog_yang | 5:ffe1a4c4881e | 85 | onBleInitError(ble, error); |
sog_yang | 5:ffe1a4c4881e | 86 | return; |
sog_yang | 5:ffe1a4c4881e | 87 | } |
sog_yang | 5:ffe1a4c4881e | 88 | |
sog_yang | 5:ffe1a4c4881e | 89 | /* Ensure that it is the default instance of BLE */ |
sog_yang | 5:ffe1a4c4881e | 90 | if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { |
sog_yang | 5:ffe1a4c4881e | 91 | return; |
sog_yang | 5:ffe1a4c4881e | 92 | } |
sog_yang | 5:ffe1a4c4881e | 93 | |
sog_yang | 5:ffe1a4c4881e | 94 | ble.gap().onDisconnection(disconnectionCallback); |
sog_yang | 5:ffe1a4c4881e | 95 | ble.gattServer().onDataWritten(onDataWrittenCallback); |
sog_yang | 5:ffe1a4c4881e | 96 | |
sog_yang | 5:ffe1a4c4881e | 97 | /* Setup primary services */ |
sog_yang | 5:ffe1a4c4881e | 98 | doorServicePtr = new DOORService(ble, initialValueForDOORCharacteristic); |
sog_yang | 5:ffe1a4c4881e | 99 | |
sog_yang | 5:ffe1a4c4881e | 100 | /* Setup advertising */ |
sog_yang | 5:ffe1a4c4881e | 101 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
sog_yang | 5:ffe1a4c4881e | 102 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, ADV_manuf, sizeof(ADV_manuf)); |
sog_yang | 5:ffe1a4c4881e | 103 | ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
sog_yang | 7:06495d54d107 | 104 | ble.gap().setAdvertisingInterval(150); /* 1000ms */ |
sog_yang | 5:ffe1a4c4881e | 105 | ble.gap().startAdvertising(); |
sog_yang | 5:ffe1a4c4881e | 106 | } |
sog_yang | 5:ffe1a4c4881e | 107 | |
sog_yang | 5:ffe1a4c4881e | 108 | void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { |
sog_yang | 5:ffe1a4c4881e | 109 | BLE &ble = BLE::Instance(); |
sog_yang | 5:ffe1a4c4881e | 110 | eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); |
sog_yang | 5:ffe1a4c4881e | 111 | } |
sog_yang | 7:06495d54d107 | 112 | |
sog_yang | 7:06495d54d107 | 113 | |
sog_yang | 5:ffe1a4c4881e | 114 | int main (void) { |
sog_yang | 7:06495d54d107 | 115 | |
sog_yang | 5:ffe1a4c4881e | 116 | hrm.enable(); |
sog_yang | 7:06495d54d107 | 117 | imu.reset(); |
sog_yang | 5:ffe1a4c4881e | 118 | imu.setmode(OPERATION_MODE_NDOF); |
sog_yang | 5:ffe1a4c4881e | 119 | |
sog_yang | 5:ffe1a4c4881e | 120 | |
sog_yang | 5:ffe1a4c4881e | 121 | BLE &ble = BLE::Instance(); |
sog_yang | 5:ffe1a4c4881e | 122 | ble.onEventsToProcess(scheduleBleEventsProcessing); |
sog_yang | 5:ffe1a4c4881e | 123 | ble.init(bleInitComplete); |
sog_yang | 7:06495d54d107 | 124 | |
sog_yang | 5:ffe1a4c4881e | 125 | while (true) { |
sog_yang | 7:06495d54d107 | 126 | imu.get_angles(); //query the i2c device |
sog_yang | 7:06495d54d107 | 127 | hrm.hr_only(); |
sog_yang | 8:ff7fdd152f14 | 128 | pc.printf("*HR=%03d#", hrm.hrm.hreat_rate); |
sog_yang | 7:06495d54d107 | 129 | /* GATT Command 0xA1 Cloud Data Transfer*/ |
sog_yang | 8:ff7fdd152f14 | 130 | if (BLE_RX_CMD == 0xA1){ |
sog_yang | 8:ff7fdd152f14 | 131 | ADV_manuf[5] = 0xF1; |
sog_yang | 8:ff7fdd152f14 | 132 | if (isWiFiEnable == true){ |
sog_yang | 8:ff7fdd152f14 | 133 | if (isConnect == true) { |
sog_yang | 8:ff7fdd152f14 | 134 | 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 | 135 | sock_tcp.send_all(out_buffer, sizeof(out_buffer) - 1); |
sog_yang | 8:ff7fdd152f14 | 136 | isCloudFiling = true; |
sog_yang | 7:06495d54d107 | 137 | } else { |
sog_yang | 8:ff7fdd152f14 | 138 | if (sock_tcp.connect(ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT) < 0) { |
sog_yang | 8:ff7fdd152f14 | 139 | isConnect = false; |
sog_yang | 8:ff7fdd152f14 | 140 | BLE_RX_CMD = 0xFF; |
sog_yang | 8:ff7fdd152f14 | 141 | #if DEBUG_LOG |
sog_yang | 8:ff7fdd152f14 | 142 | pc.printf("Unable to connect to (%s) on port (%d)\n", ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT); |
sog_yang | 8:ff7fdd152f14 | 143 | #endif |
sog_yang | 8:ff7fdd152f14 | 144 | ADV_manuf[4] = 0xCF; |
sog_yang | 8:ff7fdd152f14 | 145 | BLE_RX_CMD = 0xFF; |
sog_yang | 8:ff7fdd152f14 | 146 | } else { |
sog_yang | 8:ff7fdd152f14 | 147 | isConnect = true; |
sog_yang | 8:ff7fdd152f14 | 148 | ADV_manuf[4] = 0xF1; |
sog_yang | 8:ff7fdd152f14 | 149 | #if DEBUG_LOG |
sog_yang | 8:ff7fdd152f14 | 150 | pc.printf("Connected to Server at %s\n",ECHO_SERVER_ADDRESS); |
sog_yang | 8:ff7fdd152f14 | 151 | #endif |
sog_yang | 8:ff7fdd152f14 | 152 | } |
sog_yang | 7:06495d54d107 | 153 | } |
sog_yang | 7:06495d54d107 | 154 | } |
sog_yang | 7:06495d54d107 | 155 | } |
sog_yang | 7:06495d54d107 | 156 | /* GATT Command 0x02 WiFI & Cloud Connection Close*/ |
sog_yang | 7:06495d54d107 | 157 | if (BLE_RX_CMD == 0x02){ |
sog_yang | 7:06495d54d107 | 158 | ADV_manuf[5] = 0xF2; |
sog_yang | 7:06495d54d107 | 159 | if ( isConnect == true ) { |
sog_yang | 7:06495d54d107 | 160 | sock_tcp.close(); |
sog_yang | 7:06495d54d107 | 161 | isConnect = false; |
sog_yang | 5:ffe1a4c4881e | 162 | } |
sog_yang | 7:06495d54d107 | 163 | if ( isWiFiEnable == true ) { |
sog_yang | 7:06495d54d107 | 164 | eth.disconnect(); |
sog_yang | 7:06495d54d107 | 165 | wifi.sleep(); |
sog_yang | 7:06495d54d107 | 166 | isWiFiEnable = false; |
sog_yang | 7:06495d54d107 | 167 | } |
sog_yang | 8:ff7fdd152f14 | 168 | if (isConnect == true) isConnect = false; |
sog_yang | 8:ff7fdd152f14 | 169 | isConnect = false; |
sog_yang | 8:ff7fdd152f14 | 170 | isWiFiEnable = false; |
sog_yang | 8:ff7fdd152f14 | 171 | isCloudFiling = false; |
sog_yang | 7:06495d54d107 | 172 | |
sog_yang | 7:06495d54d107 | 173 | BLE_RX_CMD = 0xFF; |
sog_yang | 7:06495d54d107 | 174 | ADV_manuf[0] = 0x00; |
sog_yang | 7:06495d54d107 | 175 | ADV_manuf[1] = 0x00; |
sog_yang | 7:06495d54d107 | 176 | ADV_manuf[2] = 0x00; |
sog_yang | 8:ff7fdd152f14 | 177 | ADV_manuf[3] = 0x00; |
sog_yang | 8:ff7fdd152f14 | 178 | ADV_manuf[4] = 0x00; |
sog_yang | 7:06495d54d107 | 179 | } |
sog_yang | 7:06495d54d107 | 180 | /* GATT Command 0x0 init WiFI & Cloud Connection*/ |
sog_yang | 7:06495d54d107 | 181 | if (BLE_RX_CMD == 0x00){ |
sog_yang | 8:ff7fdd152f14 | 182 | if(isCloudFiling == false) { |
sog_yang | 8:ff7fdd152f14 | 183 | BLE_RX_CMD = 0xFF; |
sog_yang | 8:ff7fdd152f14 | 184 | ADV_manuf[5] = 0xF0; |
sog_yang | 7:06495d54d107 | 185 | |
sog_yang | 8:ff7fdd152f14 | 186 | if (isWiFiEnable == false) { |
sog_yang | 8:ff7fdd152f14 | 187 | eth.init(); |
sog_yang | 8:ff7fdd152f14 | 188 | wifi.setNetwork(M2M_WIFI_SEC_WPA_PSK, "SOG", "0227322327"); |
sog_yang | 8:ff7fdd152f14 | 189 | eth.connect(); |
sog_yang | 8:ff7fdd152f14 | 190 | while(true) { |
sog_yang | 8:ff7fdd152f14 | 191 | if (wifi.is_AP_connected()==1) break; |
sog_yang | 8:ff7fdd152f14 | 192 | } |
sog_yang | 8:ff7fdd152f14 | 193 | #if DEBUG_LOG |
sog_yang | 8:ff7fdd152f14 | 194 | pc.printf("Connect Success! \n"); |
sog_yang | 8:ff7fdd152f14 | 195 | pc.printf("MAC: %s\n", eth.getMACAddress()); |
sog_yang | 8:ff7fdd152f14 | 196 | pc.printf("IP: %s\n", eth.getIPAddress()); |
sog_yang | 8:ff7fdd152f14 | 197 | pc.printf("Gateway: %s\n", eth.getGateway()); |
sog_yang | 8:ff7fdd152f14 | 198 | pc.printf("NetworkMask: %s\n", eth.getNetworkMask()); |
sog_yang | 8:ff7fdd152f14 | 199 | #endif |
sog_yang | 8:ff7fdd152f14 | 200 | snprintf(ips, sizeof(ips), "%s",eth.getIPAddress()); |
sog_yang | 8:ff7fdd152f14 | 201 | unsigned short a, b, c, d; |
sog_yang | 8:ff7fdd152f14 | 202 | sscanf(ips, "%hu.%hu.%hu.%hu", &a, &b, &c, &d); |
sog_yang | 8:ff7fdd152f14 | 203 | sprintf(ips, "%x.%x.%x.%x", a, b, c, d); |
sog_yang | 8:ff7fdd152f14 | 204 | ADV_manuf[0] = a; |
sog_yang | 8:ff7fdd152f14 | 205 | ADV_manuf[1] = b; |
sog_yang | 8:ff7fdd152f14 | 206 | ADV_manuf[2] = c; |
sog_yang | 8:ff7fdd152f14 | 207 | ADV_manuf[3] = d; |
sog_yang | 8:ff7fdd152f14 | 208 | isWiFiEnable = true; |
sog_yang | 8:ff7fdd152f14 | 209 | } |
sog_yang | 8:ff7fdd152f14 | 210 | |
sog_yang | 8:ff7fdd152f14 | 211 | if (isConnect == false) { |
sog_yang | 8:ff7fdd152f14 | 212 | if (isWiFiEnable == true) { |
sog_yang | 8:ff7fdd152f14 | 213 | if (sock_tcp.connect(ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT) < 0) { |
sog_yang | 8:ff7fdd152f14 | 214 | #if DEBUG_LOG |
sog_yang | 8:ff7fdd152f14 | 215 | pc.printf("Unable to connect to (%s) on port (%d)\n", ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT); |
sog_yang | 8:ff7fdd152f14 | 216 | #endif |
sog_yang | 8:ff7fdd152f14 | 217 | sock_tcp.close(); |
sog_yang | 8:ff7fdd152f14 | 218 | ADV_manuf[4] = 0xCF; |
sog_yang | 8:ff7fdd152f14 | 219 | } else { |
sog_yang | 8:ff7fdd152f14 | 220 | isConnect = true; |
sog_yang | 8:ff7fdd152f14 | 221 | isCloudFiling = false; |
sog_yang | 8:ff7fdd152f14 | 222 | ADV_manuf[4] = 0xF1; |
sog_yang | 8:ff7fdd152f14 | 223 | #if DEBUG_LOG |
sog_yang | 8:ff7fdd152f14 | 224 | pc.printf("Connected to Server at %s\n",ECHO_SERVER_ADDRESS); |
sog_yang | 8:ff7fdd152f14 | 225 | #endif |
sog_yang | 8:ff7fdd152f14 | 226 | } |
sog_yang | 8:ff7fdd152f14 | 227 | } |
sog_yang | 8:ff7fdd152f14 | 228 | } |
sog_yang | 7:06495d54d107 | 229 | } |
sog_yang | 7:06495d54d107 | 230 | } |
sog_yang | 8:ff7fdd152f14 | 231 | BLE::Instance(BLE::DEFAULT_INSTANCE).gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, ADV_manuf, sizeof(ADV_manuf)); |
sog_yang | 8:ff7fdd152f14 | 232 | ble.waitForEvent(); |
sog_yang | 5:ffe1a4c4881e | 233 | } |
sog_yang | 7:06495d54d107 | 234 | } |