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 and there are currently different beacon formats on the market.
This guide will help you to create your own beacon scanner to detect from which type of device is the beacon received from.
This guide it’s based on the frdmkw41z_wireless_examples_bluetooth_temperature_collector_freertos demo in MCUXpresso
The first thing we will do it’s to disable the low power to make the development easier in the app_preinclude.h
/* Enable/Disable PowerDown functionality in PwrLib */
#define cPWR_UsePowerDownMode 0
The following changes will be all performed in the temperature_collector.c file
We will disable the timer so it keeps scanning the packets received
/* Start advertising timer
TMR_StartLowPowerTimer(mAppTimerId,
gTmrLowPowerSecondTimer_c,
TmrSeconds(gScanningTime_c),
ScanningTimeoutTimerCallback, NULL);
*/
Then we will define some of the data we want to use as a reference.
static uint8_t NXPAd[3] =
{
/* Company Identifier*/
mAdvCompanyId,
/* Beacon Identifier */
0xBC
};
static uint8_t iBeaconAd[2] =
{
0x4C, 0x00
};
static uint8_t EddyStoneUIDAd2[3] =
{
/* ID */
0xAA, 0xFE,
/* Frame Type */
0x00
};
static const uint8_t EddyStoneURLAd2[3] =
{
/* ID */
0xAA, 0xFE,
/* Frame Type */
0x10
};
static const uint8_t EddyStoneTLMAd2[3] =
{
/* ID */
0xAA, 0xFE,
/* Frame Type */
0x20
};
Once we have those definitions of the beacon structure of each of the types wanted we will change the function static bool_t CheckScanEvent(gapScannedDevice_t* pData)
static bool_t CheckScanEvent(gapScannedDevice_t* pData)
{
uint8_t index = 0;
bool_t foundMatch = FALSE;
bool_t EddyfoundMatch = FALSE;
while (index < pData->dataLength)
{
gapAdStructure_t adElement;
adElement.length = pData->data[index];
adElement.adType = (gapAdType_t)pData->data[index + 1];
adElement.aData = &pData->data[index + 2];
/*DESIRED BEACON SCANNER PARSER CODE */
/* Move on to the next AD elemnt type */
index += adElement.length + sizeof(uint8_t);
}
if (foundMatch)
{
SHELL_NEWLINE();
shell_write("\r\Address : ");
shell_writeHex(pData->aAddress, 6);
}
return foundMatch;
}
As you can see, there is a comment in the function that mentions the need to add the scanner parser code, depending on the beacon you want to see will be the code to use there
NXP
if (FLib_MemCmp(NXPAD, (adElement.aData), 2))
{
shell_write("\r\nFound NXP device!");
SHELL_NEWLINE();
shell_write("\r\nData Received: ");
shell_writeHex(adElement.aData, adElement.length);
foundMatch=TRUE;
}
iBeacon
if (FLib_MemCmp(iBeaconAd, (adElement.aData), 2))
{
shell_write("\r\nFound iBeacon device!");
SHELL_NEWLINE();
shell_write("\r\nData Received: ");
shell_writeHex(adElement.aData, adElement.length);
foundMatch=TRUE;
}
Eddystone
if (FLib_MemCmp(EddyStoneUIDAd1, (adElement.aData), 2))
{
shell_write("\r\nFound EddyStone device!");
if (!EddyfoundMatch)
{
EddyfoundMatch=TRUE;
}
else{
if(TRUE==EddyfoundMatch && FLib_MemCmp(EddyStoneUIDAd2, (adElement.aData), 3))
{
SHELL_NEWLINE();
shell_write("\r\n[UID type] Data Received: ");
shell_writeHex(adElement.aData, adElement.length);
foundMatch=TRUE;
EddyfoundMatch=FALSE;
}
else if(TRUE==EddyfoundMatch && FLib_MemCmp(EddyStoneURLAd2, (adElement.aData), 3))
{
SHELL_NEWLINE();
shell_write("\r\n[URL type] Data Received: ");
hell_writeHex(adElement.aData, adElement.length);
foundMatch=TRUE;
EddyfoundMatch=FALSE;
}
else if(TRUE==EddyfoundMatch && FLib_MemCmp(EddyStoneTLMAd2, (adElement.aData), 3))
{
SHELL_NEWLINE();
shell_write("\r\n[TLM type] Data Received: ");
shell_writeHex(adElement.aData, adElement.length);
foundMatch=TRUE;
EddyfoundMatch=FALSE;
}
else
{
EddyfoundMatch=TRUE;
}
}
}
Is there any examples for KW36 as beacons? Is the stack same for KW41 and KW36?
Hello,
No, the stack it's different. The stack's available for several IDEs in the MCUXpresso Dashboard.
Regards,
Estephania
Hello,
I'm not very familiar with this example. But those Beacons where will be show?
I made the mod and I got an error, that mAdvCompanyId is not defined.
So I comment that part and I select the iBeacon scan but I coulndt see it on TeraTerm.
Regards!
Hi,
I already make it work with the iBeacon but I still have the mAdvCompanyId error.
For example, if my beacon is from st the mAdvCompanyId should be the manufacturer reserved ID?
Regards!