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

Offset while sending data

I have a project which will send the temperature from the nRF51DK to host.

The value of the temperature is an integer. As example Value:0x00000A2B -> 2603 ->26.03°C

But on the Host side I will recieve only Value:2B

The same if I change the length of the Bytes to 4

nRF51DK Value is 0x00002710, but on the host side I will recieve Value:10-00-00-00

Here the set up for the characteristic(with 4Bytes):

attr_char_value.p_uuid       = &ble_uuid;
attr_char_value.p_attr_md    = &attr_md;
attr_char_value.init_len     = 4;
attr_char_value.init_offs    = 0;
attr_char_value.max_len      = 4;
attr_char_value.p_value      = NULL;

uint32_t ble_fridge_send_temp(ble_fridge_t * p_fridge, uint8_t temp_value)
{
uint32_t err_code = NRF_SUCCESS;									
ble_gatts_value_t gatts_value;										

if(temp_value != p_fridge->temp_value_last)				
{
	memset(&gatts_value,0,sizeof(gatts_value));			
	
	
	gatts_value.len 	= 4;					
	gatts_value.offset	= 0;												
	gatts_value.p_value	= &temp_value;							
	
	p_fridge->temp_value_last = temp_value;					

	err_code = sd_ble_gatts_value_set(p_fridge->conn_handle,p_fridge->temp_char_handles.value_handle,&gatts_value);
	if(err_code != NRF_SUCCESS)
	{
		return err_code;
	}
}

Why is there an offset?

Or isnt a offset? Maybe the Byte order is false?

Parents Reply Children
  • No you don't need to do that. An int32_t is 4 consecutive bytes in memory, just like a uint8_t array. He just needs to get it all the way to the function without truncation which specifying the parameter as uint8_t does.

    At the other end it needs to be turned back into an uint32_t but that's easy, if the endienness of the host is the same you can just read it right out of the buffer, else you flip the bytes around.

    Or, if you remember your old Unix networking code you call

    htonl( value to send )
    

    on the value before you send it, as a uint32_t and then

    ntohl( value received )
    

    on the value (as a uint32_t) after you receive it. That works on any and every platform because it's guaranteed to turn the value into network order on the way out and back to host order on the way back.

  • @RK Your solution would be to define temp_value as uint32_t?

  • Yes - in that function header. I'm assuming it's already a uint32_t when you send it over to the function, declaring it as uint8_t there truncates it into just the last byte. But check the place you call the function too.

    You'll see it come in in the master control panel 'backwards', ie lowest byte first. That's ok depending on what you are going to use to read it the other end, you either just read the bytes as they are or you flip them around. Worry about that when you get them all sent over properly.

    Pretty sure at this point you have this probem

    uint32_t fridge_temperature = ...; 
    ble_fridge_send_temp( fridge, fridge_temperature );
    

    but fridge_temperature starts as 0x00002710, then gets truncated to 0x10, the final byte. But all those variables are still 32 bits long internally, so you get zeros.

  • If I define temp_value as uint32_t will get an error:

    gatts_value.p_value = &temp_value;

    Because p_value is an uint8_t and temp_value is an uint32_t

  • And p_value is defined in ble_gatts.h file. This file cannot be edited...

Related