Combines a working system to save force, acceleration and gyro data to an SD card in a MAX32630 with BLE_Heartrate taken from the mbed site.
Dependencies: USBMSD_BD BMI160 HX711 max32630fthr USBDevice
Diff: source/main.cpp
- Revision:
- 80:caccea4da07b
- Parent:
- 73:633b44bce5fc
- Child:
- 81:b8ef2a762318
--- a/source/main.cpp Thu Sep 19 18:01:04 2019 +0100 +++ b/source/main.cpp Wed Oct 23 15:19:40 2019 +0000 @@ -17,157 +17,111 @@ #include <events/mbed_events.h> #include <mbed.h> #include "ble/BLE.h" -#include "ble/gap/Gap.h" +#include "ble/Gap.h" #include "ble/services/HeartRateService.h" -#include "pretty_printer.h" -const static char DEVICE_NAME[] = "Heartrate"; - -static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE); +DigitalOut led1(LED1, 1); -class HeartrateDemo : ble::Gap::EventHandler { -public: - HeartrateDemo(BLE &ble, events::EventQueue &event_queue) : - _ble(ble), - _event_queue(event_queue), - _led1(LED1, 1), - _connected(false), - _hr_uuid(GattService::UUID_HEART_RATE_SERVICE), - _hr_counter(100), - _hr_service(ble, _hr_counter, HeartRateService::LOCATION_FINGER), - _adv_data_builder(_adv_buffer) { } +const static char DEVICE_NAME[] = "HRM"; +static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE}; + +static uint8_t hrmCounter = 100; // init HRM to 100bps +static HeartRateService *hrServicePtr; + +static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); - void start() { - _ble.gap().setEventHandler(this); - - _ble.init(this, &HeartrateDemo::on_init_complete); - - _event_queue.call_every(500, this, &HeartrateDemo::blink); - _event_queue.call_every(1000, this, &HeartrateDemo::update_sensor_value); - - _event_queue.dispatch_forever(); - } +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) +{ + BLE::Instance().gap().startAdvertising(); // restart advertising +} -private: - /** Callback triggered when the ble initialization process has finished */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *params) { - if (params->error != BLE_ERROR_NONE) { - printf("Ble initialization failed."); - return; - } +void updateSensorValue() { + // Do blocking calls or whatever is necessary for sensor polling. + // In our case, we simply update the HRM measurement. + hrmCounter++; - print_mac_address(); - - start_advertising(); + // 100 <= HRM bps <=175 + if (hrmCounter == 175) { + hrmCounter = 100; } - void start_advertising() { - /* Create advertising parameters and payload */ + hrServicePtr->updateHeartRate(hrmCounter); +} - ble::AdvertisingParameters adv_parameters( - ble::advertising_type_t::CONNECTABLE_UNDIRECTED, - ble::adv_interval_t(ble::millisecond_t(1000)) - ); +void periodicCallback(void) +{ + led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ - _adv_data_builder.setFlags(); - _adv_data_builder.setAppearance(ble::adv_data_appearance_t::GENERIC_HEART_RATE_SENSOR); - _adv_data_builder.setLocalServiceList(mbed::make_Span(&_hr_uuid, 1)); - _adv_data_builder.setName(DEVICE_NAME); + if (BLE::Instance().getGapState().connected) { + eventQueue.call(updateSensorValue); + } +} - /* Setup advertising */ - - ble_error_t error = _ble.gap().setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - adv_parameters - ); +void onBleInitError(BLE &ble, ble_error_t error) +{ + (void)ble; + (void)error; + /* Initialization error handling should go here */ +} - if (error) { - printf("_ble.gap().setAdvertisingParameters() failed\r\n"); - return; - } - - error = _ble.gap().setAdvertisingPayload( - ble::LEGACY_ADVERTISING_HANDLE, - _adv_data_builder.getAdvertisingData() - ); +void printMacAddress() +{ + /* Print out device MAC address to the console*/ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("DEVICE MAC ADDRESS: "); + for (int i = 5; i >= 1; i--){ + printf("%02x:", address[i]); + } + printf("%02x\r\n", address[0]); +} - if (error) { - printf("_ble.gap().setAdvertisingPayload() failed\r\n"); - return; - } - - /* Start advertising */ +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) +{ + BLE& ble = params->ble; + ble_error_t error = params->error; - error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - - if (error) { - printf("_ble.gap().startAdvertising() failed\r\n"); - return; - } + if (error != BLE_ERROR_NONE) { + onBleInitError(ble, error); + return; } - void update_sensor_value() { - if (_connected) { - // Do blocking calls or whatever is necessary for sensor polling. - // In our case, we simply update the HRM measurement. - _hr_counter++; - - // 100 <= HRM bps <=175 - if (_hr_counter == 175) { - _hr_counter = 100; - } - - _hr_service.updateHeartRate(_hr_counter); - } - } - - void blink(void) { - _led1 = !_led1; + if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { + return; } -private: - /* Event handler */ + ble.gap().onDisconnection(disconnectionCallback); - void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) { - _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - _connected = false; - } - - virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) { - if (event.getStatus() == BLE_ERROR_NONE) { - _connected = true; - } - } + /* Setup primary service. */ + hrServicePtr = new HeartRateService(ble, hrmCounter, HeartRateService::LOCATION_FINGER); -private: - BLE &_ble; - events::EventQueue &_event_queue; - DigitalOut _led1; - - bool _connected; - - UUID _hr_uuid; + /* Setup advertising. */ + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().setAdvertisingInterval(1000); /* 1000ms */ + ble.gap().startAdvertising(); - uint8_t _hr_counter; - HeartRateService _hr_service; + printMacAddress(); +} - uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; - ble::AdvertisingDataBuilder _adv_data_builder; -}; - -/** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { - event_queue.call(Callback<void()>(&context->ble, &BLE::processEvents)); +void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + BLE &ble = BLE::Instance(); + eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); } int main() { - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(schedule_ble_events); + eventQueue.call_every(500, periodicCallback); - HeartrateDemo demo(ble, event_queue); - demo.start(); + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(scheduleBleEventsProcessing); + ble.init(bleInitComplete); + + eventQueue.dispatch_forever(); return 0; } -