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

Turn LED off when not advertising nrf 52840 PCA10059 SDK 15.3

Good day

Im trying to switch off an LED when my relay/hopper is not advertising. I switch the LED on successfully when transmission starts but I'm struggling to do the sd_ble_gap_adv_stop check to switch the led off. This is a simple relay/hopper and retransmits the MAC address of a received beacon + its own address. It works very well and I manage to stop the advertising successfully after a tiem out. Just need to switch the LED off.

The scanning part

static void advertising_init(void) // no more than 31 bytes 
{  
    uint32_t      err_code;
    ble_advdata_t advdata; // no more than 31 bytes
    uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;

    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;

        if (g_setAdvData) // if a mac address is received from a beacon build a payload consisting of repeater mac + beacon mac
    {  

        //mac address of the repeater (this device) added to payload
        manuf_specific_data.data.p_data [6]=repeater_mac_addr.addr[0]; // Local mac address
        manuf_specific_data.data.p_data [7]=repeater_mac_addr.addr[1]; // Local mac address
        manuf_specific_data.data.p_data [8]=repeater_mac_addr.addr[2]; // Local mac address
        manuf_specific_data.data.p_data [9]=repeater_mac_addr.addr[3]; // Local mac address
        manuf_specific_data.data.p_data [10]=repeater_mac_addr.addr[4]; // Local mac address
        manuf_specific_data.data.p_data [11]=repeater_mac_addr.addr[5]; // Local mac address 
        //cant go higher than 22
       
       //mac address of the beacon (received by this device) added to payload
        manuf_specific_data.data.p_data [12]= Beacon_mac_addr[0]; // Beacon MAC address
        manuf_specific_data.data.p_data [13]= Beacon_mac_addr[1]; // Beacon MAC address
        manuf_specific_data.data.p_data [14]= Beacon_mac_addr[2]; // Beacon MAC address
        manuf_specific_data.data.p_data [15]= Beacon_mac_addr[3]; // Beacon MAC address
        manuf_specific_data.data.p_data [16]= Beacon_mac_addr[4]; // Beacon MAC address
        manuf_specific_data.data.p_data [17]= Beacon_mac_addr[5]; // Beacon MAC address
      
           g_setAdvData = false; // turn off the set adv data and wait for next mac to come
   }

//shows the manuf payload of ble 
/*NRF_LOG_RAW_INFO("%02x%02X%02X%02X%02X\n",
                    manuf_specific_data.data.p_data [15], manuf_specific_data.data.p_data [16],
                    manuf_specific_data.data.p_data [17], manuf_specific_data.data.p_data [18],
                    manuf_specific_data.data.p_data [19], manuf_specific_data.data.p_data [20]);*/

NRF_LOG_RAW_INFO("Re-transmitting initial scanner MAC %02x:%02x:%02x:%02x:%02x:%02x ",initial_scanner_mac_addr[5], initial_scanner_mac_addr[4], initial_scanner_mac_addr[3], initial_scanner_mac_addr[2], initial_scanner_mac_addr[1], initial_scanner_mac_addr[0])
NRF_LOG_RAW_INFO("Re-transmitting  Beacon found MAC  %02x:%02x:%02x:%02x:%02x:%02x\r\n",Beacon_mac_addr[0], Beacon_mac_addr[1], Beacon_mac_addr[2], Beacon_mac_addr[3], Beacon_mac_addr[4], Beacon_mac_addr[5])
        
        nrf_gpio_pin_clear(NRF_GPIO_PIN_MAP(1, 9)); // green led  on to show advertising is on the go 
    //   nrf_delay_ms(10);
    //   nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(1, 9)); // green led  off

    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 (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        = 300;       // 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);
}

end loop while waiting for new data to come in for retransmission. I think this is where I need to switch my " adv in progress LED off"

  for (;;)
      {

        if (      ) {nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(1, 9));} // green led  off



      if(g_setAdvData)
                {

                 sd_ble_gap_adv_stop(m_adv_handle); 
                 
                    
                     advertising_init(); // load the new data for payload

                    //    if put something here to double check its not retransmitting something thats just been relayed, avoid an endless loop
                    //    {
                       advertising_start(); // start advertising

                    //    }
                      g_setAdvData = false; // turn of get new adv
                }

      idle_state_handle();
      }

From  what I have seen on the forum  here https://devzone.nordicsemi.com/f/nordic-q-a/14071/check-if-currently-advertising

in my "if (  ) " statement that is currently blank I need to check for a NRF_Success error code return but have not had any success.

any suggestions will be welcomed? :)

  • Hello,

    Do you want to actively stop the advertisement, or do you want to check if the advertisement has timed out?

    Best regards,

    Edvin

  • Hi Edvin

    stopping the advertisement is not a problem it seems to stop after the timeout. I would like to turn off the LED I switched on when I started to advertise.

    Im also looking at the following bsp_indication_set(BSP_INDICATE_ADVERTISING);

    could I not use that to indicate advertising and not advertising. have tried

    if (bsp_indication_set(BSP_INDICATE_ADVERTISING))
    {nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(1, 9));} // green led off}

  • Ok, then I suggest you turn off the led in your adverisement callback: on_adv_evt() in main.c (at least that is where it is located in the examples.

    From the ble_peripheral examples you have this function:

    /**@brief Function for handling advertising events.
     *
     * @param[in] ble_adv_evt  Advertising event.
     */
    static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
    {
        ret_code_t err_code;
    
        switch (ble_adv_evt)
        {
            case BLE_ADV_EVT_FAST:
                NRF_LOG_INFO("Fast advertising");
                err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
                APP_ERROR_CHECK(err_code);
                break; // BLE_ADV_EVT_FAST
    
            case BLE_ADV_EVT_IDLE:
                sleep_mode_enter();
                break; // BLE_ADV_EVT_IDLE
    
            default:
                break;
        }
    }

    Add the line that turns off the LED in the BLE_ADV_EVT_IDLE event, which is the one that is called when the advertising times out.

    EDIT: add it before sleep_mode_enter();

    Best regards,

    Edvin

  • Thanks, Edvin, what if I'm running Central?

    I have the below but I'm using non-connectable so none of the below cases seem to be entered.

    //@brief Function for handling BLE events.
     /*
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ret_code_t            err_code;
        ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;
    
    uint8_array_t adv_data;
    
        switch (p_ble_evt->header.evt_id)
        { 
      
    
            case BLE_GAP_EVT_CONNECTED:
                err_code = ble_nus_c_handles_assign(&m_ble_nus_c, p_ble_evt->evt.gap_evt.conn_handle, NULL);
                APP_ERROR_CHECK(err_code);
    
                err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                APP_ERROR_CHECK(err_code);
    
                // start discovery of services. The NUS Client waits for a discovery result
                err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
    
                NRF_LOG_INFO("Disconnected. conn_handle: 0x%x, reason: 0x%x",
                             p_gap_evt->conn_handle,
                             p_gap_evt->params.disconnected.reason);
                          /* nrf_gpio_pin_clear(NRF_GPIO_PIN_MAP(1, 0)); // set red red led
                             nrf_delay_ms(5);
                             nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(1, 0)); // clear red red led*/
                              
                break;
    
            case BLE_GAP_EVT_TIMEOUT:
                if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
                {
                    NRF_LOG_INFO("Connection Request timed out.");
                 /*   nrf_gpio_pin_clear(NRF_GPIO_PIN_MAP(1, 0)); // set red red led
                    nrf_delay_ms(5);
                    nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(1, 0)); // clear red red led*/
                    
                }
                break;
    
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                // Pairing not supported.
                err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
                APP_ERROR_CHECK(err_code);
                 nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(1, 9)); // switch off green led
                break;
    
            case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
                // Accepting parameters requested by peer.
                err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle,
                                                        &p_gap_evt->params.conn_param_update_request.conn_params);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
            {
                NRF_LOG_DEBUG("PHY update request.");
                ble_gap_phys_t const phys =
                {
                    .rx_phys = BLE_GAP_PHY_AUTO,
                    .tx_phys = BLE_GAP_PHY_AUTO,
                };
                err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
                APP_ERROR_CHECK(err_code);
            } break;
    
            case BLE_GATTC_EVT_TIMEOUT:
                // Disconnect on GATT Client timeout event.
                NRF_LOG_DEBUG("GATT Client Timeout.");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                 
                break;
    
            case BLE_GATTS_EVT_TIMEOUT:
                // Disconnect on GATT Server timeout event.
                NRF_LOG_DEBUG("GATT Server Timeout.");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                
                 
                break;
                
    // Here we get the BLE data, 
                case BLE_GAP_EVT_ADV_REPORT:
             {//NRF_LOG_RAW_HEXDUMP_INFO (m_scan.scan_buffer.p_data, m_scan.scan_buffer.len);
    
                    adv_data.size = p_gap_evt->params.adv_report.data.len;
    
                    memmove(RX_Data, p_gap_evt->params.adv_report.data.p_data, p_gap_evt->params.adv_report.data.len);

  • If you are advertising, then that is as a peripheral. 

    You are probably have a function called advertising_init()?

    does this do something like this:

    static void advertising_init(void)
    {
        uint32_t               err_code;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance      = true;
        init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
        init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
    
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
    
        init.evt_handler = on_adv_evt;
    
        err_code = ble_advertising_init(&m_advertising, &init);
        APP_ERROR_CHECK(err_code);
    
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }

    Is that correct? If not, may I see how you initialize your advertisements?

Related