This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

change Beacon advertising parameters while button pressed?

Hi,

I m using NRF52840 as a Beacon. i m using SDK15.2 ble_app_beacon.Advertising is works fine. Now i want to change advertising parameter while button pressed.

#include "app_timer.h"
#include "ble_advdata.h"
#include "bsp.h"
#include "nordic_common.h"
#include "nrf_pwr_mgmt.h"
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "nrf_soc.h"
#include <stdbool.h>
#include <stdint.h>

#include "ble_srv_common.h"
#include "boards.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
 
#define APP_BLE_CONN_CFG_TAG 1                                              // Tag identifying the BLE configuration.    
#define NON_CONNECTABLE_ADV_INTERVAL MSEC_TO_UNITS(500, UNIT_0_625_MS)      // iBeacon specifies an advertising interval of 100ms
#define APP_BEACON_INFO_LENGTH 0x17                                         // Total length of information advertised by the Beacon. */
#define APP_ADV_DATA_LENGTH 0x15                                            // Length of manufacturer specific data in the advertisement. */
#define APP_DEVICE_TYPE 0x02                                                // 0x02 refers to Beacon. 
#define APP_COMPANY_IDENTIFIER 0x004C                                       // Company identifier for Nordic Semiconductor 

#define DEAD_BEEF 0xDEADBEEF                                                // Value used as error code on stack dump
uint32_t mac_addr[];                                                        
uint8_t service_uid[17];
uint8_t *service_uid_pointer;
uint8_t m_beacon_info1[APP_BEACON_INFO_LENGTH]={0};
uint8_t serial_number[4];
uint32_t test_sno;

static ble_gap_adv_params_t m_adv_params;                                      // Parameters to be passed to the stack when starting advertising. 
static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;                  // Advertising handle used to identify an advertising set. 
static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];                   // Buffer for storing an encoded advertising set. 


      /*Encoded advertising data. */
static ble_gap_adv_data_t m_adv_data =
    {
        .adv_data =
            {
                .p_data = m_enc_advdata,
                .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX},
        .scan_rsp_data =
            {
                .p_data = NULL,
                .len = 0

            }

};

void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) {
  app_error_handler(DEAD_BEEF, line_num, p_file_name);
}
/** Initializing the Advertising.**/
static void advertising_init(void) {
  uint32_t err_code;
  ble_advdata_t advdata;
  uint32_t pin_value;
  uint8_t flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
/* Beacon Configuration*/
  ble_advdata_manuf_data_t manuf_specific_data;

  manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
  m_beacon_info1[0]=APP_DEVICE_TYPE;                       
  m_beacon_info1[1]=APP_ADV_DATA_LENGTH;

  /* service id*/
  for(int i=5;i>1;i--)
  {
    m_beacon_info1[i]=*service_uid_pointer++;
  }

  pin_value = nrf_gpio_pin_read(11);
   if(pin_value==0)
   {
     m_beacon_info1[6]=0x00;      
      nrf_gpio_pin_toggle(14);
                                 // Aided
   }
   else
   {
     m_beacon_info1[6]=0xff;
    // nrf_gpio_pin_clear(14);
   }

 // m_beacon_info1[6]=0x00;                                  // Aided
  m_beacon_info1[7]=0xff;                                  //Reserved id
  m_beacon_info1[8]=0xff;                                  // reserved id
  //m_beacon_info1[18]=0x20;                                 //Major 1st byte
  m_beacon_info1[18]=0x54; 
  m_beacon_info1[19]=0x57;  //Major 2nd byte
  m_beacon_info1[20]=0x4F;                                 //Minor 1st byte
  m_beacon_info1[21]=0x54; 
  //m_beacon_info1[21]=0x55;//Minor  2nd byte
  m_beacon_info1[22]=0xC3;                                 //Rssi @1m

 manuf_specific_data.data.p_data = (uint8_t *)m_beacon_info1;
 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.flags = flags;
  advdata.p_manuf_specific_data = &manuf_specific_data;

  // Initialize advertising parameters.
  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;                                               //Filter policy
  m_adv_params.interval = NON_CONNECTABLE_ADV_INTERVAL;
 // m_adv_params.channel_mask[4];
 // m_adv_params.channel_mask[4] = 0xA0;

  m_adv_params.duration = 0;                                                                     // Never time out.

  err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
  APP_ERROR_CHECK(err_code);

  err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
  APP_ERROR_CHECK(err_code);
}

