Techcon 2014 BLE sample Police HRM (earbud-based) for Nordic
Dependencies: BLE_API GroveEarbudSensor mbed nRF51822 BufferedSerial
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 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 "BLEDevice.h" 00019 #include "HeartRateService.h" 00020 00021 // ********************* BEGIN Tunables for TechCon 2014 00022 00023 // !!!!IMPORTANT!!!! CHANGE DEVICE_NAME so that you can find *YOUR* Nordic board in the workshop on your phone!! 00024 const static char DEVICE_NAME[] = "Policeman #DOUG"; // what we want to appear as in mBED device server 00025 00026 #define HRM_INCREMENT 10 // increment of HRM per button press (+/-) 00027 #define HRM_DEFAULT_INIT 70 // default HRM (button only... earbud defaults to offline status) 00028 #define ENABLE_CONSOLE 1 // 0 - no serial output, 1 - serial output 00029 00030 #define HRM_MIN 10 // min heartrate 00031 #define HRM_MAX 250 // max heartrate 00032 #define HRM_DEFAULT_INIT 70 // initial heartrate (buttons only, earbud will default differently) 00033 00034 00035 // ********************* END Tunables for Techcon 2014 00036 00037 volatile uint16_t hrmCounter = HRM_DEFAULT_INIT; // initial heartrate 00038 int oldhrmCounter = HRM_MAX+1; // tracker so that we only send when things change appropriately 00039 00040 // Support for the Grove Ear-Clip Earbud 00041 #define USE_EARBUD true // true - enable (pin P0_0), false - disable (default) 00042 00043 // Globals 00044 BLEDevice ble; 00045 DigitalOut led1(LED1); 00046 volatile bool connected = false; 00047 00048 // Console allocation 00049 #if ENABLE_CONSOLE 00050 #include "BufferedSerial.h" 00051 BufferedSerial pc(USBTX, USBRX); 00052 #define LOG_CONSOLE(...) { pc.printf(__VA_ARGS__); } 00053 #else 00054 #define LOG_CONSOLE(...) 00055 #endif 00056 00057 // Earbud allocation (or button usage) 00058 #if USE_EARBUD 00059 #include "GroveEarbudSensor.h" 00060 InterruptIn sensor(P0_0); 00061 GroveEarbudSensor earbud(&sensor,&pc); 00062 #else 00063 DigitalIn up(BUTTON1); 00064 DigitalIn down(BUTTON2); 00065 #endif 00066 00067 // BLE Globals 00068 static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE}; 00069 static volatile bool triggerSensorPolling = false; 00070 00071 // Disconnection callback 00072 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) { 00073 LOG_CONSOLE("Disconnected handle %u!\r\n", handle); 00074 LOG_CONSOLE("Restarting the advertising process\r\n"); 00075 ble.startAdvertising(); 00076 connected = false; 00077 oldhrmCounter = HRM_MAX+1; 00078 #if USE_EARBUD 00079 hrmCounter = HEARTRATE_OFF; 00080 #else 00081 hrmCounter = HRM_DEFAULT_INIT; 00082 #endif 00083 } 00084 00085 // Connection callback 00086 void connectionCallback(Gap::Handle_t handle, Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr, const Gap::ConnectionParams_t *params) { 00087 LOG_CONSOLE("Endpoint is connected!\r\n"); 00088 connected = true; 00089 } 00090 00091 // Periodic callback 00092 void periodicCallback(void) { 00093 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ 00094 00095 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do 00096 * heavy-weight sensor polling from the main thread. */ 00097 triggerSensorPolling = true; 00098 } 00099 00100 #if USE_EARBUD 00101 // Heartrate callback (Earbud) 00102 void heartrateCallback(float heartrate,void *data) { 00103 hrmCounter = (int)heartrate; 00104 } 00105 #endif 00106 00107 // main entry point 00108 int main(void) { 00109 bool do_loop = true; 00110 led1 = 1; 00111 Ticker ticker; 00112 ticker.attach(periodicCallback, 1); 00113 00114 #if USE_EARBUD 00115 LOG_CONSOLE("\r\nmbed PoliceHRM (EARBUD) v1.0 (ARM Techcon 2014)\r\n"); 00116 #else 00117 LOG_CONSOLE("\r\nmbed PoliceHRM (BUTTON) v1.0 (ARM Techcon 2014)\r\n"); 00118 #endif 00119 ble.init(); 00120 ble.onDisconnection(disconnectionCallback); 00121 ble.onConnection(connectionCallback); 00122 00123 /* setup advertising */ 00124 LOG_CONSOLE("Starting BLE Advertising...\r\n"); 00125 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00126 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); 00127 ble.accumulateAdvertisingPayload(GapAdvertisingData::HEART_RATE_SENSOR_HEART_RATE_BELT); 00128 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); 00129 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00130 ble.setAdvertisingInterval(1600); /* 1000ms; in multiples of 0.625ms. */ 00131 ble.startAdvertising(); 00132 00133 #if USE_EARBUD 00134 // initialize the earbud 00135 LOG_CONSOLE("Initializing Earbud...\r\n"); 00136 hrmCounter = HEARTRATE_OFF; 00137 earbud.registerCallback(heartrateCallback); 00138 #endif 00139 00140 // Start the HRM Service 00141 LOG_CONSOLE("Starting HRM Service...\r\n"); 00142 #if !USE_EARBUD 00143 HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_WRIST); 00144 #else 00145 HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_EAR_LOBE); 00146 #endif 00147 00148 // Loop 00149 LOG_CONSOLE("Entering main loop...\r\n"); 00150 while (do_loop) { 00151 if (triggerSensorPolling) { 00152 triggerSensorPolling = false; 00153 00154 #if !USE_EARBUD 00155 // see if either button was pressed and adjust the heartrate accordingly 00156 //LOG_CONSOLE("Updating HRM via button...\r\n"); 00157 if (up) hrmCounter += HRM_INCREMENT; 00158 if (down) hrmCounter -= HRM_INCREMENT; 00159 00160 // boundary checking 00161 if (hrmCounter < 0) hrmCounter = 0; 00162 else if (hrmCounter < HRM_MIN) hrmCounter = HRM_MIN; 00163 else if (hrmCounter > HRM_MAX) hrmCounter = HRM_MAX; 00164 #endif 00165 00166 // update the heartrate service if it has changed 00167 if (hrmCounter != oldhrmCounter) { 00168 LOG_CONSOLE("Updating HRM values...%d bpm\r\n",hrmCounter); 00169 hrService.updateHeartRate(hrmCounter); 00170 if (connected == true) oldhrmCounter = hrmCounter; 00171 } 00172 } else { 00173 ble.waitForEvent(); 00174 } 00175 } 00176 00177 // we have exited 00178 LOG_CONSOLE("Application exiting...\r\n"); 00179 }
Generated on Sun Jul 17 2022 00:06:39 by 1.7.2