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

Update BLE Characteristic from ENUM

Hi

I would like to use an ENUM and STUCT within my application to maintain device state (IDLE, RUNNING etc). This state needs to update a BLE Characteristic. I have the BLE Service and Characteristic running but am struggling to send the ENUM as a single byte (uint8_t).

The ENUM & STRUCT is as follows:

typedef enum
{
    IDLE    = 0x00,    //0
    RUNNING = 0x01,    //1
    FAULT   = 0x09     //9
} m_srm_state_evt_type_t;

typedef struct
{
    m_srm_state_evt_type_t evt_type;
} m_srm_state_type_t;
static m_srm_state_type_t m_srm_state;

And the BLE update char is as follows:

case BLE_SRVC_OPT_EVT_CONNECTED:
            uint8_t value[1]            = {m_srm_state.value};
            err_code = ble_srvc_opt_custom_value_update(&m_cus, value);
            APP_ERROR_CHECK(err_code);
            break;

I know it's my lack of programming skills, but really stuck on this one. Thanks in advance.

Parents
  • Hi,

    I'm interested in seeing more of your code, specifically the initialization of the service and the ble_srvc_opt_custom_value_update(). Also

    I have the BLE Service and Characteristic running but am struggling to send the ENUM as a single byte (uint8_t).

     What exactly happens when you run the application? Are you getting any errors? Have you tried debugging your application?

    regards

    Jared

  • Hi

    I think the issue is that I am attempting to send a Characteristic Value before it being ready (i.e. I'm sending as soon as BLE_SRVC_OPT_EVT_CONNECTED). As this is at the Service level, I assume that the Characteristic could still be being negotiated.

    Would this make sense?

  • Hi,

    Did you try the workaround suggest in the linked case in the previous reply? 

    You could try setting err_code =sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0)  before you call  ble_srvc_opt_custom_value_update(). And you should make sure that notifications is enabled.

    regards

    Jared

  • Hi

    I have looked at my code and carried out a few modifications and have a better understand how the SoftDevice works.

    The following is working, on the following event, it calls handle_ble_char:

    case BLE_SRVC_OPT_EVT_CONNECTED:
            t_value = SET;
            handle_ble_char(p_cus_service, &p_cus_service->status_char_handles , &t_value);
            break;

    The structure of handle_ble_char is as follows:

    static void handle_ble_char (ble_srvc_opt_t *p_service, ble_gatts_char_handles_t *p_char_handle, m_setget *p_type) {
    
        uint32_t err_code;
        ble_gatts_value_t	t_value;
    
        //Get & Set for ble_src_opt - Char - Status
        if (p_char_handle->value_handle == m_cus.status_char_handles.value_handle) {
            
            t_value.p_value = &m_srm_state.evt_type;
    	    t_value.len      = 1;
    	    t_value.offset   = 0;
    
            switch (*p_type)
            {
            case SET:
                err_code = sd_ble_gatts_value_set(p_service->conn_handle, p_char_handle->value_handle, &t_value);
        	    APP_ERROR_CHECK(err_code);
                break;
            case GET:
                err_code = sd_ble_gatts_value_get(p_service->conn_handle, p_char_handle->value_handle, &t_value);
        	    APP_ERROR_CHECK(err_code);
                break;
            default:
                break;
            }
        }
    
    }

    This is a universal bit of code which allows me to tell it which service and characteristic to set or get.

    It is working as planned now...thanks for the help on this one.

Reply
  • Hi

    I have looked at my code and carried out a few modifications and have a better understand how the SoftDevice works.

    The following is working, on the following event, it calls handle_ble_char:

    case BLE_SRVC_OPT_EVT_CONNECTED:
            t_value = SET;
            handle_ble_char(p_cus_service, &p_cus_service->status_char_handles , &t_value);
            break;

    The structure of handle_ble_char is as follows:

    static void handle_ble_char (ble_srvc_opt_t *p_service, ble_gatts_char_handles_t *p_char_handle, m_setget *p_type) {
    
        uint32_t err_code;
        ble_gatts_value_t	t_value;
    
        //Get & Set for ble_src_opt - Char - Status
        if (p_char_handle->value_handle == m_cus.status_char_handles.value_handle) {
            
            t_value.p_value = &m_srm_state.evt_type;
    	    t_value.len      = 1;
    	    t_value.offset   = 0;
    
            switch (*p_type)
            {
            case SET:
                err_code = sd_ble_gatts_value_set(p_service->conn_handle, p_char_handle->value_handle, &t_value);
        	    APP_ERROR_CHECK(err_code);
                break;
            case GET:
                err_code = sd_ble_gatts_value_get(p_service->conn_handle, p_char_handle->value_handle, &t_value);
        	    APP_ERROR_CHECK(err_code);
                break;
            default:
                break;
            }
        }
    
    }

    This is a universal bit of code which allows me to tell it which service and characteristic to set or get.

    It is working as planned now...thanks for the help on this one.

Children
No Data
Related