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.
Fork of nRF5-DK-HeartRateDemo by
source/main.cpp
- Committer:
- bsiever
- Date:
- 2016-11-11
- Revision:
- 2:b850666f3c8f
- Parent:
- 0:3a7b472313d7
- Child:
- 3:f593ad98fe21
File content as of revision 2:b850666f3c8f:
#include <events/mbed_events.h> #include <mbed.h> #include "ble/BLE.h" #include "ble/Gap.h" // Uses the provided Service Classes: // (Local copies with comments are used rather than "ble/services/NAME" versions #include "DeviceInformationService.h" #include "HeartRateService.h" // If debug is "true", include code to print debugging messages to the "console" #define DEBUG 1 #if DEBUG #define LOG_PRINTF(...) eventQueue.call(printf, __VA_ARGS__); #else #define LOG_PRINTF(...) ; #endif /*********************************************************************** I. Global Variables: This section declares "global variable" (variables that are used in multiple functions in this file) ************************************************************************/ // A. A way to keep track of the heart rate service object // Declare a pointer to a heart rate service object. (This variable isn't // an actual object. It's used like Java Reference Variables --- it can refer // to a heart rate service object, but doesn't until it is initialized) // Pointers are used because the heart rate service constructor requires a BLE // object in its constructors, which isn't available when the program first starts // The Object won't exist until created with "new" ( HeartRateService *pHrs; // B. A way to create new "events" /* Total size of space for eventQueue = event count * event size */ EventQueue eventQueue( 16 * 32); // C. Setup the interrupt pins for any buttons InterruptIn buttons[4] = { InterruptIn(P0_13), InterruptIn(P0_14), InterruptIn(P0_15), InterruptIn(P0_16) }; // D. Variable to contain the heart rate value uint8_t heartRate = 0; /*********************************************************************** II. Event "Call backs": This section contains functions that are called to respond to events. (Each of these is "set" as a callback somewhere in the following code too) ************************************************************************/ // A. Callback for things to do when a device disconnects void bleDisconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { LOG_PRINTF(__func__); // Print the function's name // Start advertising for a new connection BLE::Instance().gap().startAdvertising(); } // B. Callback for things to do when the BLE object is ready void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { LOG_PRINTF(__func__); // Print the function's name // Get the BLE object BLE& ble = BLE::Instance(); // Create the HeartRateService Object with initial value of 0 and "OTHER" location // (The object's constructor automatically adds the service) pHrs = new HeartRateService(ble, heartRate, HeartRateService::LOCATION_OTHER); // Add in a Device Information Service object too. // Argument order: "Manufacturer", "Model No", "Serial No", "Hardware Rev", "Firmware Rev", "Software Rev" new DeviceInformationService(ble, "Acme", "1A", "123", "v1.1", "r2a", "r3"); // Setup the "onDisconnection()" callback // Connection info is handeled by GAP (Generic ACCESS Protocol), hence the ble.gap() part ble.gap().onDisconnection(bleDisconnectionCallback); // Setup advertising: Build the "payload" // Add in the mode (discoverable / low energy only) ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // Include a list of services in the advertising packet uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE}; ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *) uuid16_list, sizeof(uuid16_list)); // Include the device name in the advertising packet char DEVICE_NAME[] = "HRM"; ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME)); // Add the fact that it's "connectable" to the advertising packet (and that its not directed to a specific device) ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // Wait 1S between advertising packets. Shorter will lead to faster connections but more power consumption // Longer will usually lead to slower times-to-connect, but lower power consumption ble.gap().setAdvertisingInterval(1000); /* 1000ms */ // Also set the device name in the GAP level ble.setDeviceName((uint8_t*)DEVICE_NAME); // Set the "GAP Name" too. // Start advertising ble.gap().startAdvertising(); } void buttonsPress() { LOG_PRINTF(__func__); // Print the function's name // Display the buttons that are pressed // Do NOT use printf() in callbacks. Put all printing on tasks handled by the event queue. // (This uses the debug macro provided to call printf() with arguments) for(int i=0;i<sizeof(buttons)/sizeof(InterruptIn);i++) { if(buttons[i].read()==0) LOG_PRINTF("\t%d down\r\n",i+1); } if(buttons[0].read()==0) { heartRate++; pHrs->updateHeartRate(heartRate); } else if(buttons[1].read()==0) { heartRate--; pHrs->updateHeartRate(heartRate); } } // C. Callback to respond to BLE events. This will add a function call to the // Event Queue to process the event. void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { BLE &ble = BLE::Instance(); eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); } /*********************************************************************** III. main() thread This section will run initially and configure/start everything else. ************************************************************************/ int main() { LOG_PRINTF(__func__); // Print the function's name // Configure the buttons. for(int i=0;i<sizeof(buttons)/sizeof(InterruptIn); i++) { // Pull the button voltages "up" to 3v by default buttons[i].mode(PullUp); // Callback for when the button falls to a 0 (when the button is pressed) buttons[i].fall(&buttonsPress); } // Get access to the BLE object BLE &ble = BLE::Instance(); // Set the BLE object to use the event queue to process any BLE events // (So when a BLE event occurs, a function to respond to it will be placed in the event queue) ble.onEventsToProcess(scheduleBleEventsProcessing); // Initialize the BLE object ble.init(bleInitComplete); // Let the "event queue" take over eventQueue.dispatch_forever(); return 0; }