This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Detect broadcaster reliably

Other Parts Discussed in Thread: CC2540, CC2541


Hi,


I have a system with around 20~40 broadcasters (2540) and one observer (2541). Each broadcaster sends unicast advertisement data every 2 sec. Observer just listens to that. The design purpose is to detect all the advertisement data from the broadcaster as fast as possible, and should not miss any one. But I found even with one broadcaster, observer can't detect broadcaster occasionally. I do not know there way to improve that.

Here is what I found in test,

- setup: observer and broadcaster is around 3 feet away and stationary. Not sure of interference, but should be low here with no other BLE device, but there is a 2G wifi router. (I did not check inside shield box)

- with 1 broadcaster in system, the detect probability is only 86%. RSSI is quite strong. I increase the scan duration on observer and there is some improvement but can't achieve 100%. I guess if I increase to long enough like 10 sec, the result will be good enough. But I want to keep it as short as possible. This means occasionally the beacon is not detected.

- with 13 broadcaster in system, there is a performance degradation, detect ratio drop from  86% to 81%.

test.pdf

Here is my setting:

On broadcaster, advertData is just 15 bytes.

   uint8 advType = GAP_ADTYPE_ADV_NONCONN_IND;   // use non-connectable advertisements

    // Set the GAP Role Parameters
    GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
    GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );

    GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof( uint8 ), &advType );
  }

  // Set advertising interval
  {
    uint16 advInt = 3200;  //2 sec

    GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, advInt );
    GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, advInt );
    GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, advInt );
    GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, advInt );
  }
 
#if defined( CC2540_MINIDK )
 
  // Register for all key events - This app will handle


On observer,


