BLE_Button is a BLE service template. It handles a read-only characteristic with a simple input (boolean values). The input's source is the button on the board itself - the characteristic's value changes when the button is pressed or released. The canonical source for this example lives at https://github.com/ARMmbed/mbed-os-example-ble/tree/master/BLE_Button

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 #include <events/mbed_events.h>
00017 
00018 #include <mbed.h>
00019 #include "ble/BLE.h"
00020 #include "ble/Gap.h"
00021 #include "ButtonService.h"
00022 #include "pretty_printer.h"
00023 
00024 const static char DEVICE_NAME[] = "Button";
00025 
00026 static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE);
00027 
00028 
00029 class BatteryDemo : ble::Gap::EventHandler {
00030 public:
00031     BatteryDemo(BLE &ble, events::EventQueue &event_queue) :
00032         _ble(ble),
00033         _event_queue(event_queue),
00034         _led1(LED1, 1),
00035         _button(BLE_BUTTON_PIN_NAME, BLE_BUTTON_PIN_PULL),
00036         _button_service(NULL),
00037         _button_uuid(ButtonService::BUTTON_SERVICE_UUID),
00038         _adv_data_builder(_adv_buffer) { }
00039 
00040     void start() {
00041         _ble.gap().setEventHandler(this);
00042 
00043         _ble.init(this, &BatteryDemo::on_init_complete);
00044 
00045         _event_queue.call_every(500, this, &BatteryDemo::blink);
00046 
00047         _event_queue.dispatch_forever();
00048     }
00049 
00050 private:
00051     /** Callback triggered when the ble initialization process has finished */
00052     void on_init_complete(BLE::InitializationCompleteCallbackContext *params) {
00053         if (params->error != BLE_ERROR_NONE) {
00054             printf("Ble initialization failed.");
00055             return;
00056         }
00057 
00058         print_mac_address();
00059 
00060         /* Setup primary service. */
00061 
00062         _button_service = new ButtonService(_ble, false /* initial value for button pressed */);
00063 
00064         _button.fall(Callback<void()>(this, &BatteryDemo::button_pressed));
00065         _button.rise(Callback<void()>(this, &BatteryDemo::button_released));
00066 
00067         start_advertising();
00068     }
00069 
00070     void start_advertising() {
00071         /* Create advertising parameters and payload */
00072 
00073         ble::AdvertisingParameters adv_parameters(
00074             ble::advertising_type_t::CONNECTABLE_UNDIRECTED,
00075             ble::adv_interval_t(ble::millisecond_t(1000))
00076         );
00077 
00078         _adv_data_builder.setFlags();
00079         _adv_data_builder.setLocalServiceList(mbed::make_Span(&_button_uuid, 1));
00080         _adv_data_builder.setName(DEVICE_NAME);
00081 
00082         /* Setup advertising */
00083 
00084         ble_error_t error = _ble.gap().setAdvertisingParameters(
00085             ble::LEGACY_ADVERTISING_HANDLE,
00086             adv_parameters
00087         );
00088 
00089         if (error) {
00090             print_error(error, "_ble.gap().setAdvertisingParameters() failed");
00091             return;
00092         }
00093 
00094         error = _ble.gap().setAdvertisingPayload(
00095             ble::LEGACY_ADVERTISING_HANDLE,
00096             _adv_data_builder.getAdvertisingData()
00097         );
00098 
00099         if (error) {
00100             print_error(error, "_ble.gap().setAdvertisingPayload() failed");
00101             return;
00102         }
00103 
00104         /* Start advertising */
00105 
00106         error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
00107 
00108         if (error) {
00109             print_error(error, "_ble.gap().startAdvertising() failed");
00110             return;
00111         }
00112     }
00113 
00114     void button_pressed(void) {
00115         _event_queue.call(Callback<void(bool)>(_button_service, &ButtonService::updateButtonState), true);
00116     }
00117 
00118     void button_released(void) {
00119         _event_queue.call(Callback<void(bool)>(_button_service, &ButtonService::updateButtonState), false);
00120     }
00121 
00122     void blink(void) {
00123         _led1 = !_led1;
00124     }
00125 
00126 private:
00127     /* Event handler */
00128 
00129     virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) {
00130         _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
00131     }
00132 
00133 private:
00134     BLE &_ble;
00135     events::EventQueue &_event_queue;
00136 
00137     DigitalOut  _led1;
00138     InterruptIn _button;
00139     ButtonService *_button_service;
00140 
00141     UUID _button_uuid;
00142 
00143     uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE];
00144     ble::AdvertisingDataBuilder _adv_data_builder;
00145 };
00146 
00147 /** Schedule processing of events from the BLE middleware in the event queue. */
00148 void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) {
00149     event_queue.call(Callback<void()>(&context->ble, &BLE::processEvents));
00150 }
00151 
00152 int main()
00153 {
00154     BLE &ble = BLE::Instance();
00155     ble.onEventsToProcess(schedule_ble_events);
00156 
00157     BatteryDemo demo(ble, event_queue);
00158     demo.start();
00159 
00160     return 0;
00161 }
00162