Запись числа с плавающей запятой в характеристику 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), не имеет документации.

Спасибо!

, 👍2

Обсуждение

Попробуйте упаковать, а затем полностью распаковать значение в python в качестве теста. Попробуйте отправить упакованное значение из arduino обратно в него напрямую в качестве теста. Выясните, как сбросить байты упакованного значения в виде шестнадцатеричного значения из python для проверки и т. Д., @Chris Stratton


3 ответа


Лучший ответ:

1

Я мог бы решить эту проблему, еще раз просмотрев документацию по struct lib в python. Я тестировал различные методы упаковки и распаковки и задавался вопросом, откуда взялся [0] в моем коде (я откуда-то его скопировал). Итак, то, что я нашел работающим для моей установки, это просто:

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

Когда я отправлю это упакованное значение через BLE, Arduino его примет.

,

1

Мне пришло в голову два решения, если я собираюсь сделать то, что ты делаешь, 1) преобразовать число в строку char by char и отправить его как есть, затем распаковать его как char by char , например 5.3 -> "5.3" будет получено, тогда вам нужно разложить его на 5 и . и 3 (неэффективное решение из-за конвертации типов будет много)

2) вычислить количество десятичных цифр и отправить его с числом примерно так: 5.3 ---> 53 и одна десятичная точка, вы бы отправили это как 53:1, а затем распакуйте его и восстановите

второе решение было бы лучше для меня, так как я должен отправить его как 2 вещи число: десятичная точка а затем восстановить его, эта библиотека облегчит восстановление десятичной точки, отправленной 53: 1 (если вы хотите отправлять float в двух направлениях) SimpleSerialExtractor

,

0

Я использовал этот способ: определить дескриптор формата 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 устанавливает тип данных, см. здесь подробнее:

,