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

Higher precision in BLE_UUID_HEALTH_THERMOMETER_SERVICE

Hi,

I am trying to include temperature (read from DS18B20) in advertisement data using BLE_UUID_HEALTH_THERMOMETER_SERVICE. So far it works fine, but my temperature is multiplied by 10 (234 instead of 23.4). I use following code (inspired by examples I found), on nrf51822:

  uint32_t temperature_data = measure_temp_ds18b20();

  service_data[1].service_uuid = BLE_UUID_HEALTH_THERMOMETER_SERVICE;
  service_data[1].data.size    = sizeof(temperature_data);
  service_data[1].data.p_data  = (uint8_t *) &temperature_data;

Temperature is shown correctly (e.g. in nRF Temp app on android) but of course as 234, instead of 23.4. Is it possible to send this value as fractional?

greetings, Bartek

  • What type does measure_temp_ds18b20() return? If you are expecting a decimal i.e. 23.4 but you are storing it in uint32_t then thats a problem. Then looking at the code you provided you are storing the uint32_t into p_data in an array of uint8_t. So if you want a decimal reading maybe you need to read your measure_temp..() into a float or double or something and then store it to p_data as that type (if thats possible im not really sure). Otherwise maybe you keep it as sending in a uint32_t and just know how to interpret those raw bits on the other side of the BLE link.

  • Hi Michael, thanks for answer. My measurement function returns temperature multiplied by ten, but of course I know how to get 23.4f from 234. But I don't how to put this float into service_data[1].data (or how to put '234' but inform "client" that information is of factor 10x). I'm really new to this stuff so I would appreciate working example. As nrfTemp shows temperature with one digit precision (23.0) so I guess there is a way to send out this information in a way it is interpreted correctly by BLE client. Bartek

  • If you're using the health thermometer service then the data format is defined by the BT SIG, so if it says you send a 10 x integer, you have to send an scaled integer. In general you don't want to send floats because you don't want to deal with them on the BTLE chip which (unless you're nRF52) doesn't have built-in floating point and floats require more care to ensure what you send out (probably IEEE value, little endian) is received correctly the other end.

    You can add extra descriptors to a characteristic to say what format it's in so that a generic device can read it, that includes scaled integers, where you can define the power of 10 scaling.

    If this is your own service, just define that you'll send a x10 or x100 or x1000 integer and then process it appropriately in the app the other end.

  • All this stuff, thermometer profile, format stuff, ought to be on the BT SIG site, but they seem to have released a new one, broken all the links and removed all the useful information. There used to be great tables you could find which showed the mandated data format for all the characteristic types defined by the SIG, plus the description of al the format codes and everything else. Hopefully they'll fix this and put the information back because, surprisingly, the profile specs don't contain the information about data formats.

Related