[KW41Z] Implementing Beacon Scanner

Document created by Estephania Martinez Employee on Sep 19, 2018Last modified by Estephania Martinez Employee on Oct 2, 2018
Version 2Show Document
  • View in full screen mode

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 NXP[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(adData1, (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;
        }

    }

}
2 people found this helpful

Attachments

    Outcomes