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

2 button state update after reseat

Hello

We have two boards PCA10040, client and peripheral. Blinky exemple.

The project is with two buttons on peripheral side and 2 leds on the client side.

If we hold down  button1 on the peripheral  and then after reseat the central  led3 toggle on the central..

That works ok. Also with button2 and led4.

But now the problem.

If we hold down the two buttons together ( button1 and button2) on the peripheral  and then after reseat the central

only 1 led toggle.

We have do a init_state_update on ble_lbs.c . below the code, what we do wrong?

Thank you very much for the help!


#include "boards.h"


void init_state_update(ble_lbs_t * p_lbs)
{
            ret_code_t err_code;
            ble_gatts_hvx_params_t params;
            uint8_t button_state = 0;
 
      if(nrf_gpio_pin_read(BSP_BUTTON_0)==0)
       
        {
             button_state=1;
       }
       
         //2. button
      
        if(nrf_gpio_pin_read(BSP_BUTTON_1)==0)
       
              {
             button_state=3;
       }
           
            uint16_t len = sizeof(button_state);

            memset(&params, 0, sizeof(params));
            params.type = BLE_GATT_HVX_NOTIFICATION;
            params.handle = p_lbs->button_char_handles.value_handle;
            params.p_data = &button_state;
            params.p_len = &len;
            err_code = sd_ble_gatts_hvx(p_lbs->conn_handle, &params);
            nrf_gpio_pin_read(BSP_BOARD_LED_3);
           nrf_gpio_pin_read(BSP_BOARD_LED_4);
      
            APP_ERROR_CHECK(err_code);    

_____

static void on_write(ble_lbs_t * p_lbs, ble_evt_t * p_ble_evt)
{
    ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;

    if ((p_evt_write->handle == p_lbs->led_char_handles.value_handle) &&
        (p_evt_write->len == 1) &&
        (p_lbs->led_write_handler != NULL))
    {
        p_lbs->led_write_handler(p_lbs, p_evt_write->data[0]);
    }
  
//for after reseat.
  
   else if (p_evt_write->handle == p_lbs->button_char_handles.cccd_handle)
    {
        if(p_ble_evt->evt.gatts_evt.params.write.len == 2)
      
    {
               init_state_update(p_lbs);
     
    }
    } 
  
}

Parents
  • Hello,

    You call this function only once upon reset, right? The init_state_update()?

     

    If you have pressed both buttons, then if(nrf_gpio_pin_read(BSP_BUTTON_0)==0) will trigger, and sett button_state = 1. Then it continues to if(nrf_gpio_pin_read(BSP_BUTTON_1)==0), which will also trigger, and overwrite button_state = 3, and then send the button_state (= 3).

     

    A workaround to get your application to work is either to send 2 messages, one with button 1 and one with button 2, or you can (which I recommend you to try) create a button mask.

     

    uint8_t button_state = 0;

    if(button0)

    {

        button_state |= (1 << 0);

    }

    if(button1)

    {

        button_state |= (1<< 1);

    }

     

    this will result in button state being the following:

    btn_1_pressed      btn_2_pressed        button_state(bits):     button_state(hex)

    0                            0                             0b00000000              0x00

    1                            0                             0b00000001              0x01

    0                            1                             0b00000010              0x02

    1                            1                             0b00000011              0x03

     

    When you send this byte to the central, you will have to decode it there. You can do something like this:

    uint8_t button_state = 0;
    button_state |= (1 << 0);
    button_state |= (1 << 1);
    NRF_LOG_INFO("button_state = 0x%2x", button_state);
    
    uint8_t button1_state = (0x01 & (button_state >> 0));
    uint8_t button2_state = (0x01 & (button_state >> 1));
    
    NRF_LOG_INFO("button1: %d, button2: %d", button1_state, button2_state);

    play around with the button_state |= (1 << n) to see how it behaves. Of course, you should use the byte that you sent, and not change button_state in the central. Just play around with this on one of the DKs to see how it behaves.

     

    Best regards,

    Edvin

     

  • Hello Edvin

    Thank you very much for the answer.

    I have do it with a second message for the button1 

    "void init_state_update2(ble_lbs_t * p_lbs)"  

    and

    else if (p_evt_write->handle == p_lbs->button_char_handles.cccd_handle)
        {
            if(p_ble_evt->evt.gatts_evt.params.write.len == 2)
          
        {
                   init_state_update(p_lbs);
                   init_state_update2(p_lbs);
        }

    It works fine!

    This with the mask i will try out.

    Thank you very much

    Best regards
    mc

Reply
  • Hello Edvin

    Thank you very much for the answer.

    I have do it with a second message for the button1 

    "void init_state_update2(ble_lbs_t * p_lbs)"  

    and

    else if (p_evt_write->handle == p_lbs->button_char_handles.cccd_handle)
        {
            if(p_ble_evt->evt.gatts_evt.params.write.len == 2)
          
        {
                   init_state_update(p_lbs);
                   init_state_update2(p_lbs);
        }

    It works fine!

    This with the mask i will try out.

    Thank you very much

    Best regards
    mc

Children
No Data
Related