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

Ways of sending a Float array as a value of a characteristic

want to send a float as a value of a characteristic

I have successfully achieved this using the simple way

Below is the example of just two float variables in an array.

float temperature[2]=  {1.1,2.2}; 

attr_char_value.init_len  = 8;
attr_char_value.init_offs = 0;
attr_char_value.max_len   = 8;
attr_char_value.p_value   = (uint8_t*)&temperature;

And this works fine, in the future I want to be able to send180 variables so i will need to change

attr_char_value.max_len   = 180;

While reading up upon Heart monitor and Blood pressure monitoring services, they use this method:

static uint8_t hts_measurement_encode(ble_hts_t      * p_hts,
                                      ble_hts_meas_t * p_hts_meas,
                                      uint8_t        * p_encoded_buffer)
{
    uint8_t  flags = 0;
    uint8_t  len   = 1;
    uint32_t encoded_temp;

    // Flags field
    if (p_hts_meas->temp_in_fahr_units)
    {
        flags |= HTS_MEAS_FLAG_TEMP_UNITS_BIT;
    }
    if (p_hts_meas->time_stamp_present)
    {
        flags |= HTS_MEAS_FLAG_TIME_STAMP_BIT;
    }

    // Temperature Measurement Value field
    if (p_hts_meas->temp_in_fahr_units)
    {
        flags |= HTS_MEAS_FLAG_TEMP_UNITS_BIT;

        encoded_temp = ((p_hts_meas->temp_in_fahr.exponent << 24) & 0xFF000000) |
                       ((p_hts_meas->temp_in_fahr.mantissa <<  0) & 0x00FFFFFF);
    }
    else
    {
        encoded_temp = ((p_hts_meas->temp_in_celcius.exponent << 24) & 0xFF000000) |
                       ((p_hts_meas->temp_in_celcius.mantissa <<  0) & 0x00FFFFFF);
    }
    len += uint32_encode(encoded_temp, &p_encoded_buffer[len]);

    // Time Stamp field
    if (p_hts_meas->time_stamp_present)
    {
        flags |= HTS_MEAS_FLAG_TIME_STAMP_BIT;
        len   += ble_date_time_encode(&p_hts_meas->time_stamp, &p_encoded_buffer[len]);
    }

    // Temperature Type field
    if (p_hts_meas->temp_type_present)
    {
        flags                  |= HTS_MEAS_FLAG_TEMP_TYPE_BIT;
        p_encoded_buffer[len++] = p_hts_meas->temp_type;
    }

    // Flags field
    p_encoded_buffer[0] = flags;

    return len;
}

This code uses a struct called

    typedef struct
{
  int8_t  exponent;                                                         /**< Base 10 exponent */
  int32_t mantissa;                                                         /**< Mantissa, should be using only 24 bits */
} ieee_float32_t;

So my question is, is this another way or better way of sending a float variable?? I don't understand what they are doing here as almost every NRF ble example uses this method.

Parents
  • Hi Nicko,

    In our example we have to do with IEEE-11073 float (with 24 bit mantissa and 8 bit exponent) because it's defined in the spec as in here.

    If you are fine with C float, you can simply convert it to 4 bytes like what you are doing now. Note that each float requires 4 bytes, if you have 180 values, you would need 720 bytes. This may exceed the max size of characteristic we support now. I would suggest you to send them in 20 bytes trunk, so you keep the characteristic size at 20 bytes, and send the result with 36 notification packets.

  • You mean you can send more than 20 bytes via notification ? It could be that the phone actually support long ATT MTU. With Bluetooth 4.2 the ATT MTU can get upto 512 bytes instead of 23 bytes as before. The longest notification can send is ATT MTU -3. That's why I said it was 20 bytes. We need to see the sniffer trace to check if actually long ATT MTU is used.

    It's pretty new features, we only supported that from S132 v3.x

Reply
  • You mean you can send more than 20 bytes via notification ? It could be that the phone actually support long ATT MTU. With Bluetooth 4.2 the ATT MTU can get upto 512 bytes instead of 23 bytes as before. The longest notification can send is ATT MTU -3. That's why I said it was 20 bytes. We need to see the sniffer trace to check if actually long ATT MTU is used.

    It's pretty new features, we only supported that from S132 v3.x

Children
No Data
Related