1. Create new project, using BLUENRG template.
2. Codes and sending commands
#include "mbed.h" #include "ble/BLE.h" #include "LEDService.h" DigitalOut actuatedLED(LED1, 0); const static char DEVICE_NAME[] = "LED"; static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID}; LEDService *ledServicePtr; void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { (void)params; BLE::Instance().gap().startAdvertising(); // restart advertising } /** * This callback allows the LEDService to receive updates to the ledState Characteristic. * * @param[in] params * Information about the characterisitc being updated. */ void onDataWrittenCallback(const GattWriteCallbackParams *params) { if ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) { actuatedLED = *(params->data); } } /** * This function is called when the ble initialization process has failled */ void onBleInitError(BLE &ble, ble_error_t error) { /* Initialization error handling should go here */ } /** * Callback triggered when the ble initialization process has finished */ void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { BLE& ble = params->ble; ble_error_t error = params->error; if (error != BLE_ERROR_NONE) { /* In case of error, forward the error handling to onBleInitError */ onBleInitError(ble, error); return; } /* Ensure that it is the default instance of BLE */ if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; } ble.gap().onDisconnection(disconnectionCallback); ble.gattServer().onDataWritten(onDataWrittenCallback); bool initialValueForLEDCharacteristic = true; ledServicePtr = new LEDService(ble, initialValueForLEDCharacteristic); /* 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::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(); while (true) { ble.waitForEvent(); } } int main(void) { BLE &ble = BLE::Instance(); ble.init(bleInitComplete); }
3. Test BLE
Impletion of BLE in mbed is in two steps. First, abstract of hardware via SPI. Second, porting the STM32L476 SPI data to BLE API of mbed. There is no hardware I/O defination for SPI pins in the program, since the mbeb has done all the job with ST team and the process is transparant to users. In other words, developer can not make any modifiation or redefine the pins. For developers, only BLE API matters.
With BLE instance and init, the BLE is started and function of onDataWrittenCallback() will lead the way of flashing the LED according to the Data received. No more experience with bluetooth protocols.
BLE &ble = BLE::Instance(); ble.init(bleInitComplete);
4. Summary
I have tested and can flash the LED from any mobile application with BLE like lightblue.