Как Mimi c nRF Connect (для Android) действий с Pygatt Script? - PullRequest
1 голос
/ 26 января 2020

Я использую nRF Connect для Android, чтобы проверить BLE-периферию. Периферийным устройством является монитор остаточного мышечного кислорода BSX Insight, программное приложение которого больше не работает или не поддерживается производителем. Таким образом, моя единственная возможность использовать мое устройство (BSX) - написать собственное управляющее программное обеспечение. Я написал Python 3.7 скрипт, который я запускаю в подпрограмме tkinter на моем 64-битном ноутбуке Win 10. Кроме того, я использую библиотеку Pygatt и ключ BT BLED112.

Я могу подключаться к периферии, считывать и записывать значения в соответствии с характеристиками, но я уверен, что «преобразование» из процесса Используется в nRF Connect и мой сценарий является неполным и неэффективным. Итак, первое, что я хотел бы подтвердить, это то, что используются правильные соответствующие функции из Pygatt. Как только я использую правильные функции из Pygatt, я могу сравнить соответствующие выходные данные для двух потоков данных (характеристики c значения), которые я хочу захватить и сохранить.

Базовый процесс c в nRF Connect:
1. Сканирование
2. Выберите / подключите BSX Insight
3. Предоставьте интересующие услуги и характеристики
4. enable CCCDs
5. записать значения «стартовых данных» (04-02)

Это результаты команды процесса из файла журнала nRF Connect. Начиная с номера четыре:
4.
D 09: 04: 54,491 gatt.setCharacteristicNotification (00002a37-0000-1000-8000-00805f9b34fb, true) 11
D 09: 04: 54.496 gatt.setCharacteristicNotification (2e4ee00b -d9f0-5490-ff4b-d17374c433ef, правда) 20x
D 09: 04: 54.499 gatt.setХарактеристика уведомления (2e4ee00d-d9f0-5490-ff4b-d17374c433ef, правда) 25x
D: 16,5-й класс: (2e4ee00e-d9f0-5490-ff4b-d17374c433ef, true) 32x
D 09: 04: 54.519 gatt.setCharacteristicNotification (00002a63-0000-1000-8000-00805f9b34fb, true) 36
D 09: 04: 54,523 г .setCharacteristicNotification (00002a53-0000-1000-8000-00805f9b34fb, true) 40

Вышеуказанное явилось результатом использования команды nRF «Включить CCCD». В основном, все характеристики c, которые могли быть включены, были включены, что нормально. «Х» - это три, которые мне нужно включить. Другие являются дополнительными. Обратите внимание, я прокомментировал соответствующие дескрипторы для этих UUID в конце строки.

V 09: 05: 39.211 Запись команды в характеристики c 2e4ee00a-d9f0-5490-ff4b-d17374c433ef
D 09: 05: 39.211 gatt.writeCharacteristi c (2e4ee00a-d9f04433 d17f4-433-f1737 f37 , значение = 0x0402)
I 09: 05: 39.214 Данные, записанные в 2e4ee00a-d9f0-5490-ff4b-d17374c433ef, значение: (0x) 04-02
A 09: 05: 39.214 "(0x) 04- 02 "отправлено

Номер пять - это то, где я пишу 0402 в UUID выше. Это действие отправляет потоки данных / значений из:

  • 2e4ee00d-d9f0-5490-ff4b-d17374c433ef с дескриптором дескриптора 26
  • 2e4ee00e-d9f0-5490-ff4b-d17374c433ef, с дескриптором дескриптора 33

После того, как я выполнил основные шаги c, описанные выше в nRF Connect, активируются два потока значений c, и я могу сразу увидеть преобразованные значения в мое головное устройство Garmin Edge 810.

Итак, попытка дублировать тот же процесс в моем фрагменте tkinter:

