Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API mbed nRF51822
main.cpp
00001 /* 00002 Copyright (c) 2016 Y. Miyakawa 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00005 and associated documentation files (the "Software"), to deal in the Software without restriction, 00006 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 00007 and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 00008 subject to the following conditions: 00009 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 00010 00011 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 00012 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 00013 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 00014 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00015 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00016 */ 00017 00018 #include "mbed.h" 00019 #include "ble/BLE.h" 00020 #include "CyclingSpeedAndCadenceService.h" 00021 #include "ble/services/DeviceInformationService.h" 00022 00023 DigitalOut led1(LED1); 00024 00025 const static char DEVICE_NAME[] = "CSC1"; 00026 static const uint16_t uuid16_list[] = {GattService::UUID_CYCLING_SPEED_AND_CADENCE, 00027 GattService::UUID_DEVICE_INFORMATION_SERVICE}; 00028 00029 static volatile bool triggerSensorPolling = false; 00030 00031 CyclingSpeedAndCadenceService *cyclingSpeedAndCadenceService; 00032 DeviceInformationService *deviceInfo; 00033 00034 uint16_t feature = CyclingSpeedAndCadenceService::FEATURE_WHEEL_REVOLUTION_DATA 00035 + CyclingSpeedAndCadenceService::FEATURE_CRANK_REVOLUTION_DATA; 00036 00037 uint8_t flags = CyclingSpeedAndCadenceService::FLAG_WHEEL_REVOLUTION_DATA_PRESENT 00038 + CyclingSpeedAndCadenceService::FLAG_CRANK_REVOLUTION_DATA_PRESENT; 00039 00040 uint8_t location = CyclingSpeedAndCadenceService::LOCATION_CHAINSTAY; 00041 00042 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) 00043 { 00044 } 00045 00046 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) 00047 { 00048 triggerSensorPolling = false; 00049 BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); // restart advertising 00050 } 00051 00052 void confirmationRcvCallBack(Gap::Handle_t handle) 00053 { 00054 } 00055 00056 void periodicCallback(void) 00057 { 00058 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ 00059 00060 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do 00061 * heavy-weight sensor polling from the main thread. */ 00062 triggerSensorPolling = true; 00063 } 00064 00065 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00066 { 00067 BLE &ble = params->ble; 00068 ble_error_t error = params->error; 00069 00070 if (error != BLE_ERROR_NONE) { 00071 return; 00072 } 00073 00074 ble.gap().onConnection(connectionCallback); 00075 ble.gap().onDisconnection(disconnectionCallback); 00076 ble.onConfirmationReceived(confirmationRcvCallBack); 00077 00078 /* Setup primary service. */ 00079 cyclingSpeedAndCadenceService = new CyclingSpeedAndCadenceService(ble, feature, location); 00080 00081 /* Setup auxiliary service. */ 00082 deviceInfo = new DeviceInformationService(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1"); 00083 00084 /* Setup advertising. */ 00085 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00086 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); 00087 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR); 00088 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); 00089 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00090 ble.gap().setAdvertisingInterval(1000); /* 1000ms */ 00091 ble.gap().startAdvertising(); 00092 } 00093 00094 int main(void) 00095 { 00096 uint16_t dCumulativeWheelRev = 4; 00097 uint16_t dLastWheelEventTime = 1024; 00098 uint16_t dCumulativeCrankRev = 1; 00099 uint16_t dLastCrankEventTime = 1024; 00100 00101 led1 = 1; 00102 00103 Ticker ticker; 00104 ticker.attach(periodicCallback, 1); // blink LED every second 00105 00106 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); 00107 ble.init(bleInitComplete); 00108 00109 /* SpinWait for initialization to complete. This is necessary because the 00110 * BLE object is used in the main loop below. */ 00111 while (ble.hasInitialized() == false) { /* spin loop */ } 00112 00113 // infinite loop 00114 while(1) { 00115 if (triggerSensorPolling && ble.getGapState().connected) { 00116 triggerSensorPolling = false; 00117 dLastWheelEventTime -= 32; 00118 dLastCrankEventTime -= 32; 00119 if (dLastWheelEventTime < 512) { 00120 dLastWheelEventTime = 1024; 00121 dLastCrankEventTime = 1024; 00122 } 00123 cyclingSpeedAndCadenceService->updateCyclingSpeedAndCadence(flags, 00124 dCumulativeWheelRev, dLastWheelEventTime, dCumulativeCrankRev, dLastCrankEventTime); 00125 } else { 00126 ble.waitForEvent(); // low power wait for event 00127 } 00128 } 00129 }
Generated on Mon Aug 15 2022 07:16:47 by
1.7.2