I have a vendor specific characteristic for the battery voltage in my device, expressed as an actual voltage rather than a percentage. Values are 0.000V to about 4.300V and I need millivolt precision. My voltage variable is simply:
#include <float.h>
float m_battery_voltage;
The issue is that the value pointer on ble_gatts_attr_t
is to a uint8_t
:
typedef struct
{
ble_uuid_t* p_uuid;
ble_gatts_attr_md_t* p_attr_md;
uint16_t init_len;
uint16_t init_offs;
uint16_t max_len;
uint8_t* p_value;
} ble_gatts_attr_t;
I have tried to hack a float into this by assuming it's four bytes and just casting it like this:
attr_char_value.p_uuid = &char_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 = (uint8_t*)&m_battery_voltage;
and then doing the same sort of thing on the notify:
hvx_params.handle = p_bts->voltage_handles.value_handle;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
hvx_params.offset = 0;
hvx_params.p_len = &len;
hvx_params.p_data = (uint8_t*)&m_battery_voltage;
The value that shows up in the Master Control Panel looks like this (presumably in hex):
00 80 89 40
As for the Android app that's supposed to be reading the value, this results in a value of negative infinity:
Float voltageFloat = c.getFloatValue(BluetoothGattCharacteristic.FORMAT_FLOAT, 0);
There's also this I could try, but haven't yet:
Float voltageFloat = c.getFloatValue(BluetoothGattCharacteristic.FORMAT_SFLOAT, 0);
I'm aware that I can't simply treat a pointer to a float as if it's a pointer to a uint8_t
, but am at a loss as to what else I can do, given the type of ble_gatts_attr_t.p_value
.