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

Best way to send float over BLE

What is the Best way to send float over BLE?

Values range between -2.000volt and +2.000Volt (-2000mV / +2000mV) Do I break it into two uint8_t and manipulate the +/- sign in separate 8-bit byte?

I took the ble_sdk_app_proximity example, and commented out what I do not need. Then used the examples from the tutorials, to add three services. So I added x3 services, based on the BLE Characteristics, a beginner's tutorial, and it is working fine. (nrf5-ble-tutorial-characteristic-CompletedCode ported for SDK 13.zip)

So I need to send the Voltage either as a float, or manipulate it to look like uint8_t, and keep track of the sign.

Any help appreciated.

Parents
  • You can use this function that encodes a float (32 bits) into a uint8_t buffer

    bds_float_encode(&float_data, encoded_buffer)
    

    A float after all is just 4 bytes of data.

    The definition of the function is in this file

    ./sdk/components/libraries/util/app_util_bds.h
    
    static __INLINE uint8_t bds_float_encode(const float_t * p_value, uint8_t * p_encoded_data){
    union { 
        float float_val;
        uint8_t char_val[4];
    }encoder;
    
    encoder.float_val = *p_value;
    p_encoded_data[0] = encoder.char_val[0];
    p_encoded_data[1] = encoder.char_val[1];
    p_encoded_data[2] = encoder.char_val[2];
    p_encoded_data[3] = encoder.char_val[3];
    return(4);}
    

    .

  • I'm quite surprised that IAR doesn't know what a union is. Here is a link on IAR that uses union endianness

    This is a IEEE 32b float. You just need to make sure the float get correctly re-assembled on the other side.

    float gsr = bytesToFloat(characteristic.getValue()[1],
                                     characteristic.getValue()[2],
                                     characteristic.getValue()[3],
                                     characteristic.getValue()[4]);
    
    private float bytesToFloat(byte b0, byte b1, byte b2, byte b3) {
        int asInt = (b0 & 0xFF)
                |  ((b1 & 0xFF) << 8)
                |  ((b2 & 0xFF) << 16)
                |  ((b3 & 0xFF) << 24);
        return  Float.intBitsToFloat(asInt);
    }
    
Reply
  • I'm quite surprised that IAR doesn't know what a union is. Here is a link on IAR that uses union endianness

    This is a IEEE 32b float. You just need to make sure the float get correctly re-assembled on the other side.

    float gsr = bytesToFloat(characteristic.getValue()[1],
                                     characteristic.getValue()[2],
                                     characteristic.getValue()[3],
                                     characteristic.getValue()[4]);
    
    private float bytesToFloat(byte b0, byte b1, byte b2, byte b3) {
        int asInt = (b0 & 0xFF)
                |  ((b1 & 0xFF) << 8)
                |  ((b2 & 0xFF) << 16)
                |  ((b3 & 0xFF) << 24);
        return  Float.intBitsToFloat(asInt);
    }
    
Children
No Data
Related