Central/ Peripheral example: Central Device connects to a Peripheral called "LED" and a characteristic is toggled automatically with a random sleep interval (10-100ms) -> BLE_LED_PERIPHERAL needed With a external uC the latency Time of a round trip is measured via pin interrupts.
Dependencies: BLE_API mbed nRF51822
Fork of BLE_LED_CENTRAL_TIME_AUTO by
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "mbed.h" 00018 #include "ble/BLE.h" 00019 #include "ble/DiscoveredCharacteristic.h" 00020 #include "ble/Gap.h" 00021 00022 DigitalOut alivenessLED(p16, 1); 00023 DigitalOut gateLED(p15,1); 00024 DigitalOut flagStart(p2, 0); 00025 DigitalOut flagStop(p3, 1); 00026 00027 00028 //InterruptIn button(p9); 00029 Serial pc(p5, p4); 00030 Ticker ticker, loop; 00031 Timer latency; 00032 00033 timestamp_t latencyTime; 00034 uint8_t toggledValue = 0x1; 00035 uint8_t counter = 0; 00036 uint8_t randNumber = 5; 00037 uint8_t randCount = 10; 00038 00039 static DiscoveredCharacteristic ledCharacteristic; 00040 static const char PEER_NAME[] = "LED"; 00041 static Gap::ConnectionParams_t para; 00042 00043 void periodicCallback(void) 00044 { 00045 if(!BLE::Instance().getGapState().connected){ 00046 alivenessLED = !alivenessLED; /* Do blinky on LED1 while waiting for BLE events */ 00047 gateLED = 1; 00048 } 00049 counter += 1; 00050 } 00051 00052 void triggerCallback(void) 00053 { 00054 randCount = 0; 00055 if(!BLE::Instance().getGapState().connected){ 00056 //pc.printf("not connected \n"); 00057 return; 00058 } 00059 else{ 00060 if(counter > 5 && flagStop.read()){ 00061 alivenessLED = 1; 00062 //latency.start(); 00063 flagStart = 1; 00064 flagStop = 0; 00065 toggledValue = toggledValue ^ 0x1; 00066 ledCharacteristic.write(1, &toggledValue); 00067 //pc.printf("AckStatus = %i \n", AckStatus); 00068 } 00069 } 00070 } 00071 00072 void randCallback(void) 00073 { 00074 //Gap::GapState_t GapInfo; //class Gap with struct GapState_t 00075 randCount += 1; 00076 if(randCount > randNumber+1 && BLE::Instance().getGapState().connected){ 00077 //if(BLE::Instance().getGapState().connected){ 00078 00079 triggerCallback(); 00080 gateLED = !gateLED; 00081 } 00082 } 00083 00084 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) 00085 { 00086 for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { 00087 00088 const uint8_t record_length = params->advertisingData[i]; 00089 if (record_length == 0) { 00090 continue; 00091 } 00092 const uint8_t type = params->advertisingData[i + 1]; // PDU Advertising // AD length 1B / AD type 1B / AD data 0-22B // 00093 const uint8_t* value = params->advertisingData + i + 2; //pointer adresse + i + 2, so AD data 00094 const uint8_t value_length = record_length - 1; 00095 00096 if(type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { //0x09 is type of complete local name 00097 if ((value_length == sizeof(PEER_NAME)) && (memcmp(value, PEER_NAME, value_length) == 0)) { /* compares name LED with advertisingData*/ 00098 pc.printf( 00099 "adv peerAddr[%02x %02x %02x %02x %02x %02x], LocalName %s, rssi %d, isScanResponse %u, AdvertisementType %u\r\n", 00100 params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], 00101 params->peerAddr[1], params->peerAddr[0], value, params->rssi, params->isScanResponse, params->type 00102 ); 00103 printf("\r\n"); 00104 00105 //create wanted ConnectionParameters (defined in nrf51822/target_nrf5/source/nrf5xGap.cpp) 00106 para.minConnectionInterval = Gap::MSEC_TO_GAP_DURATION_UNITS(100); 00107 para.maxConnectionInterval = Gap::MSEC_TO_GAP_DURATION_UNITS(100); 00108 para.slaveLatency = 0; 00109 para.connectionSupervisionTimeout = 600; 00110 00111 BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, ¶, NULL); 00112 break; 00113 } 00114 } 00115 i += record_length; 00116 } 00117 } 00118 00119 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) 00120 { 00121 pc.printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().read()); 00122 if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* LED characteristic of device (Read/Write) */ 00123 ledCharacteristic = *characteristicP; 00124 } 00125 } 00126 00127 void writeResponseCallback(const GattWriteCallbackParams *response) 00128 { 00129 if (response->handle == ledCharacteristic.getValueHandle()) { //handle is ID of connection 00130 //ledCharacteristic.read(); 00131 //latency.stop(); 00132 flagStart = 0; 00133 flagStop = 1; 00134 //latencyTime = latency.read_high_resolution_us(); 00135 //latency.reset(); 00136 00137 //pc.printf("ledCharacteristic: %d %d\r\n",response->data[0],response->data[1]); 00138 //pc.printf("Latency Time: %d us \n",latencyTime); 00139 //writeVal(latencyTime); 00140 randNumber = rand()%10; //number between 0 and 9 00141 /*pc.printf("triggerRead: handle %u, writeOp %u \r\n", response->connHandle, response->writeOp); 00142 for (unsigned index = 0; index < response->len; index++) { 00143 printf("%c[%02x]", response->data[index], response->data[index]); 00144 } 00145 pc.printf("\r\n");*/ 00146 } 00147 } 00148 00149 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) 00150 { 00151 if (params->role == Gap::CENTRAL) { 00152 BLE &ble = BLE::Instance(); 00153 //ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); 00154 ble.gattClient().launchServiceDiscovery(params->handle, NULL, characteristicDiscoveryCallback, 0xa000, 0xa001); 00155 00156 uint16_t slaveLat = params->connectionParams->slaveLatency; 00157 uint16_t maxConnectionInt = params->connectionParams->maxConnectionInterval; 00158 uint16_t minConnectionInt = params->connectionParams->minConnectionInterval; 00159 uint16_t connectionTimeout = params->connectionParams->connectionSupervisionTimeout; 00160 00161 pc.printf("slaveLatency %u, minConnection %u, maxConnection %u, connectionTimeout %u \n", slaveLat, minConnectionInt, maxConnectionInt, connectionTimeout); 00162 pc.printf("handle %u, role %u \n", params->handle, params->role); 00163 pc.printf("connected\r\n"); 00164 pc.printf("\r\n"); 00165 } 00166 } 00167 00168 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) 00169 { 00170 pc.printf("disconnected\r\n"); 00171 /* Start scanning and try to connect again */ 00172 BLE::Instance().gap().startScan(advertisementCallback); 00173 counter = 0; 00174 } 00175 00176 void onBleInitError(BLE &ble, ble_error_t error) 00177 { 00178 /* Initialization error handling should go here */ 00179 } 00180 00181 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00182 { 00183 BLE& ble = params->ble; 00184 ble_error_t error = params->error; 00185 00186 if (error != BLE_ERROR_NONE) { 00187 /* In case of error, forward the error handling to onBleInitError */ 00188 onBleInitError(ble, error); 00189 return; 00190 } 00191 00192 /* Ensure that it is the default instance of BLE */ 00193 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { 00194 return; 00195 } 00196 00197 ble.gap().onDisconnection(disconnectionCallback); 00198 ble.gap().onConnection(connectionCallback); 00199 00200 ble.gattClient().onDataWritten(writeResponseCallback); 00201 00202 // scan interval: 400ms and scan window: 400ms. 00203 // Every 400ms the device will scan for 400ms 00204 // This means that the device will scan continuously. 00205 ble.gap().setScanParams(400, 400); 00206 ble.gap().startScan(advertisementCallback); 00207 00208 } 00209 00210 00211 int main(void) { 00212 pc.baud(115200); 00213 00214 ticker.attach(periodicCallback, 1); /* Blink LED every second */ 00215 //button.rise(buttonPressedCallback); 00216 loop.attach(randCallback, 0.01); 00217 srand(time(NULL)); 00218 00219 BLE &ble = BLE::Instance(); 00220 ble.init(bleInitComplete); 00221 pc.printf("Initialization complete... \n"); 00222 00223 counter = 0; 00224 //latency.reset(); 00225 00226 while (true) { 00227 ble.waitForEvent(); 00228 } 00229 }
Generated on Tue Jul 19 2022 23:54:42 by
1.7.2
