Запись числа с плавающей запятой в характеристику BLE. Какой формат данных?
В настоящее время я работаю над клиентом Bluetooth с низким энергопотреблением на основе Python для OS X, и я застрял, пытаясь записать удаленное значение характеристики с плавающей запятой.
Прежде всего: моя установка — это Arduino 101 со встроенным модулем BLE и Macbook. На стороне Arduino код работает хорошо, я могу читать и записывать характеристики BLE из приложения BLE Explorer на своем телефоне.
Также мне удалось прочитать плавающие значения характеристик в моем скрипте Python на Macbook. При этом я не совсем понимал, что именно я делаю. После запроса значения характеристики от периферийного устройства, периферийное устройство отвечает, и я получаю то, что, как мне кажется, является двоичными данными? Мне удалось распаковать данные в число с плавающей запятой с помощью.
def characteristic_to_float(data):
float_value = struct.unpack('f', data)[0]
return float_value
Полученные числа с плавающей запятой верны. Но я не мог заставить свой код Python правильно записывать значение с плавающей запятой на периферийное устройство. Я пробовал это:
a_number = 5.3 def float_to_characteristic (float_value): val = struct.pack('<f', float_value)[0] возвращаемое значение характеристика_1.write_value (плавающая_в_характеристика(a_number))
Сам код Python будет выполнен без ошибок, но Arduino не получит данные. Я уверен в этом, потому что я реализовал на нем функцию, которая отправляет Serial print, когда характеристика записана.
Помните, что характеристики читаются & напишите, и я мог бы проверить это с помощью моего телефона. Я думаю, что у меня что-то не так с struct.pack, так как я не могу найти информацию о том, какой формат данных необходим...
Кто-нибудь знает, как я могу упаковать или преобразовать число с плавающей запятой в правильный формат данных? К сожалению, библиотека, которую я использую (Adafruit BluefruitLE), не имеет документации.
Спасибо!
@ArduStack, 👍2
Обсуждение3 ответа
Лучший ответ:
Я мог бы решить эту проблему, еще раз просмотрев документацию по struct lib в python. Я тестировал различные методы упаковки и распаковки и задавался вопросом, откуда взялся [0] в моем коде (я откуда-то его скопировал). Итак, то, что я нашел работающим для моей установки, это просто:
def float_to_characteristic(float_value):
val=struct.pack('<f',float_value)
return val
Когда я отправлю это упакованное значение через BLE, Arduino его примет.
Мне пришло в голову два решения, если я собираюсь сделать то, что ты делаешь, 1) преобразовать число в строку char by char и отправить его как есть, затем распаковать его как char by char , например 5.3 -> "5.3" будет получено, тогда вам нужно разложить его на 5 и . и 3 (неэффективное решение из-за конвертации типов будет много)
2) вычислить количество десятичных цифр и отправить его с числом примерно так: 5.3 ---> 53 и одна десятичная точка, вы бы отправили это как 53:1, а затем распакуйте его и восстановите
второе решение было бы лучше для меня, так как я должен отправить его как 2 вещи число: десятичная точка а затем восстановить его, эта библиотека облегчит восстановление десятичной точки, отправленной 53: 1 (если вы хотите отправлять float в двух направлениях) SimpleSerialExtractor
Я использовал этот способ: определить дескриптор формата BLE (0x2904) Прикрепить дескриптор к характеристике
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; // должна оставаться допустимая память для ArduinoBLE
desc1.m_format = 0x14; // плавать
desc1.m_exponent = 0x0;
desc1.m_unit = 0x2728; // Напряжение
desc1.m_namespace = 1;
desc1.m_description = 0x10f;
BLEDescriptor voltageLabelDescriptor("2904", (uint8_t*)&desc1, sizeof(desc1));
batteryLevelCharacteristic.addDescriptor(voltageLabelDescriptor);
Дескриптор 2904 устанавливает тип данных, см. здесь подробнее:
- Подключение нескольких модулей HC-05 к одной компьютерной системе
- Программирование Arduino с использованием Python, а не C/C ++
- Как получить тип данных переменной?
- Преобразование в Unix Timestamp и обратно
- Не удается связаться с ардуино с помощью python (Windows)
- Можно ли измерить скорость акселерометром? Насколько точно?
- Arduino Pro Micro, получить данные с контакта Tx?
- Хочу создать Bluetooth audio control (увеличение/уменьшение громкости, воспроизведение, пауза и т.д.) для смартфона
Попробуйте упаковать, а затем полностью распаковать значение в python в качестве теста. Попробуйте отправить упакованное значение из arduino обратно в него напрямую в качестве теста. Выясните, как сбросить байты упакованного значения в виде шестнадцатеричного значения из python для проверки и т. Д., @Chris Stratton