SimpleBLERObserver_init(){

...

  // Setup Observer Profile
    uint8 scanRes = 50;
    GAPObserverRole_SetParameter ( GAPOBSERVERROLE_MAX_SCAN_RES, sizeof( uint8 ), &scanRes
 
  // Setup GAP
  GAP_SetParamValue( TGAP_GEN_DISC_SCAN, 2000 );
  GAP_SetParamValue( TGAP_LIM_DISC_SCAN, 2000 );

...}


Each time after a GAP_DEVICE_DISCOVERY_EVENT event, a discovery is started again. Observer always keep detecting if there is broadcaster around and get their advertisement data.

static void simpleBLEObserverEventCB( gapObserverRoleEvent_t *pEvent )
{
  switch ( pEvent->gap.opcode )
  {
         
    case GAP_DEVICE_DISCOVERY_EVENT:
      {
        // discovery complete
        simpleBLEScanning = FALSE;

        // Copy results
        simpleBLEScanRes = pEvent->discCmpl.numDevs;
        osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList,
                     (sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) );

                GAPObserverRole_StartDiscovery( DEFAULT_DISCOVERY_MODE,
                                                                                DEFAULT_DISCOVERY_ACTIVE_SCAN,
                                                                                DEFAULT_DISCOVERY_WHITE_LIST );     

       thanks

  • Hi,
    Have you also turned off the duplicate filter when scanning. For reference:
    e2e.ti.com/.../337753

    Best wishes
  • Thanks for the prompt reply.

    The use case is different from what is mentioned in your link. What we want is to discover the broadcaster nearby fast and reliably. The background is when a new broadcaster comes around, observer can find him/her. The observer will run the scan operation repeatly (every 2 sec) and endlessly to detect any new broadcaster. In the application, observer will start a new discovery cycle as soon as previous one ends with GAP_DEVICE_DISCOVERY_EVENT event. As long as a single advData is discovered during the scan window (discovery cycle), we are ok with that. TGAP_FILTER_ADV_REPORTS is set as false but does not matter here.

    We are stuck now and what we found is the discovery (I should not put detect in the title) is not 100% reliable. Observer can find the broadcaster most of time but not all. We are wondering if there is way to improve this. So far increasing scan duration can help, but not 100% either. This seems more related to BLE stack.

    thanks
  • Hi

    If you haven't solved this,you probably missed somethings as following.

    "The scanWindow and scanInterval parameters shall be less than or equal to 10.24 s. The scanWindow shall be less than or equal to the scanInterval. If the
    scanWindow and the scanInterval parameters are set to the same value by the Host, the Link Layer should scan continuously." quoted form BT core spec v4.0 vol 6 part B 4.4.3.

    You can set up like this:

     GAP_SetParamValue( TGAP_GEN_DISC_SCAN_INT, xxxx );
     GAP_SetParamValue( TGAP_GEN_DISC_SCAN_WIND, xxxx );
     GAP_SetParamValue( TGAP_LIM_DISC_SCAN_INT, xxxx);
     GAP_SetParamValue( TGAP_LIM_DISC_SCAN_WIND, xxxx );

    Note:"xxxx" is value that you want to set up,but just let "xxxx" equal to every one.

  • Thanks a lot pointing out the detailed spec. This is the root cause. It seems CC2541 has some default value. Observer can receive advData 99% of times after the fix. In my setup, observer and broadcaster is very close and stationary. Should this ratio be 100% since the channel is so clean?


    Another question is on RF channel. Broadcaster sends advData on three channels only. During an advertisement interval, does broadcaster send on all three channels or hop to new channel during next interval? If there is hopping, the pair needs to synchronize; if there is no hopping, broadcaster should send on three channels and it is kind of waste in power.


    thanks.

  • Hi

    I also new to BLE,i do a test,even if make scanWindow qual to scanInterval, Observer still can't receive advData 100%. the user case just one broadcaster and Observer. sorry, i have no idea of the reason. mybe it is need to find appropriate params."Observer can receive advData 99% of times after the fix",what is the "fix"?how can do that?

    As for "During an advertisement interval, does broadcaster send on all three channels or hop to new channel during next interval?", in the BT core spec v4.0 vol 6 part B 4.4. there are following description.

    'Each advertising event is composed of one or more advertising PDUs sent on used advertising channel indexes. The advertising event shall be closed after one advertising PDU has been sent on each of the used advertising channel indexes (see Section 4.4.2.1) or the advertiser may close an advertising event earlier to accommodate other functionality....."you will get more information from that.

    In addition, you can specify the advertising channel you want to use.

    In gap.h

    /** @defgroup GAP_ADVCHAN_DEFINES GAP Advertisement Channel Map
     * @{
     */
    #define GAP_ADVCHAN_37  0x01  //!< Advertisement Channel 37
    #define GAP_ADVCHAN_38  0x02  //!< Advertisement Channel 38
    #define GAP_ADVCHAN_39  0x04  //!< Advertisement Channel 39
    #define GAP_ADVCHAN_ALL (GAP_ADVCHAN_37 | GAP_ADVCHAN_38 | GAP_ADVCHAN_39) //!< All Advertisement Channels Enabled
    /** @} End GAP_ADVCHAN_DEFINES */

    In role profile,such as peripheral.c. in GAPRole_Init() function.

    void GAPRole_Init( uint8 task_id )
    {
      gapRole_TaskID = task_id;

      gapRole_state = GAPROLE_INIT;
      gapRole_ConnectionHandle = INVALID_CONNHANDLE;

      GAP_RegisterForHCIMsgs( gapRole_TaskID );

      // Initialize the Profile Advertising and Connection Parameters
      gapRole_profileRole = GAP_PROFILE_PERIPHERAL;
      VOID osal_memset( gapRole_IRK, 0, KEYLEN );
      VOID osal_memset( gapRole_SRK, 0, KEYLEN );
      gapRole_signCounter = 0;
      gapRole_AdvEventType = GAP_ADTYPE_ADV_IND;
      gapRole_AdvDirectType = ADDRTYPE_PUBLIC;
      gapRole_AdvChanMap = GAP_ADVCHAN_ALL;
      gapRole_AdvFilterPolicy = GAP_FILTER_POLICY_ALL;

      // Restore Items from NV
      VOID osal_snv_read( BLE_NVID_IRK, KEYLEN, gapRole_IRK );
      VOID osal_snv_read( BLE_NVID_CSRK, KEYLEN, gapRole_SRK );
      VOID osal_snv_read( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ), &gapRole_signCounter );
    }

    hope this will help.

  • As to the "fix", I mean setting the scan window and scan interval you suggested earlier. In your application, can you get 100% of advData if channel is clean? I run 1000x2 sec scan in the test for enough samples.


    I believe the RF channel is per implementation. A spectrum analyzer can find this and I will check this later.

  • Hi
    You set up the TGAP_GEN_DISC_SCAN is 2 sec,what is the TGAP_GEN_DISC_SCAN_INT and TGAP_GEN_DISC_SCAN_WIND? lengthening the TGAP_GEN_DISC_SCAN_INT and TGAP_GEN_DISC_SCAN_WIND can reduce the wasted time of switching on scan on and off. all the same will be better. because in you code you only get the GAP_DEVICE_DISCOVERY_EVENT when time reach TGAP_GEN_DISC_SCAN.

    My test situation just one broadcaster and Observer is different from you.but the scan mechanism shou be the same.like following posts say:
    e2e.ti.com/.../338212.aspx
    e2e.ti.com/.../1000001.aspx

    Have you tried to let the multipe Broadcaster far away each other.
  • Hi,

    Thanks for the suggestion. On broadcaster side, ADV_INT is set at 2sec. On observer side, DISC_SCAN is set at 2.2 sec to make sure xtal error will not impact here. TGAP_GEN_DISC_SCAN_INT and TGAP_GEN_DISC_SCAN_WIND are set at 2.2 sec too. You are right, I need to try longer SCAN_INT and SCAN_WIND like 22 sec and maybe call HCI_EXT_HaltDuringRfCmd(), thanks for the link.

    I put the broadcaster roughly 1 feet away to each other during the test. Distance seems unrelated since each sends in a very short burst and probability of collision should be very low.

    thanks