/**Starting advertising.*/
static void advertising_start(void) {
  ret_code_t err_code;

  err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
  APP_ERROR_CHECK(err_code);

  err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
  APP_ERROR_CHECK(err_code);
}
/* Getting MAc address*/
void device_name_get(void) {

  memcpy(serial_number,(uint32_t*)0x10001084,4);
    //NRF_LOG_INFO("Serial Number : %x, %x, %x, %x",serial_number[0],serial_number[1],serial_number[2],serial_number[3]);
    //NRF_LOG_FLUSH();
  mac_addr[0]=NRF_FICR->DEVICEADDR0;
  
  test_sno = test_sno | (serial_number[0] <<24)|(serial_number[1] <<16)|(serial_number[2] <<8)|(serial_number[3]);

  if (test_sno != 0xFFFF7FFFF)
  {
      
    for(int i=0;i<4;i++){
      service_uid[i]=serial_number[i];
      NRF_LOG_INFO("S.NO:%2X",service_uid[i]);
    }
   }
   else
   {
        for(int i=0;i<4;i++){
        service_uid[i]=(uint8_t)((mac_addr[0])>>(8*i));
        NRF_LOG_INFO("MAC:%2X",service_uid[i]);
      }
   }
service_uid_pointer=&service_uid;

}
/*Initializing the BLE stack.*/
static void ble_stack_init(void) {
  ret_code_t err_code;

  err_code = nrf_sdh_enable_request();
  APP_ERROR_CHECK(err_code);

  // Configure the BLE stack.
  // Fetch the start address of the application RAM.
  uint32_t ram_start = 0;
  err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
  APP_ERROR_CHECK(err_code);

  // Enable BLE stack.
  err_code = nrf_sdh_ble_enable(&ram_start);
  APP_ERROR_CHECK(err_code);
}

/** Initializing logging. */
static void log_init(void) {
  ret_code_t err_code = NRF_LOG_INIT(NULL);
  APP_ERROR_CHECK(err_code);

  NRF_LOG_DEFAULT_BACKENDS_INIT();
}

/**Initializing LEDs. */
static void leds_init(void) {
  ret_code_t err_code = bsp_init(BSP_INIT_LEDS, NULL);
  APP_ERROR_CHECK(err_code);
}

/**Initializing timers. */
static void timers_init(void) {
  ret_code_t err_code = app_timer_init();
  APP_ERROR_CHECK(err_code);
}

/** Initializing power management.
 */
static void power_management_init(void) {
  ret_code_t err_code;
  err_code = nrf_pwr_mgmt_init();
  APP_ERROR_CHECK(err_code);
}

/*Function for handling the idle state (main loop).
 *No pending log operation, then sleep until next the next event occurs.
 */
static void idle_state_handle(void) {
  if (NRF_LOG_PROCESS() == false) {
    nrf_pwr_mgmt_run();
  }
}

/*Main Loop */
int main(void) {
  // Initialize.
  nrf_gpio_cfg_input(11,GPIO_PIN_CNF_PULL_Pullup);
  nrf_gpio_cfg_output(14);
  log_init();
  timers_init();
 // leds_init();
  device_name_get();
  power_management_init();
  ble_stack_init();
  advertising_init();
  nrf_drv_clock_init();
  sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, BLE_GAP_TX_POWER_ROLE_ADV, 0);     //Set transmission Power
  // Start execution.
  NRF_LOG_INFO("Beacon example started.");
  
  advertising_start();

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

/**
 * @}
 */
Here is my code.I m not getting the result.Please guide me to solve this issue

Parents Reply Children
  • If you want advertising data to change, you need to call the functions that initialize advertising data again. It is not sufficient to change the variable that was used when first initializing advertising data. The data is copied to internal buffers in the stack.

  • hi jorgen ,

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
    ret_code_t err_code;
    err_code = sd_ble_gap_adv_stop(m_adv_handle);
    nrf_drv_gpiote_out_toggle(14);
    device_name_get();
    advertising_init1();   // Re_initialise the parameter
    uint16_t i;
    err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
    NRF_LOG_INFO("Beacon.");
    nrf_delay_ms(1000);
    advertising_init();  // after 10 advertising set to back to normal
    }

    All r works fine.

    Except one thing.

    while pressing button,i reinitialized advertising data (advertising_init1();).

    then next 10 advertising the parameters should hold and then its back to its original condition(advertising_init();)

    i stuck in 10 advertising. please help me

  • mayuri said:
    i stuck in 10 advertising.

    What do you mean by this? 

    It is not recommended to spend long time inside interrupt handlers, I would recommend that you do the work in main loop and use flags that you set in the handlers, to tell what should happen in main context. 

  • Thanks for your valuable recommend. i changed to interrupt handler as you said

    for (;;)
    {
    //advertising_start();
    idle_state_handle();
    if(flag==1)
    {
    ret_code_t err_code;
    err_code = sd_ble_gap_adv_stop(m_adv_handle);
    nrf_drv_gpiote_out_toggle(14);
    device_name_get();
    advertising_init_new();    // reinitialised beacon parameteruint32_t i;
    err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
    NRF_LOG_INFO("Beacon.");
    for(i=0;i>100;i++)
    {
    //i=0;
    idle_state_handle();
    i++;
    }
    advertising_init();
    nrf_drv_gpiote_out_toggle(14);
    flag=0;
    }

    What do you mean by this? 

    i mean that, after pressing button,the next 10 advertising will be re initialed advertising  (advertising_init_new();  ).then it back to normal advertising mode.

    now i checked in NRFconnect app..i can see the re initialed advertising value by 1sec. then it changed immediately.i want to check advertising count. how do i check advertising count?

  • I would rather recommend that you setup a timer (app_timer can be used - see application timer tutorial) that change the advertising back after n times the advertising interval.

Related