Hi,
My advertising initial is as follow.
But, 10~11 packet are sent and stop.
After 7~8 sec. resent advertisement packet again.... and 10~10 packet send, 7~8 sec stop...
What is the problem?
BR
Paul
Hi,
My advertising initial is as follow.
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.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. 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);
But, 10~11 packet are sent and stop.
After 7~8 sec. resent advertisement packet again.... and 10~10 packet send, 7~8 sec stop...
What is the problem?
BR
Paul
Hi Paul,
I do not see anything here that should cause advertising to stop. Can you share all your advertising related code, or perhaps the whole application?
Einar
Hi,
I attached full source file here.
/** * Copyright (c) 2014 - 2021, Nordic Semiconductor ASA * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @file * * @defgroup ble_sdk_app_beacon_main main.c * @{ * @ingroup ble_sdk_app_beacon * @brief Beacon Transmitter Sample Application main file. * * This file contains the source code for an Beacon transmitter sample application. */ #include <stdbool.h> #include <stdint.h> #include <stdarg.h> #include "nordic_common.h" #include "nrf.h" #include "nrf_sdh.h" #include "nrf_sdh_soc.h" #include "nrf_sdh_ble.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "nrf_log_internal.h" #include "nrf_ble_qwr.h" #include "nrf_gpio.h" #include "nrf_gpiote.h" #include "nrf_pwr_mgmt.h" #include "nrf_delay.h" #include "nrf_drv_gpiote.h" #include "nrf_drv_saadc.h" #include "nrf_drv_twi.h" #include "nrfx_twi.h" #include "ble_hci.h" #include "ble_gap.h" #include "ble_advdata.h" #include "ble_advertising.h" #include "ble_conn_params.h" #include "bsp_btn_ble.h" #include "boards.h" #include "app_timer.h" #include "app_uart.h" #include "app_util_platform.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "def.h" #include "decl.h" #define APP_BLE_CONN_CFG_TAG 1 /**< A tag identifying the SoftDevice BLE configuration. */ #define NON_CONNECTABLE_ADV_INTERVAL MSEC_TO_UNITS(500, 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 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_MEASURED_RSSI 0xC3 /**< The Beacon's measured RSSI at 1 meter distance in dBm. */ #define APP_COMPANY_IDENTIFIER 0x0059 /**< Company identifier for Nordic Semiconductor ASA. as per www.bluetooth.org. */ #define APP_MAJOR_VALUE 0x01, 0x02 /**< Major value used to identify Beacons. */ #define APP_MINOR_VALUE 0x03, 0x04 /**< Minor value used to identify Beacons. */ #define APP_BEACON_UUID 0x4b, 0x33, 0xc0, 0xbf, \ 0x54, 0x13, 0x00, 0x02, \ 0x00, 0x11, 0x22, 0x33, \ 0x44, 0x55, 0x66, 0x77 /**< Proprietary UUID for Beacon. */ #define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */ #if defined(USE_UICR_FOR_MAJ_MIN_VALUES) #define MAJ_VAL_OFFSET_IN_BEACON_INFO 18 /**< Position of the MSB of the Major Value in m_beacon_info array. */ #define UICR_ADDRESS 0x10001080 /**< Address of the UICR register used by this example. The major and minor versions to be encoded into the advertising data will be picked up from this location. */ #endif 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. */ /**@brief Struct that contains pointers to the 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 } }; APP_TIMER_DEF(m_app_timer_id); APP_TIMER_DEF(m_led_off_timer_id); int hostConnected = 0; int moduleId = TAG_MODULE; static int idle_cnt = IDLE_CNT; 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_MAJOR_VALUE, // Major arbitrary value that can be used to distinguish between Beacons. APP_MINOR_VALUE, // Minor arbitrary value that can be used to distinguish between Beacons. APP_MEASURED_RSSI // Manufacturer specific information. The Beacon's measured TX power in // this implementation. }; /**@brief Callback function for asserts in the SoftDevice. * * @details This function will be called in case of an assert in the SoftDevice. * * @warning This handler is an example only and does not fit a final product. You need to analyze * how your product is supposed to react in case of Assert. * @warning On assert from the SoftDevice, the system can only recover on reset. * * @param[in] line_num Line number of the failing ASSERT call. * @param[in] file_name File name of the failing ASSERT call. */ void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name) { app_error_handler(DEAD_BEEF, line_num, p_file_name); } /**@brief Function for initializing the Advertising functionality. * * @details Encodes the required advertising data and passes it to the stack. * Also builds a structure to be passed to the stack when starting advertising. */ static void advertising_init(void) { uint32_t err_code; ble_advdata_t advdata; 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; #if defined(USE_UICR_FOR_MAJ_MIN_VALUES) // If USE_UICR_FOR_MAJ_MIN_VALUES is defined, the major and minor values will be read from the // UICR instead of using the default values. The major and minor values obtained from the UICR // are encoded into advertising data in big endian order (MSB First). // To set the UICR used by this example to a desired value, write to the address 0x10001080 // using the nrfjprog tool. The command to be used is as follows. // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val <your major/minor value> // For example, for a major value and minor value of 0xabcd and 0x0102 respectively, the // the following command should be used. // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val 0xabcd0102 uint16_t major_value = ((*(uint32_t *)UICR_ADDRESS) & 0xFFFF0000) >> 16; uint16_t minor_value = ((*(uint32_t *)UICR_ADDRESS) & 0x0000FFFF); uint8_t index = MAJ_VAL_OFFSET_IN_BEACON_INFO; m_beacon_info[index++] = MSB_16(major_value); m_beacon_info[index++] = LSB_16(major_value); m_beacon_info[index++] = MSB_16(minor_value); m_beacon_info[index++] = LSB_16(minor_value); #endif 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.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. 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); } /**@brief Function for 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); } /**@brief Function for initializing the BLE stack. * * @details Initializes the SoftDevice and the BLE event interrupt. */ 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 using the default settings. // 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); } /**@brief Function for initializing logging. */ static void log_init(void) { return; ret_code_t err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); NRF_LOG_DEFAULT_BACKENDS_INIT(); } /**@brief Function for initializing LEDs. */ static void leds_init(void) { return; ret_code_t err_code = bsp_init(BSP_INIT_LEDS, NULL); APP_ERROR_CHECK(err_code); } /**@brief Function for initializing timers. */ static void timers_init(void) { ret_code_t err_code = app_timer_init(); APP_ERROR_CHECK(err_code); } /**@brief Function for 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); } /**@brief Function for handling the idle state (main loop). * * @details If there is 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(); } } /**@brief Function for handling app_uart events. * * @details This function receives a single character from the app_uart module and appends it to * a string. The string is sent over BLE when the last character received is a * 'new line' '\n' (hex 0x0A) or if the string reaches the maximum data length. */ static uint8_t uart_data_ring_buf[UART_MAX_DATA_LEN]; static uint16_t wr_ptr = 0, rd_ptr = 0; void uart_event_handle(app_uart_evt_t * p_event) { return; switch (p_event->evt_type) { /**@snippet [Handling data from UART] */ case APP_UART_DATA_READY: { uint8_t ch; UNUSED_VARIABLE(app_uart_get(&ch)); //app_uart_put (ch); uart_data_ring_buf[wr_ptr ++] = ch; if (wr_ptr == UART_MAX_DATA_LEN) { wr_ptr = 0; } } break; /**@snippet [Handling data from UART] */ case APP_UART_COMMUNICATION_ERROR: NRF_LOG_ERROR("Communication error occurred while handling UART."); APP_ERROR_HANDLER(p_event->data.error_communication); break; case APP_UART_FIFO_ERROR: NRF_LOG_ERROR("Error occurred in FIFO module used by UART."); APP_ERROR_HANDLER(p_event->data.error_code); break; default: break; } } void uart_rx_handler (void) { uint8_t ch; if (wr_ptr != rd_ptr) { ch = uart_data_ring_buf [rd_ptr ++]; DBG ("%c", ch); if (rd_ptr == UART_MAX_DATA_LEN) { rd_ptr = 0; } } } /**@brief Function for initializing the UART. */ static void uart_init(void) { ret_code_t err_code; app_uart_comm_params_t const comm_params = { .rx_pin_no = DBG_UART_RX_PIN, .tx_pin_no = DBG_UART_TX_PIN, .rts_pin_no = 0, .cts_pin_no = 0, .flow_control = APP_UART_FLOW_CONTROL_DISABLED, .use_parity = false, .baud_rate = UART_BAUDRATE_BAUDRATE_Baud115200 }; APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_event_handle, APP_IRQ_PRIORITY_LOWEST, err_code); APP_ERROR_CHECK(err_code); } static void app_timer_event_handler (void * p_context) { nrf_gpio_pin_clear (OP_LED_1_PIN); app_timer_start(m_app_timer_id, APP_TIMER_TICKS(APP_TIMER_INTERVAL), NULL); app_timer_start(m_led_off_timer_id, APP_TIMER_TICKS(1), NULL); } static void led_off_timer_event_handler (void * p_context) { nrf_gpio_pin_set (OP_LED_1_PIN); } static void lis2dw_int_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { idle_cnt = IDLE_CNT; } static void lis2dw_interrupt_port_ini (void) { ret_code_t err_code; err_code = nrf_drv_gpiote_init(); APP_ERROR_CHECK(err_code); // This is because the IN event requires the HF clock to be running, i.e. adding about 250uA. // The PORT event on the other hand does not require the HF clock to be running and // is therefore better suited for low power applications. nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false); // port interrupt, not IN_Event in_config.pull = NRF_GPIO_PIN_PULLDOWN; err_code = nrf_drv_gpiote_in_init(LIS2DW_INT1_PIN, &in_config, lis2dw_int_handler); APP_ERROR_CHECK(err_code); nrf_drv_gpiote_in_event_enable(LIS2DW_INT1_PIN, true); } /**@brief Function for initializing buttons and leds. */ static void port_init(void) { nrf_gpio_cfg_input(MODULE_ID_PIN, NRF_GPIO_PIN_NOPULL ); moduleId = nrf_gpio_pin_read (MODULE_ID_PIN); nrf_gpio_cfg_output(OP_LED_1_PIN); nrf_gpio_cfg_output(OP_LED_2_PIN); nrf_gpio_pin_clear (OP_LED_1_PIN); nrf_gpio_pin_clear (OP_LED_2_PIN); } void tx_power_set (int tx_power) { sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_adv_handle, tx_power); } /** * @brief Function for application main entry. */ int main(void) { // Initialize. log_init(); port_init(); uart_init (); timers_init(); leds_init(); power_management_init(); ble_stack_init(); advertising_init(); sd_power_dcdc_mode_set (NRF_POWER_DCDC_ENABLE); app_timer_create(&m_app_timer_id, APP_TIMER_MODE_SINGLE_SHOT, app_timer_event_handler); app_timer_start(m_app_timer_id, APP_TIMER_TICKS(1), NULL); app_timer_create(&m_led_off_timer_id, APP_TIMER_MODE_SINGLE_SHOT, led_off_timer_event_handler); // Start execution. NRF_LOG_INFO("Beacon example started."); DBG ("Start AIoT Tag\n"); DBG ("Advertising started !!\n"); advertising_start(); tx_power_set (0); DBG ("Power is set to 0\n"); if (0) { lis2dw_init (); // LFCLK on for power saving NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; NRF_CLOCK->TASKS_LFCLKSTART = 1; while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0); lis2dw_interrupt_port_ini (); } // Enter main loop. for (;; ) { idle_state_handle(); uart_rx_handler (); } } /** * @} */
Hi,
I do not see anything in your code that explains the described behavior where the device sends a short burst of advertising packets, then pausing for some seconds before sending a burst again.
Have you checked (for instance by enabling logging) to see if the device resets and that is how advertising is re-started? If not, can you check? Also, what else have you learned by debugging?
If you don't make progress, perhaps you can make a project that reproduce this on a DK so that I can test on mye end?
Hi,
I'm testing on nrf52840 DK board, not custom board.
I insert the LED blink test part in next of port_init(); call as follow.
for (int i = 0; i < 5; i ++) { nrf_gpio_pin_toggle (OP_LED_1_PIN); nrf_delay_ms (100); } nrf_gpio_pin_clear (OP_LED_1_PIN);
After starting the DK board, I found only once executed this. so, It looks no reset is occurred during running.
I am testing on s140_nrf52_7.2.0_softdevice.hex.