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

How to write uint32_t to characteristic?

I will write time to my ble device and need write uint32_t via characteristic. When i try only (uint8_t)data[0] is correct.

How can I do writable characteristics (uint32_t)? Example please.

  • Hi Tom

    Thanks for your question

    You can only transmit bytes over BLE so you will need to convert the 32 bit variable to bytes, and then reassemble it on the peer device. Example:

    Define two variables

    static uint32_t variable_32 = 0x12345678;
    static uint8_t variable_8[4];
    

    put the value of the 32 bit variable into an array of 8 bit variable

    variable_8[0] = variable_32 >> 24;
    variable_8[1] = variable_32 >> 16;
    variable_8[2] = variable_32 >> 8;
    variable_8[3] = variable_32;
    

    Transmit the value over BLE e.g. with the NUS (Nordic UART Service) service

    ble_nus_string_send(&m_nus, &variable_8[0], 4);
    

    Update 26.10.2015 I tried to recreate your issue when writing 4 bytes from MCP to the device. I am not sure how you have set up your service, but I suspect some settings are incorrect, but I am not sure which ones. I have my test example working fine. I took the ble_app_bps and allowed writing on the battery characteristic with setting

    char_md.char_props.write  = 1;
    

    in the battery_level_char_add function. Then I remove security for the write property on the battery characteristic

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.write_perm);
    

    Then I set variable length on the characteristic

    attr_md.vlen       = 1;
    

    and set the maximum length to 20 bytes, you could also set it to 4.

    attr_char_value.max_len   = 20;
    

    Thats it ! I then test the incoming data with adding the following code to the on_write function in the ble_bas.c file

    if (p_evt_write->handle == p_bas->battery_level_handles.value_handle)     
    {
    	for(int i=0; i<p_evt_write->len; i++)
    	{
    		value[i] = p_evt_write->data[i];
    	}
    }
    

    and set a breakpoint after this code in order to stop the program and read the data from the debugger. Just remember to set optimization level to "level 0" in Options for target -> C/C++ tab. Now when I connect with MCP and send 12345678 hex I get exactly that data into the value array.

    Perhaps you can try the settings for the ble_app_bps example in the SDK 9.0.0 to see if you have something else set up differently, and then mimic my added settings in order to make it work as expected.

    Let me know what you find out.

  • Stefan it is other problem.

    I try create writable characteristic with 4 byte data len.

    My on_write ble event handler is:

    static void on_write(ble_dls_t * p_dls, ble_evt_t * p_ble_evt)
    {
        ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    		uint32_t temp_val = 0;
        
        if ((p_evt_write->handle == p_dls->dl_char_handles.value_handle) &&
            (p_evt_write->len == 4) &&
            (p_dls->dl_write_handler != NULL))
        {
    				p_dls->dl_write_handler(p_dls, p_evt_write);
        }
    		
    }
    

    and dl_write_handler is function:

    static void dl_timestamp_write_handler(ble_dls_t * p_dls, ble_gatts_evt_write_t * p_evt_write)
    {
    
    	volatile uint8_t value1 = ((p_evt_write->data[0]));
    	volatile uint8_t value2 = ((p_evt_write->data[1]));
    	volatile uint8_t value3 = ((p_evt_write->data[2]));
    	volatile uint8_t value4 = ((p_evt_write->data[3]));
    
    }
    

    in debuger when I write in Master Control Panel value 0x12345678:

    value1 = 0x78
    value2 = 0x78
    value3 = 0x78
    value4 = 0x78
    

    how can I resolv problem?

Related