he LED example demonstrates the use of a read-write characteristic to control a LED through a phone app. The canonical source for this example lives at https://github.com/ARMmbed/mbed-os-example-ble/tree/master/BLE_LED

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