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

long press button to start advertisement does not work

Hello,

I am trying to make a beacon start advertising on a long press of a button. Using this as a reference, I implemented a timer as follows:

this is the flag to keep track of advertising status-

static bool advflag = false;

this is the handler and timer creation/start-

Note that, I am using m_timer_id which is a repeated timer for some other purpose. The timer used for the button is m_timer_b which is a single shot timer.

static void timer_b_handler(void * p_context)
{
	uint32_t err_code;
	if(nrf_gpio_pin_read(BSP_BUTTON_0)==0){
		err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);
	nrf_gpio_pin_toggle(BSP_LED_2);
	}
}

// Create timers
static void create_timers()
{   
    uint32_t err_code;

    // Create timers
    err_code = app_timer_create(&m_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                timer_a_handler);
	APP_ERROR_CHECK(err_code);
		err_code = app_timer_create(&m_timer_id_b,
                                APP_TIMER_MODE_SINGLE_SHOT,
                                timer_b_handler);
    APP_ERROR_CHECK(err_code);
}

void bsp_event_handler(bsp_event_t event)
{
    uint32_t err_code;
    switch (event)
    {
        case BSP_EVENT_SLEEP:
            sleep_mode_enter();
            break;

        case BSP_EVENT_DISCONNECT:
            err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            if (err_code != NRF_ERROR_INVALID_STATE)
            {
                APP_ERROR_CHECK(err_code);
            }
            break;

        case BSP_EVENT_WHITELIST_OFF:
            err_code = ble_advertising_restart_without_whitelist();
            if (err_code != NRF_ERROR_INVALID_STATE)
            {
                APP_ERROR_CHECK(err_code);
            }
            break;
				case BSP_EVENT_KEY_0: 
						//mark(first);
						if(advflag==false){
							err_code = app_timer_start(m_timer_id_b, APP_TIMER_TICKS(2000, APP_TIMER_PRESCALER),NULL);
                            APP_ERROR_CHECK(err_code);
						}
						break;
        default:
            break;
    }
}

I even made changes in the softdevice event handler-

static void on_ble_evt(ble_evt_t * p_ble_evt)
{
    uint32_t                         err_code;
    
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
						advflag=true;
					scan_start();
            break;
            
        case BLE_GAP_EVT_DISCONNECTED:
            err_code = bsp_indication_set(BSP_INDICATE_IDLE);
            APP_ERROR_CHECK(err_code);
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
							advflag=false;
						scan_start();
			
            break;

        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            // Pairing not supported
            err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GATTS_EVT_SYS_ATTR_MISSING:
            // No system attributes have been stored.
            err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
            APP_ERROR_CHECK(err_code);
            break;
				
				case BLE_GAP_EVT_ADV_REPORT:
            on_adv_report(p_ble_evt);
            break;
				
				case BLE_GAP_EVT_TIMEOUT:
            if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING)
			{
				advflag = false; // If advertising times out
			}
            break;
        default:
            // No implementation needed.
            break;
    }
}

What I have observed is that, when i press and hold the button, both LED! and LED3 flash once and the board does not do anything

(I'm assuming the device reset?.If so, i dont understand why, i assumed using the flag fixes the advertising while already advertising problem ).

But when i hold the button even after those 2 LEDs have flashed, the device works as required while i keep the button pressed.

I am using the nRF52832 development board, nRF5 SDK11.0 and keil uvision5

Any solutions to this would be appreciated.

Thank you.

Parents
  • Hi,

    In many of the BLE SDK examples button ID 0 is used to go to system off mode. (on the event BSP_EVENT_SLEEP). Try using BSP_BUTTON_2 / BSP_EVENT_KEY_2 instead, and see if that solves the issue.

    See this post for general information on how to debug your code.

  • I used ble_app_uart example as one of the bases of my code, though in that ID 0 is used to wakeup the device from sleep.

    Since I intend for this code to run in a custom nRF51 board with only 1 button as a goal, I will have to use that for on/off as well.

    That post afaik doesn't explain how to identify errors that depend on external events like me holding down the button, any idea on how I can do that?

  • Since I intend for this code to run in a custom nRF51 board with only 1 button as a goal, I will have to use that for on/off as well.

    How are you handling the BSP_EVENT_SLEEP event ?

    How do you decide if it should go to sleep or not?

    By default it looks like this:

            case BSP_EVENT_SLEEP:
                sleep_mode_enter();
                break;

    That post afaik doesn't explain how to identify errors that depend on external events like me holding down the button, any idea on how I can do that?

    Try setting breakpoints, and see if you reach the desired event-handlers when you press the button.

  • I have not done anything to the SLEEP event. Is it triggered by the button press?

    I thought it just set button0 as the "wakeup button" and set device to sleep and that the event itself was triggered by an internal timeout.

    edit:

    The thing is, Ive been using button0 for another operation as well (the mark() function in the snippet) which does not have any issues even with the SLEEP even being there. So I dont think having another operation also be triggered by the button should cause problems. I'm new with using timers, so maybe I've made a mistake related to them. I just used the same code for timer a,b except the timer ID,handler and repeated/single shot part being different. Could it be that the timers interfere with each other (i assume that they might both use timer0 and interfere with each other, but i'm not exactly sure where to select timer0/timer1 during timer creation)

Reply
  • I have not done anything to the SLEEP event. Is it triggered by the button press?

    I thought it just set button0 as the "wakeup button" and set device to sleep and that the event itself was triggered by an internal timeout.

    edit:

    The thing is, Ive been using button0 for another operation as well (the mark() function in the snippet) which does not have any issues even with the SLEEP even being there. So I dont think having another operation also be triggered by the button should cause problems. I'm new with using timers, so maybe I've made a mistake related to them. I just used the same code for timer a,b except the timer ID,handler and repeated/single shot part being different. Could it be that the timers interfere with each other (i assume that they might both use timer0 and interfere with each other, but i'm not exactly sure where to select timer0/timer1 during timer creation)

Children
Related