Wake on button press, connect with master and transmit button state

Development Software: Segger Embedded Studio, nRF5_SDK_17.0.2_d674dde

Project consists of an nRF52DK-based peripheral (remote control) and a custom nRF52832-based central (carries out the desired operations). These units are separated by a few meters.

Primary Objective: The time from a button press at the peripheral until the operation is initiated at the central must be minimal; Less than 200msec. Max battery power conservation.

Peripheral Objective: Always in deep sleep until the user presses a button. When the user presses a button the device wakes up, advertises and connects to the central.  One byte of data is then transmitted for the button press followed by a 2nd byte of data when the button is released. Finally, disconnect and return to deep sleep.

Central Objective: Scans, connects, receives the button press and release commands and performs the user-specified actions.

For a short connection time I set the following: Scan interval of 20ms. Scan window of 12.5ms. Advertisement interval of 20ms

Not using pairing or bonding

What works so far:

1. Peripheral goes to deep sleep

2. Peripheral wakes up on button press, advertises and connects to the central unit

3. Central only receives the button release byte (if the button is released greater than 1.0 sec after its pressed)

What doesn't work:

1. Central doesn't receive the button press byte

2. Central doesn't receive the button release byte if the user releases it less than 1.0 sec after it's pressed

My observations / thoughts:

Central doesn't receive the button press byte because the press occurs before connection.

Central doesn't receive the button release byte because if it released before the "connection time + central/peripheral negotiation time", the peripheral won't send it.

When looking at Sniffer data, the time delta between connection indicate (CONNECT_IND) and the end of negotiation is consistently 512 msec.

At the function: ble-evt_handler,  p_ble_evt->header.evt_id = BLE_GAP_EVT_CONNECTED I tried manually transmitting the button pressed byte, but the Sniffer viewer never displayed the transmitted byte. I suspect because negotiation was in progress.

1. Is there anyway to get around the negotiation time? Does connecting to a previously paired device cut down on the negotiation time? Current negotiation time is too long to meet my requirements.

2. I searched examples, nothing. Do you know of any example code?

3. Any suggestions on how to transmit the button press event byte to the central?

Parents
  • I asked a similar question and was directed to an older project , which will probably need updating to use the new SDK 17.0.2.
    GitHub - NordicPlayground/solar_sensor_beacon

    That said, all new development is going to be in the nRF Connect SDK (I am a little sad about that myself, but ...progress must move forward). The quicker you try to translate this into the newer code, the happier you may be.
    A M

  • Thanks for your comments. I have successfully implemented pairing and bonding and my connection time is reduced. That's a good thing. 

    A follow up question:

    I previously asked:

    3. Any suggestions on how to transmit the button press event byte to the central?

    You stated:

    Maybe you can use the Queue library for this. Queue the button presses, and when you get the connected event, and/or are ready to send the data, you get the button presses from the queue, and then send the data.

    When I attempt to transmit data to the client in the connected event no data is sent (as per sniffer). When I start a Timer in the Connected Event and load it with a value that gives a 700msec time out and then call 

     send_data_to_client(uint32_t cmd)

    within the Timer event handler, no data is sent to the client. When I load the timer with a value that gives a 750msec time out, data is successfully sent to the Client.

    Why can't I successfully send data to the Client unless I wait for at least 750msec? Thanks much for your time.

    Connected Event based on ble_peripheral_hrs:

    #define TILT_UP   1

        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                printf("Connected.\n ");
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
                APP_ERROR_CHECK(err_code);
                send_data_to_client(TILT_UP); // this doesn't work here
            break;
    _______________________________________________________

    Transmit packet to client sub:
    void send_data_to_client(uint32_t cmd)
    {
        ret_code_t      err_code;
        uint16_t        heart_rate;
    
        heart_rate = (uint16_t)cmd;
    
        err_code = ble_hrs_heart_rate_measurement_send(&m_hrs, heart_rate);
        if ((err_code != NRF_SUCCESS) &&
            (err_code != NRF_ERROR_INVALID_STATE) &&
            (err_code != NRF_ERROR_RESOURCES) &&
            (err_code != NRF_ERROR_BUSY) &&
            (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
           )
        {
            APP_ERROR_HANDLER(err_code);
        }
    }













    sss

Reply
  • Thanks for your comments. I have successfully implemented pairing and bonding and my connection time is reduced. That's a good thing. 

    A follow up question:

    I previously asked:

    3. Any suggestions on how to transmit the button press event byte to the central?

    You stated:

    Maybe you can use the Queue library for this. Queue the button presses, and when you get the connected event, and/or are ready to send the data, you get the button presses from the queue, and then send the data.

    When I attempt to transmit data to the client in the connected event no data is sent (as per sniffer). When I start a Timer in the Connected Event and load it with a value that gives a 700msec time out and then call 

     send_data_to_client(uint32_t cmd)

    within the Timer event handler, no data is sent to the client. When I load the timer with a value that gives a 750msec time out, data is successfully sent to the Client.

    Why can't I successfully send data to the Client unless I wait for at least 750msec? Thanks much for your time.

    Connected Event based on ble_peripheral_hrs:

    #define TILT_UP   1

        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                printf("Connected.\n ");
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
                APP_ERROR_CHECK(err_code);
                send_data_to_client(TILT_UP); // this doesn't work here
            break;
    _______________________________________________________

    Transmit packet to client sub:
    void send_data_to_client(uint32_t cmd)
    {
        ret_code_t      err_code;
        uint16_t        heart_rate;
    
        heart_rate = (uint16_t)cmd;
    
        err_code = ble_hrs_heart_rate_measurement_send(&m_hrs, heart_rate);
        if ((err_code != NRF_SUCCESS) &&
            (err_code != NRF_ERROR_INVALID_STATE) &&
            (err_code != NRF_ERROR_RESOURCES) &&
            (err_code != NRF_ERROR_BUSY) &&
            (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
           )
        {
            APP_ERROR_HANDLER(err_code);
        }
    }













    sss

Children
Related