This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Advertising init as nonconnectable but still shows as connectable?

I can not seem to figure out why when I init the advertising and then issue a start to the advertising the advertising beacon shows up as a connectable when viewing under nRFConnect app.

I have put the defines, and the two functions that I am using for advertising init and start.  I have included main as well.  All the other functions that have been omitted are the same as the ble_beacon_app example from SDK v17.1

#define APP_BLE_CONN_CFG_TAG            1                                  /**< A tag identifying the SoftDevice BLE configuration. */

#define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(5000, UNIT_0_625_MS)  /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */

#define APP_BEACON_INFO_LENGTH          0x18                               /**< Total length of information advertised by the Beacon. */
#define APP_ADV_DATA_LENGTH             0x16                               /**< Length of manufacturer specific data in the advertisement. */
#define APP_DEVICE_TYPE                 0x02                               /**< 0x02 refers to Beacon. */
#define APP_MEASURED_RSSI               0xC3                               /**< The Beacon's measured RSSI at 1 meter distance in dBm. */
#define APP_BATT_PCNT_LVL               80                                 /**< The percentage amount of battery left. */
#define APP_COMPANY_IDENTIFIER          0x0059                             /**< Company identifier for Nordic Semiconductor ASA. as per www.bluetooth.org. */
#define APP_PRD_ID_OFS                  0x00                               /**< Product ID Offset. */
#define APP_PCB_REV                     0x00                               /**< PCB Revision Level. */
#define APP_FW_MAJ_VERS                 0x00                               /**< Firmware Major Version. */
#define APP_FW_MIN_VERS                 0x80                               /**< Firmware Minor Version. */
#define APP_BEACON_UUID                 0x01, 0x12, 0x23, 0x34, \
                                        0x45, 0x56, 0x67, 0x78, \
                                        0x89, 0x9a, 0xab, 0xbc, \
                                        0xcd, 0xde, 0xef, 0xf0            /**< Proprietary UUID for Beacon. */

//-----------------------------------------------------------------------------
// data structure intialization
  BLE_ADVERTISING_DEF(f_advertising);        //< Advertising module instance. 

  typedef struct{

    ble_advdata_manuf_data_t  f_manuf_specific_data;
    ble_advertising_init_t    f_init; 

  }f_ble_adv_data_t;

  static f_ble_adv_data_t         f_ble_data;
  
  static ble_advdata_manuf_data_t  f_manuf_data;   // This is where the advertising beacon data will be updated.
  
//-----------------------------------------------------------------------------
static uint8_t m_beacon_info[APP_BEACON_INFO_LENGTH] =  /**< Information advertised by the Beacon. */
{
 APP_DEVICE_TYPE,     // Manufacturer specific information. Specifies the device type in this
                      // implementation.
 APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the
                      // manufacturer specific data in this implementation.
 APP_BEACON_UUID,     // 128 bit UUID value.
 APP_PRD_ID_OFS,      // Manufacturer specific information.  Product ID offset value.
 APP_PCB_REV,         // Manufacturer specific information.  PCB Revision Level.
 APP_FW_MAJ_VERS,     // Manufacturer specific information.  Firmware Major Version
 APP_FW_MIN_VERS,     // Manufacturer specific information.  Firmware Minor Version
 APP_MEASURED_RSSI,   // Manufacturer specific information.  The Beacon's measured TX power in this implementation.
 APP_BATT_PCNT_LVL    // Manufacturer specific information.  The Beacon's measured Battery power in percent
};

//-----------------------------------------------------------------------------
static uint8_array_t ary_beacon_info = 
{
 .size   = 0x0001,          // Number of array entries
 .p_data = m_beacon_info    // pointer to the data
};

//-----------------------------------------------------------------------------
static void advertising_init(void)
{
 uint32_t      err_code;

 NRF_LOG_INFO("advertising_init");

 memset(&f_manuf_data, 0, sizeof(f_manuf_data));

 f_manuf_data.company_identifier      = APP_COMPANY_IDENTIFIER;
 f_manuf_data.data                    = ary_beacon_info;

 memset(&f_ble_data, 0, sizeof(f_ble_data));

 f_ble_data.f_init.advdata.name_type             = BLE_ADVDATA_NO_NAME;
 f_ble_data.f_init.advdata.include_appearance    = false;
 f_ble_data.f_init.advdata.flags                 = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
 f_ble_data.f_init.advdata.p_manuf_specific_data = &f_manuf_data;

 f_ble_data.f_init.evt_handler                   = on_adv_evt;

 f_ble_data.f_init.config.ble_adv_fast_enabled   = true;
 f_ble_data.f_init.config.ble_adv_fast_interval  = NON_CONNECTABLE_ADV_INTERVAL;
 f_ble_data.f_init.config.ble_adv_fast_timeout   = 0;  // Never timeout

 err_code = ble_advertising_init(&f_advertising, &f_ble_data.f_init);
 APP_ERROR_CHECK(err_code);

 ble_advertising_conn_cfg_tag_set(&f_advertising, APP_BLE_CONN_CFG_TAG);
}

