python - pyusb - как прочитать поток данных по нажатию кнопки - PullRequest
0 голосов
/ 31 января 2019

У меня есть сенсорный экран и датчик силы, подключенные к моему компьютеру через один и тот же USB-поток (разные интерфейсы).Я использую pyUSB для взаимодействия с предоставленными данными (меня интересует конечная точка IN 3-го интерфейса устройства).

До сих пор мне удавалось считывать данные в массив и печатать значение силы (data [3]) непрерывно (с циклом while True).

Теперь яЯ хочу прочитать это значение, только когда я нажимаю кнопку в приложении с графическим интерфейсом (запрограммировано в PyQt5).

Мне удалось прочитать значение силы при нажатии кнопки, но это значение не соответствует действительности: когдаКогда я нажимаю кнопку, на экране я прикладываю усилие ~ 30, значение читается как ~ 1.Когда я нажимаю второй раз на кнопку, применяя другое усилие (неважно, сколько), читаемое значение равно ~ 30.

Я пытался прочитать кучу данных (20) каждый раз, когданажата кнопка, и результат немного отличается, хотя и не удовлетворяет ни одному: когда я нажимаю на кнопку с силой, отображаемые 20 значений меняются в соответствии с примененной силой.Но при следующем нажатии кнопки, даже если никакая сила не применяется, первое значение примерно равно последнему значению предыдущего набора данных, а остальные 19 значений являются связными.Ниже приведен скриншот из двух сгустков данных: первый с приложенной силой, а второй без силы:

2 bunches of data

Вот код IЯ использую:

main.py

import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import QObject, pyqtSignal

import usb.core
import usb.util

if __name__ == "__main__":
    app = QApplication(sys.argv)
    engine = QQmlApplicationEngine()
    engine.load('main.qml')
    win = engine.rootObjects()[0]
    win.show()    

    #---------------connect to device
    dev = usb.core.find(idVendor=0x03eb, idProduct=0x2f04)
    if dev is None:
        print("Error")
        raise ValueError('Device not found')
    else:
        print("No error")

    dev.reset()


    #When you connect the device to Linux, Linux automatically sets some drivers to it. In order for this script to work, we must first detach the driver
    if dev.is_kernel_driver_active(0) == True:
        dev.detach_kernel_driver(0)
        print("true")
    else:
        print("false")

    endpoint3 = dev[0][(2,0)][0]

    interface = 2
    if dev.is_kernel_driver_active(interface) is True:
        #tell the kernel to detach
        dev.detach_kernel_driver(interface)
        #claim the device

    def twos_comp(val, bits):
        if (val & (1 << (bits - 1))) != 0:
            val = val - (1 << bits)
        return val

    def on_button_pressed():
        for x in range(0, 20):
            try:
                data = dev.read(endpoint3.bEndpointAddress, endpoint3.wMaxPacketSize)
            except usb.core.USBError as e:
                data = None
                print("error")
            except KeyboardInterrupt:
                print ("Bye")
                sys.exit()

            print(twos_comp(data[3] + (data[4] << 8), 16), ", ", data[1])
            #data[3] + (data[4] << 8) is the force value
            data = []
        print("\n")

    button = win.findChild(QObject, "myButton")
    button.messageRequired.connect(on_button_pressed)

    #---------------prepare to close...
    ret = app.exec_()

    usb.util.release_interface(dev, interface)
    dev.attach_kernel_driver(interface)

    print("end")

    sys.exit(ret)

main.qml

import QtQuick 2.9
import QtQuick.Window 2.11
import QtGraphicalEffects 1.0
import QtQuick.Controls 2.4

Window {
    visible: true
    width: 1100
    height: 650
    title: qsTr("Tutorial 1")

    Button {
        signal messageRequired
        signal messageClick
        signal messageRelease
        autoRepeat: true
        objectName: "myButton"
        anchors.top: parent.top
        width: parent.width
        height: parent.height / 2 - 100
        anchors.margins: 20
        text: "Read force"
        onPressed: messageRequired()
    }
}

Я работаю в Linux и Windows 10, и проблема еще хуже в Windows.

Чего мне не хватает?Я читал о конечных точках, USB и pyUSB и рассказывал о каждом SO посте, чтобы попытаться понять, что происходит, но безуспешно ... Моя идея в том, что где-то есть буфер (возможно, отслеживается ОС)который не сбрасывается вовремя или не читается в соответствующее время.Но я ничего не нашел об этом в Интернете ...

PS: Я попробовал это на C ++ напрямую с libusb, но результаты те же.Я думаю, что это проблема буфера, который не был очищен, но не знаю, какой, как получить к нему доступ и как его очистить ...

...