2

I am currently working on a python-based Bluetooth Low Energy client for OS X and I got stuck while trying to write a remote float characteristic value.

First of all: my setup is an Arduino 101 with integrated BLE module and a Macbook. On the Arduino side the code is working well, I can read and write BLE characteristic's from a BLE explorer app on my phone.

Also I did achieve to read out the characteristics float values in my python script on the Macbook. Yet I did not fully understand what exactly I am doing. After requesting the characteristic's value from the peripheral, the peripheral answers and I get what I think is binary data? I could manage to unpack the data to a float by using.

 def characteristic_to_float(data):
 float_value = struct.unpack('f', data)[0]
 return float_value

The received floats are correct. But I couldn't get my python code to properly write a float value to the peripheral. I tried this:

 a_number = 5.3
 def float_to_characteristic(float_value):
 val = struct.pack('<f', float_value)[0]
 return val
 characteristic_1.write_value(float_to_characteristic(a_number))

The python code itself will run through without an error, but the Arduino doesn't receive the data. I am sure of that, because I implemented a function on it that sends out a Serial print when a characteristic has been written.

Remember the characteristics are read & write and I could verify this by using my phone. I think I got something wrong with the struct.pack thing, since I can't find any information about what data format is needed...

Does someone know how I can pack or convert the float to the right data format? Unfortunately the lib I use (Adafruit BluefruitLE) does not have a documentation.

Thanks!

asked Oct 24, 2016 at 19:31
1
  • Try packing and then unpacking the value entirely in python as a test. Try sending the packed value from the arduino back to it directly as a test. Figure out how to dump the bytes of the packed value as hex from python for verification, etc... Commented Oct 24, 2016 at 19:35

3 Answers 3

1

Two solutions came to my mind if am gonna do your thing, 1) convert the number to a string char by char and send it as it is then unpack it as char by char , for example 5.3 --> "5.3" it will be received then you have to decompose it 5 and . and 3 (inefficient solution because of conversion of types will be alot)

2) calculate the number of decimal digits and send it with the number something like: 5.3 ---> 53 and one decimal point, you would send it as 53:1 and then unpack it and reconstruct it

the second solution would be better for me since i have to send it as 2 things number: decimal point and then reconstruct it, this library will ease the reconstruction of decimal point sent by 53:1 (if you want to send floats in two directions) SimpleSerialExtractor

answered Oct 24, 2016 at 19:52
1

I could solve the issue by taking another look in the documentation of the struct lib in python. I tested different pack and unpack methods and wondered where the [0] in my code came from (I did copy it from somewhere). So what I found working for my setup simply is:

def float_to_characteristic(float_value):
 val=struct.pack('<f',float_value)
 return val 

When I send this packed value through BLE the Arduino will accept it.

answered Oct 25, 2016 at 8:13
0

I used this way: define a BLE format descriptor (0x2904) Attach the descriptor to the characteristic

struct BLE2904_Data {
 uint8_t m_format;
 int8_t m_exponent;
 uint16_t m_unit;
 uint8_t m_namespace;
 uint16_t m_description;
} __attribute__((packed));
struct BLE2904_Data desc1; // must remain valid memory for ArduinoBLE
 desc1.m_format = 0x14; // float
 desc1.m_exponent = 0x0;
 desc1.m_unit = 0x2728; // voltage
 desc1.m_namespace = 1;
 desc1.m_description = 0x10f;
 BLEDescriptor voltageLabelDescriptor("2904", (uint8_t*)&desc1, sizeof(desc1));
 batteryLevelCharacteristic.addDescriptor(voltageLabelDescriptor); 

The 2904 descriptor sets the data type see here for more details:

answered Apr 29, 2023 at 21:27

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.