//-----------------------------------------------------------------------------
static void advertising_start(void)
{
 ret_code_t err_code;

 NRF_LOG_INFO("advertising_start");

 err_code = ble_advertising_start(&f_advertising, BLE_ADV_MODE_FAST);
 APP_ERROR_CHECK(err_code);
}

//-----------------------------------------------------------------------------
int main(void)
{
 // Initialize.
 log_init();
 timers_init();
 leds_init();
 power_management_init();
 ble_stack_init();
 advertising_init();

 // Start execution.
 NRF_LOG_INFO("Beacon example started.");
 advertising_start();

 // Enter main loop.
 for (;;)
   {
    idle_state_handle();
   }
}

I am running in Release mode and have tried Debug mode and get the same results.  The nRF_Log output is as below:

<info> app_timer: RTC: initialized.

<info> app: advertising_init

<info> app: Beacon example started.

<info> app: advertising_start

<info> app: Fast advertising.

On the nRF Connect app I am seeing under Raw:

0x02010404FF590002

I am seeing a five second advertisement so I know that parameter is being respected in the init sequence.

Any help or suggestions would be greatly appreciated.

Parents
  • UPDATE:  I started investigating what could have caused a difference between the advertising_init and the subsequent update routine.  The only thing I could come up with had to do with initializing both encode buffers in the advertising_init routine.  That did take care of the ERROR 12 issue.  However, when you go look at the nRF Connect app to see the beacon data, something somewhere is becoming corrupted and not pointing to the correct data.  Below is the code snippet for the advertising_init:

     uint32_t      err_code;
    
     NRF_LOG_INFO("advertising_init");
    
    // ble_advdata_t advdata;  // moved to a global position
    
     // flags must be this for beacon to work properly
     uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
    
     // Changing to this flag causes an ERROR 7 to occur if m_adv_params.duration = 0
     //   Even if you change the duration to 5 you still see nothing on nRF Connect App
     //uint8_t       flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    
     ble_advdata_manuf_data_t manuf_specific_data;
    
     manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
    
     manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info;
     manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;
    
     // Build and set advertising data.
     memset(&advdata, 0, sizeof(advdata));
    
     advdata.name_type             = BLE_ADVDATA_NO_NAME;
    // advdata.name_type             = BLE_ADVDATA_FULL_NAME;
     advdata.flags                 = flags;
     advdata.p_manuf_specific_data = &manuf_specific_data;
    
     // Initialize advertising parameters (used when starting advertising).
     memset(&m_adv_params, 0, sizeof(m_adv_params));
    
     m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
     m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
     m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
     m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
     m_adv_params.duration        = 0;  // Never time out.  Must be zero for beacon to work properly
    
     m_adv_data.adv_data.p_data = &m_enc_advdata[1][0];
    
     NRF_LOG_INFO("adv_init enc buf 1");
    
     err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len); 
     APP_ERROR_CHECK(err_code);
    
     NRF_LOG_HEXDUMP_INFO(m_adv_data.adv_data.p_data, m_adv_data.adv_data.len);
    
     NRF_LOG_INFO("adv_init enc buf 0");
    
     m_adv_data.adv_data.p_data = &m_enc_advdata[0][0];
    
     err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
     APP_ERROR_CHECK(err_code);
    
     NRF_LOG_HEXDUMP_INFO(m_adv_data.adv_data.p_data, m_adv_data.adv_data.len);
    
     err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
     APP_ERROR_CHECK(err_code);

    Below is the updated code for the update routine:

       uint32_t err_code;
       uint8_t loc_index = BATT_VAL_OFFSET_IN_BEACON_INFO;
    
       NRF_LOG_INFO("Adv data update started.");
    
       /* This is an [in][out] variable used by the encode function */
       m_adv_data.adv_data.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
    
       m_beacon_info[loc_index] = app_Batt_PCnt; // Batt percent value
    
       /* Swap adv data buffer - from API doc: "In order to update advertising
          data while advertising,new advertising buffers must be provided" */
    
       if (f_enc_idx & 1)
         {
          m_adv_data.adv_data.p_data = &m_enc_advdata[0][0];
         }
       else
         {
          m_adv_data.adv_data.p_data = &m_enc_advdata[1][0];
         }
    
       ++f_enc_idx;
    
       /* Go encode the updated beacon data for the buffer that was selected */
       err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
       APP_ERROR_CHECK(err_code);
    
    //   NRF_LOG_HEXDUMP_INFO(m_adv_data.adv_data.p_data, m_adv_data.adv_data.len);
    
       err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, NULL);
       APP_ERROR_CHECK(err_code);
    
       NRF_LOG_INFO("Advertising payload updated.");
    

    This is what I see when I capture on the debug terminal:

    <info> app_timer: RTC: initialized.
    
    <info> app: advertising_init
    
    <info> app: adv_init enc buf 1
    
    <info> app:  02 01 04 1A FF 59 00 02|.....Y..
    
    <info> app:  15 01 12 23 34 45 56 67|...#4EVg
    
    <info> app:  78 89 9A AB BC CD DE EF|x.......
    
    <info> app:  F0 00 00 80 C3 50      |.....P  
    
    <info> app: adv_init enc buf 0
    
    <info> app:  02 01 04 1A FF 59 00 02|.....Y..
    
    <info> app:  15 01 12 23 34 45 56 67|...#4EVg
    
    <info> app:  78 89 9A AB BC CD DE EF|x.......
    
    <info> app:  F0 00 00 80 C3 50      |.....P  
    
    <info> app: Beacon example started.
    
    <info> app: advertising_start
    
    04:04:12.910: <info> app: Adv data update started.
    
    <info> app: Advertising payload updated.
    
    04:04:17.976: <info> app: Adv data update started.
    
    <info> app: Advertising payload updated.
    
    04:04:22.901: <info> app: Adv data update started.
    
    <info> app: Advertising payload updated.
    
    04:04:27.961: <info> app: Adv data update started.
    
    <info> app: Advertising payload updated.
    
    04:04:32.990: <info> app: Adv data update started.
    
    <info> app: Advertising payload updated.
    
    

    On the nRF Connect app the raw data I see is:

    0x02010403FF0000

    If I back out the update routine, everything seems to work fine with no updates.  Any ideas?

  • I don't see why initializing the m_enc_advdata buffers would make any difference. Anyway, I see now that I had not placed the manuf_specific_data variable in static memory. So the p_manuf_specific_data ends up pointing to a stack variable.

    Please try to define this variable as 'static' and see if fixes the problem:

     static ble_advdata_manuf_data_t manuf_specific_data;

    Would it not be better to take care of all the housekeeping in one event rather than multiple events firing asynchronously?

    In theory yes, but I doubt it will make a noticeable difference in practice. The time it takes to wake up to service an interrupt is only a few micro seconds. What's more important is how often you decide to read the voltage. It does not make sense to sample a battery voltage every 5 seconds if the battery is expected to last for several months.

    As for the 32KHz source, where do I go check to see if the external crystal is enabled or does it just default to the internal 32KHz source by default?

    You can see which clock source the Softdevice the will be configured with from the NRF_SDH_CLOCK_LF_SRC symbol in sdk_config.h. Our SDK BLE examples have the LF crystal selected by default.