# this function fires from the 'On' button click event
def powerON():
    powerON_buttonevent = 1
    print(f"\tpowerON_buttonevent OK {powerON_buttonevent}")

    # Connect to the BSX Insight
    try:
        adapter = pygatt.BGAPIBackend()       # serial_port='COM3'
        adapter.start()
        device = adapter.connect('0C:EF:AF:81:0B:76', address_type=pygatt.BLEAddressType.public)
        print(f"\tConnected: {device}")
    except:
        print(f"BSX Insight connection failure")
    finally:
        # adapter.stop()
        pass

    # Enable only these CCCDs
    try:
        device.char_write_handle(21, bytearray([0x01, 0x00]), wait_for_response=True)
        device.char_write_handle(26, bytearray([0x01, 0x00]), wait_for_response=True)
        device.char_write_handle(33, bytearray([0x01, 0x00]), wait_for_response=True)

        print(f"\te00b DESC: {device.char_read_long_handle(21)}")       # notifiy e00b
        print(f"\te00d DESC: {device.char_read_long_handle(26)}")       # notify e00d SmO2
        print(f"\te00e DESC: {device.char_read_long_handle(33)}")       # notify e00e tHb

        # Here's where I tested functions from Pygatt...
        # print(f"\t{device.get_handle('UUID_here')}")     # function works
        # print(f"\tvalue_handle/characteristic_config_handle:            {device._notification_handles('UUID_here')}")       # function works
        # print(f"{device.char_read('UUID_here')}")
        # print(f"{device.char_read_long_handle(handle_here)}")        # function works
    except:
        print(f"CCCD write value failure")
    finally:
        # adapter.stop()
        pass

    # Enable the data streams
    try:
        device.char_write('2e4ee00a-d9f0-5490-ff4b-d17374c433ef', bytearray([0x04, 0x02]), wait_for_response=True)    # function works
        print(f"\te00a Power ON: {device.char_read('2e4ee00e-d9f0-5490-ff4b-d17374c433ef')}")
    except:
        print(f"e00a Power ON write failure")
    finally:
        # adapter.stop()
        pass

    # Subscribe to SmO2 and tHb UUIDs
    try:
        def data_handler(handle, value):
            """
            Indication and notification come asynchronously, we use this function to
            handle them either one at the time as they come.
            :param handle:
            :param value:
            :return:
            """
            if handle == 25:
                print(f"\tSmO2: {value} Handle: {handle}")
            elif handle == 32:
                print(f"\ttHb: {value} Handle: {handle}")
            else:
                print(f"\tvalue: {value}, handle: {handle}")

        device.subscribe("2e4ee00d-d9f0-5490-ff4b-d17374c433ef", callback=data_handler, indication=False, wait_for_response=True)
        device.subscribe("2e4ee00e-d9f0-5490-ff4b-d17374c433ef", callback=data_handler, indication=False, wait_for_response=True)
        print(f"\tSuccess 2e4ee00d: {device.char_read('2e4ee00d-d9f0-5490-ff4b-d17374c433ef')}")
        print(f"\tSuccess 2e4ee00e: {device.char_read('2e4ee00e-d9f0-5490-ff4b-d17374c433ef')}")

        # this statement causes a run-on continuity when enabled
        # while True:
        #     sleep(1)

    except:
        print("e00d/e00e subscribe failure")
    finally:
        adapter.stop()
        # pass  

Проблема: в окне вывода моего редактора Atom запускаются два потока данных как и ожидалось. Например:

I 09: 05: 39.983 Уведомление получено от 2e4ee00d-d9f0-5490-ff4b-d17374c433ef, значение: (0x) 00-00-00-00-C0-FF-00-00-C0 -FF-84-65-B4-3B-9E-AB-83-3 C -FF-03

и ...

I 09: 05: 39.984 Уведомление получено от 2e4ee00e-d9f0-5490-ff4b-d17374c433ef, значение: (0x) 1 C -00-00-FF-03-FF-0F-63-00-00-00-00-00-00-16-32- 00-00-00-00

Я посмотрю от семи до десяти строк данных, прежде чем «поток» остановится. Там будет промежуток около 20 секунд, а затем большой дамп значений. Это отличается от вывода nRF Connect, который является немедленным и непрерывным.

У меня есть журналы от nRF Connect и Python ... но я не уверен, какая запись журнала указывает на причину остановки. Может ли эта проблема быть связана с параметрами периферийного предпочтительного соединения? Свойство nRF Connect показывает следующее:

  • ConnectionInterval = 50 мс ~ 100 мс
  • SlaveLatency = 1
  • SuperTimeoutMonitor = 200

The Python запись в журнале показывает это:

ИНФОРМАЦИЯ: pygatt.backends.bgapi.bgapi: Состояние соединения: handle = 0x0, flags = 5, address = 0xb'760b81afef0 c ', интервал подключения = 75.000000ms, тайм-аут = 1000, задержка = 0 интервалов, соединение = 0xff

Кто-нибудь думает? (И действительно, заранее спасибо.)

1 Ответ

0 голосов
/ 29 января 2020

Я ответил на мои вопросы. Теперь мне нужно решить новую проблему того, почему мой диалог tKinter «не отвечает», как отдельную проблему. Спасибо, все отредактировали 31.03.2020: я переписал скрипт, используя pyQt, и теперь у меня есть функциональное приложение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...