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@6:4ca0aa131d20, 2017-05-02 (annotated)
- 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?
User | Revision | Line number | New 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 | } |