Reply
  • I don't see why initializing the m_enc_advdata buffers would make any difference. Anyway, I see now that I had not placed the manuf_specific_data variable in static memory. So the p_manuf_specific_data ends up pointing to a stack variable.

    Please try to define this variable as 'static' and see if fixes the problem:

     static ble_advdata_manuf_data_t manuf_specific_data;

    Would it not be better to take care of all the housekeeping in one event rather than multiple events firing asynchronously?

    In theory yes, but I doubt it will make a noticeable difference in practice. The time it takes to wake up to service an interrupt is only a few micro seconds. What's more important is how often you decide to read the voltage. It does not make sense to sample a battery voltage every 5 seconds if the battery is expected to last for several months.

    As for the 32KHz source, where do I go check to see if the external crystal is enabled or does it just default to the internal 32KHz source by default?

    You can see which clock source the Softdevice the will be configured with from the NRF_SDH_CLOCK_LF_SRC symbol in sdk_config.h. Our SDK BLE examples have the LF crystal selected by default.

Children
  • Adding static as you suggested fixed the beacon data issue.  I found the NRF_SDH_CLOCK_LF_SRC symbol and changed it as you suggested and verified operation still worked after disabling the 32KHz crystal.  So now, I am back on track again.  So I have a few more questions if you do not mind.

    1. Is the internal DCDC regulator enabled by default?

    2. When I ran the online power profiler and plugged in the variables for my application, I liked the result that it came back with.  Does the profiler take into consideration not really going into sleep (System On) but rather Idle as in the case of the beacon app example?  Does the profiler take into consideration the other passives on the board that allow the micro to function?

    3. Can you point me where I need to go to adjust the TX Power output of the beacon?

  • Good to hear that it works now. Note that the 32 KHz crystal will give you a slightly lower average current if you have the option to choose.

    AllenS said:
    1. Is the internal DCDC regulator enabled by default?

    We use the LDO by default, but you can call sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE ) after ble_stack_init() to enable it.  However, before you enabling it, please make sure you have the DCDC inductors included in your design:

    Otherwise, you may risk bricking the device.

    2. Idle and system ON is the same in this context. I.e. the device enters System ON when you call the idle function from your main loop.

    AllenS said:
    Does the profiler take into consideration the other passives on the board that allow the micro to function?

    Yes, the power profiler data is based on actual measurements.

    3. sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV , 0, <tx power>).

  • Thank you for the information.  All of it is working very well right now.

Related