Introduction:
Bluetooth Low Energy offers the ability to broadcast data in format of non-connectable advertising packets while not being in a connection. This GAP Advertisement is widely known as a beacon.
In this post we will explore some of the features of the beacon_freertos example included in the SDK package of the KW45B41Z Evaluation Kit for MCUXpresso, for updating a counter every 5 seconds and broadcasting its value with the beacon, so the user can see it using the IoT Toolbox application.
Setup:
1 – SDK installation
Download the latest version of the KW45B41Z-EVK SDK package from MCUXpresso SDK Builder
Drag and drop the SDK zip file into the Installed SDKs window:
2 – Importing the project
In the QuickStart Panel, click on Import SDK example
From wireless_examples, select beacon_freertos. It is recommended to select UART for Debug Console when using BLE projects.
Click on finish
App Customization
1 – app_preinclude.h file:
Set the following definitions to "0" in order to disable Extended Advertising and Low Power functionality.
2 – app_advertiser.h file:
Add these aux prototypes that will allow to get and set the value of some flags.
/*Functions for data exchanging with beacon application*/
bool_t GetBleAppStarted(void);
bool_t GetmAdvertisingOn(void);
void SetmAdvertisingOn(bool_t value);
3 – app_advertiser.c file:
Include fsl_component_timer_manager.h
Add the macro UPDATE_BEACON_TIMER (5) to set the update timer to 5 seconds
Create a timer ID by using TIMER_MANAGER_HANDLE_DEFINE
Declare the callback for the timer
Declare and define the "flag" BleAppStarted
Include extern variable gAppAdvertisingData
Define the aux functions that will allow to get and set the value of BleAppStarted and mAdvertisingOn flags.
Define the timer callback, which will add the value of the counter into "A" field of the Beacon packet.
#include "fsl_component_timer_manager.h"
#define UPDATE_BEACON_TIMER (5) //in seconds
/*Create timer ID*/
static TIMER_MANAGER_HANDLE_DEFINE(BeaconUpdateDataTimerID);
/*Callback prototype*/
static void UpdateBeaconTimerCallback(void * pParam);
/*Define the variables*/
static bool_t BleAppStarted = FALSE;
static bool_t mAdvertisingOn = FALSE;
/*Declare variable as external*/
extern gapAdvertisingData_t gAppAdvertisingData;
/*Define functions for data echange*/
bool_t GetBleAppStarted(void)
{
return BleAppStarted;
}
bool_t GetmAdvertisingOn(void)
{
return mAdvertisingOn;
}
void SetmAdvertisingOn(bool_t value)
{
mAdvertisingOn = value;
}
/*define the timer callback*/
static void UpdateBeaconTimerCallback(void * pParam)
{
/*Value that will be advertised*/
static int32_t count = 1;
/* Stop ADV and handle the update on the callbacks*/
Gap_StopAdvertising();
mAdvertisingOn = !mAdvertisingOn;
/* On ADV data 0-1 = company ID, 2 = Beacon ID, 3 -18 = UUID,
/* 19-20: A Data, 21-22: B Data, 23-24: C Data */
gAppAdvertisingData.aAdStructures[1].aData[19] = (uint8_t)((count >> 8) & 0xFF);
gAppAdvertisingData.aAdStructures[1].aData[20] = (uint8_t)(count & 0xFF);
count++;
}
Inside App_AdvertiserHandler function, gAdvertisingParametersSetupComplete_c event is triggered when the advertising parameters setup is complete. Here, Advertising Data is set, and we are going to use this event to start the timer.
Once the Advertising Data Setup is complete, we are going to use gAdvertisingDataSetupComplete_c event in App_AdvertiserHandler function to start advertising and update the timer. Every time the Data Setup is complete, the timer will start again.
case gAdvertisingParametersSetupComplete_c:
{
(void)Gap_SetAdvertisingData(mpAdvParams->pGapAdvData,
mpAdvParams->pScanResponseData);
if (!BleAppStarted) {
BleAppStarted = TRUE;
/*Allocate timer*/
(void) TM_Open(BeaconUpdateDataTimerID);
/* Start data update timer */
(void) TM_InstallCallback((timer_handle_t) BeaconUpdateDataTimerID,
UpdateBeaconTimerCallback, NULL);
(void) TM_Start((timer_handle_t) BeaconUpdateDataTimerID,
(uint8_t) kTimerModeSingleShot
| (uint8_t) kTimerModeLowPowerTimer,
TmSecondsToMilliseconds(UPDATE_BEACON_TIMER));
}
}
break;
case gAdvertisingDataSetupComplete_c: {
(void) Gap_StartAdvertising(App_AdvertisingCallback,
App_ConnectionCallback);
/* Start data update timer */
(void) TM_InstallCallback((timer_handle_t) BeaconUpdateDataTimerID,
UpdateBeaconTimerCallback, NULL);
(void) TM_Start((timer_handle_t) BeaconUpdateDataTimerID,
(uint8_t) kTimerModeSingleShot
| (uint8_t) kTimerModeLowPowerTimer,
TmSecondsToMilliseconds(UPDATE_BEACON_TIMER));
}
break;
4 – beacon.c file:
Wrap the mAppExtAdvParams structure inside gBeaconAE_c definition macro to avoid problems with the declaration of the extended advertising parameters
#if defined(gBeaconAE_c) && (gBeaconAE_c)
static appExtAdvertisingParams_t mAppExtAdvParams = {
&gExtAdvParams,
&gAppExtAdvertisingData,
NULL,
mBeaconExtHandleId_c,
gBleExtAdvNoDuration_c,
gBleExtAdvNoMaxEvents_c
};
#endif /*gBeaconAE_c */
BleApp_AdvertisingCallback handles BLE Advertising callback from the host stack. Every time advertising state changes, we are going to update Advertising Data when the device is not advertising and BleApp has already started. Replace the existing content of gAdvertisingStateChanged_c event.
case gAdvertisingStateChanged_c:
{
/* update ADV data when is disabled */
if((!GetmAdvertisingOn()) && GetBleAppStarted())
{
Gap_SetAdvertisingData(&gAppAdvertisingData, NULL);
SetmAdvertisingOn(true);
}
if(GetmAdvertisingOn())
{
Led1On();
}
else
{
Led1Off();
#if defined(gBeaconAE_c) && (gBeaconAE_c)
if(mAppTargetState == mAppState_ExtAdv_c)
{
if (gBleSuccess_c != BluetoothLEHost_StartExtAdvertising(&mAppExtAdvParams, BleApp_AdvertisingCallback, NULL))
{
panic(0, 0, 0, 0);
}
}
#endif
}
}
break;
Testing the application:
The IoT Toolbox is an all-in-one application that demonstrates NXP’s BLE functionalities, the implementation of BLE and custom profiles and the compatibility with different smartphones. This mobile application can be downloaded from the App Store and Google Play Store.
Please, refer to the IoT Toolbox Mobile Application User Manual for more information on features, requirements and how to install the application.
Select Beacons
Press scan
Press the USERINTERFACE Button (carrier board) to start advertising
In the IoT Toolbox app, you should be able to see the counter increasing its value every 5 seconds in the field "A"
查看全文