[KW41Z] Implementing Beacon Scanner

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[KW41Z] Implementing Beacon Scanner

[KW41Z] Implementing Beacon Scanner

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;
        }
 
    }
 
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Labels (2)
Comments

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!

No ratings
Version history
Last update:
‎09-10-2020 02:42 AM
Updated by: