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

Disconnect and stop advertising after transaction

Hi - In the examples provided, a peripheral will go to power off after completing its transactions.This means the the application does not have to "clean up" afterwards.

I have an application that requires the peripheral to stay on Power On mode all the time due to transactions on an accelerometer. When an event is detected the application must start advertising, and when connected to, it sends a transaction to the central application and receives a response from the central application.

After that, the application must clean up and go back to monitoring the accelerometer until the next event is detected.

My question is, how do I clean up to ensure that I can start the process all over again without powering off.

My application works fine, but I have the following issues:

After receiving the response from the central, I do a disconnect. When I receive the disconnect event, then I stop scanning else the central will simply try and connect again. When I call start advertising again thereafter I get errors.

Please can you advise as to how to gracefully achieve my objective.

Thank you

Parents
  • Hello,

    The device will not go to power off unless you specifically tell it to. In our examples, this is typically done in a function called sleep_mode_enter(), which calls sd_power_system_off(), which will put the device in "deep sleep" mode (basically turning it off). The only way to recover is by either a pin interrupt, power cycle, or the NFC. So if it is possible with your accelerometer to toggle a pin on movement, you can go to deep sleep, but if it suits your application to not go to system-off mode, you don't need to do this call (sd_power_system_off()) .

    Other than this, your approach sounds quite straight forward. You need to advertise, scan with the connecting device, and wait for them to connect. When they are connected, send the data that you need to send, and wait for the reply. If you need the reply message, you can wait for it, but if you only use the reply to verify that the data was sent successfully, you can also wait for the BLE_GATTS_EVT_HVN_TX_COMPLETE event (you must add this to your event handler). When you have received this event the same number of times as messages you have sent, you know that all of the messsages has been ACKed. When this happens, disconnect.

    Note that depending on your advertisement settings, the device will automatically start to advertise on the BLE_GAP_EVT_DISCONNECTED event. This is triggered in the on_disconnected() function in ble_advertising.c (the name may depend on the SDK version that you are using. You can change this in the advertising_init function on main.c. Note that these variables may have changed, but in SDK15.2.0 it is done like this (the advertising_init() function is from the ble_app_uart example):

    /**@brief Function for initializing the Advertising functionality.
     */
    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 = false;
        init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    
        init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.srdata.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;
        init.config.ble_adv_on_disconnect_disabled = true;      //ADD THIS LINE TO PREVENT ADVERTISING ON THE DISCONNECTED EVENT
    
        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);
    }

    Now you just need to wait for your interrupt from the accelerometer to start advertising again.

    Best regards,

    Edvin

Reply
  • Hello,

    The device will not go to power off unless you specifically tell it to. In our examples, this is typically done in a function called sleep_mode_enter(), which calls sd_power_system_off(), which will put the device in "deep sleep" mode (basically turning it off). The only way to recover is by either a pin interrupt, power cycle, or the NFC. So if it is possible with your accelerometer to toggle a pin on movement, you can go to deep sleep, but if it suits your application to not go to system-off mode, you don't need to do this call (sd_power_system_off()) .

    Other than this, your approach sounds quite straight forward. You need to advertise, scan with the connecting device, and wait for them to connect. When they are connected, send the data that you need to send, and wait for the reply. If you need the reply message, you can wait for it, but if you only use the reply to verify that the data was sent successfully, you can also wait for the BLE_GATTS_EVT_HVN_TX_COMPLETE event (you must add this to your event handler). When you have received this event the same number of times as messages you have sent, you know that all of the messsages has been ACKed. When this happens, disconnect.

    Note that depending on your advertisement settings, the device will automatically start to advertise on the BLE_GAP_EVT_DISCONNECTED event. This is triggered in the on_disconnected() function in ble_advertising.c (the name may depend on the SDK version that you are using. You can change this in the advertising_init function on main.c. Note that these variables may have changed, but in SDK15.2.0 it is done like this (the advertising_init() function is from the ble_app_uart example):

    /**@brief Function for initializing the Advertising functionality.
     */
    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 = false;
        init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    
        init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.srdata.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;
        init.config.ble_adv_on_disconnect_disabled = true;      //ADD THIS LINE TO PREVENT ADVERTISING ON THE DISCONNECTED EVENT
    
        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);
    }

    Now you just need to wait for your interrupt from the accelerometer to start advertising again.

    Best regards,

    Edvin

Children
No Data
Related