Yoshio Miyakawa / Mbed 2 deprecated BLE_CyclingPower

Dependencies:   BLE_API mbed nRF51822

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 "CyclingPowerService.h"
00021 #include "ble/services/DeviceInformationService.h"
00022 
00023 DigitalOut led1(LED1);
00024 
00025 const static char     DEVICE_NAME[] = "CyclingPower";
00026 static const uint16_t uuid16_list[] = {UUID_CYCLING_POWER_SERVICE,
00027                                        GattService::UUID_DEVICE_INFORMATION_SERVICE};
00028 
00029 static volatile bool triggerSensorPolling = false;
00030 
00031 CyclingPowerService *cyclingPowerService;
00032 DeviceInformationService *deviceInfo;
00033 
00034 uint32_t feature = CyclingPowerService::FEATURE_PEDAL_POWER_BALANCE
00035                  + CyclingPowerService::FEATURE_WHEEL_REVOLUTION_DATA
00036                  + CyclingPowerService::FEATURE_CRANK_REVOLUTION_DATA
00037                  + CyclingPowerService::FEATURE_EXTREME_MAGNITUDES;
00038 
00039 uint16_t flags = CyclingPowerService::FLAG_PEDAL_POWER_BALANCE_PRESENT
00040                + CyclingPowerService::FLAG_PEDAL_POWER_BALANCE_REFERENCE_LEFT
00041                + CyclingPowerService::FLAG_WHEEL_REVOLUTION_DATA_PRESENT
00042                + CyclingPowerService::FLAG_CRANK_REVOLUTION_DATA_PRESENT
00043                + CyclingPowerService::FLAG_EXTREME_TORQUE_MAGNITUDES_PRESENT;
00044 
00045 uint8_t location = CyclingPowerService::LOCATION_CHAINSTAY;
00046 
00047 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
00048 {
00049 }
00050 
00051 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
00052 {
00053     triggerSensorPolling = false;
00054     BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); // restart advertising
00055 }
00056 
00057 void confirmationRcvCallBack(Gap::Handle_t handle)
00058 {
00059 }
00060 
00061 void periodicCallback(void)
00062 {
00063     led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
00064 
00065     /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
00066      * heavy-weight sensor polling from the main thread. */
00067     triggerSensorPolling = true;
00068 }
00069 
00070 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
00071 {
00072     BLE &ble          = params->ble;
00073     ble_error_t error = params->error;
00074 
00075     if (error != BLE_ERROR_NONE) {
00076         return;
00077     }
00078 
00079     ble.gap().onConnection(connectionCallback);
00080     ble.gap().onDisconnection(disconnectionCallback);
00081     ble.onConfirmationReceived(confirmationRcvCallBack);
00082 
00083     /* Setup primary service. */
00084     cyclingPowerService = new CyclingPowerService(ble, feature, location);
00085 
00086     /* Setup auxiliary service. */
00087     deviceInfo = new DeviceInformationService(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
00088 
00089     /* Setup advertising. */
00090     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00091     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
00092     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
00093     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
00094     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00095     ble.gap().setAdvertisingInterval(1000); /* 1000ms */
00096     ble.gap().startAdvertising();
00097 }
00098 
00099 int main(void)
00100 {
00101     int16_t power = 200;
00102     uint8_t balance = 50 * 2;
00103     int16_t maxTorque = 100;
00104     int16_t minTorque =  20;
00105 
00106     uint16_t dCumulativeWheelRev =    4;
00107     uint16_t dLastWheelEventTime = 2048;
00108     uint16_t dCumulativeCrankRev =    1;
00109     uint16_t dLastCrankEventTime = 1024;
00110 
00111     led1 = 1;
00112 
00113     Ticker ticker;
00114     ticker.attach(periodicCallback, 1); // blink LED every second
00115 
00116     BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
00117     ble.init(bleInitComplete);
00118 
00119     /* SpinWait for initialization to complete. This is necessary because the
00120      * BLE object is used in the main loop below. */
00121     while (ble.hasInitialized() == false) { /* spin loop */ }
00122 
00123     // infinite loop
00124     while(1) {
00125         if (triggerSensorPolling && ble.getGapState().connected) {
00126             triggerSensorPolling = false;
00127             power += 10;
00128             dLastWheelEventTime -= 64;
00129             dLastCrankEventTime -= 32;
00130             if (power > 300) {
00131                 power = 200;
00132                 dLastWheelEventTime = 2048;
00133                 dLastCrankEventTime = 1024;
00134             }
00135             cyclingPowerService->updateCyclingPower(flags, power, balance, maxTorque, minTorque, 
00136                 dCumulativeWheelRev, dLastWheelEventTime, dCumulativeCrankRev, dLastCrankEventTime);
00137         } else {
00138             ble.waitForEvent(); // low power wait for event
00139         }
00140     }
00141 }