Thiết bị USB HID chỉ bắn 1 sự kiện


10

Tôi có Bộ điều khiển từ xa USB eDIO (Bộ thu hồng ngoại) đi kèm với Điều khiển từ xa lướt web ASUS PSR 2000.

Tôi đang cố gắng kết nối Bộ điều khiển từ xa với số pi của mình để nó nhận được các tổ hợp phím được gửi từ xa.

Bộ điều khiển được phát hiện là một thiết bị HID. Dưới đây là chi tiết từ lệnh lsusb -v

    Bus 001 Device 007: ID 147a:e001 Formosa Industrial Computing, Inc.
    Couldn't open device, some information will be missing
    Device Descriptor:
    bLength                18
    bDescriptorType         1
    bcdUSB               1.10
    bDeviceClass            0 (Defined at Interface level)
   bDeviceSubClass         0
   bDeviceProtocol         0
   bMaxPacketSize0         8
   idVendor           0x147a Formosa Industrial Computing, Inc.
   idProduct          0xe001
   bcdDevice            1.22
   iManufacturer           1
   iProduct                2
   iSerial                 0
   bNumConfigurations      1
  Configuration Descriptor:
  bLength                 9
  bDescriptorType         2
wTotalLength           34
bNumInterfaces          1
bConfigurationValue     1
iConfiguration          4
bmAttributes         0xa0
  (Bus Powered)
  Remote Wakeup
MaxPower              300mA
Interface Descriptor:
  bLength                 9
  bDescriptorType         4
  bInterfaceNumber        0
  bAlternateSetting       0
  bNumEndpoints           1
  bInterfaceClass         3 Human Interface Device
  bInterfaceSubClass      1 Boot Interface Subclass
  bInterfaceProtocol      2 Mouse
  iInterface              0
    HID Device Descriptor:
      bLength                 9
      bDescriptorType        33
      bcdHID               1.10
      bCountryCode            0 Not supported
      bNumDescriptors         1
      bDescriptorType        34 Report
      wDescriptorLength      20
     Report Descriptors:
       ** UNAVAILABLE **
  Endpoint Descriptor:
    bLength                 7
    bDescriptorType         5
    bEndpointAddress     0x81  EP 1 IN
    bmAttributes            3
      Transfer Type            Interrupt
      Synch Type               None
      Usage Type               Data
    wMaxPacketSize     0x0004  1x 4 bytes
    bInterval              10

Tôi cũng có thể xem thiết bị đích trong thư mục dev với sự kiện được tạo

    pi@raspberrypi /dev/input/by-id $ dir
    usb-Cypress_Semiconductor_eDio_USB_Multi_Remote_Controlle-event-if00

Trình xử lý sự kiện liên quan đến nó như sau như được thấy từ lệnh sau.

pi@raspberrypi /proc/bus/input $ cat devices
I: Bus=0003 Vendor=147a Product=e001 Version=0110
N: Name="Cypress Semiconductor eDio USB Multi Remote Controlle"
P: Phys=usb-bcm2708_usb-1.2/input0
S: Sysfs=/devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2:1.0/input/input2
U: Uniq=
H: Handlers=event0
B: PROP=0
B: EV=1

Vấn đề là khi tôi đang cố đọc đầu ra từ trình xử lý sự kiện được tạo cho thiết bị. Tổ hợp phím đầu tiên được đăng ký nhưng các nét phím tiếp theo không được hiển thị bằng lệnh CAT.

 pi@raspberrypi /dev/input $ cat event0 | xxd
 0000000: e007 9450 9476 0900 0000 0000 0000 0000  ...P.v..........

Vui lòng gợi ý cho tôi những gì tôi có thể làm để thiết bị hoạt động. Nhấn bất kỳ phím nào sau lần nhấn phím đầu tiên sẽ không trả lại bất cứ thứ gì trừ khi thiết bị được cắm lại.

Vui lòng đề xuất những gì cần phải được thực hiện để khắc phục vấn đề.


Bất cứ ai cũng có thể ??? Tôi không biết chuyện gì đang xảy ra với thiết bị. Có lẽ một người điều hành có thể giúp tôi đóng khung câu hỏi tốt hơn nếu đó là một vấn đề ở đây?
SteveIrwin

Câu hỏi là tốt. Tuy nhiên, nó khá cục bộ, vì vậy tôi chắc chắn sẽ không có nhiều người gặp vấn đề tương tự. Nó có thể giúp bạn bình tĩnh khi biết rằng tôi đã thấy một thứ rất giống được sử dụng bởi chiếc thuyền biết nói của Chris Wallace để bạn có thể nhìn vào đó. Điều đầu tiên tôi sẽ hỏi để chẩn đoán vấn đề là; bạn đang sử dụng một trung tâm tự cấp nguồn, bởi vì nó có thể là một vấn đề năng lượng.
Jivings

Bạn đã thử mà không có |xxd? Nó đệm đầu ra. Tôi đã sử dụng irwtừ gói lircđể nhận mã khóa được gửi từ xa.
macrojames

trình điều khiển tùy chỉnh có nghĩa là một bản vá hạt nhân Linux. Tùy chọn dễ dàng hơn là sử dụng libusb vì libusb cho phép truy cập trực tiếp vào Điểm cuối USB.
Lars Pötter

Câu trả lời:


5

Vấn đề dường như là bộ giải mã USB chưa hoàn chỉnh:

  Couldn't open device, some information will be missing
  Report Descriptors:
  ** UNAVAILABLE **

Mô tả có thể được đọc nói rằng đây là Chuột.

  bInterfaceProtocol      2 Mouse

Và rằng sẽ có một Mô tả 20 byte mô tả định dạng dữ liệu:

  bDescriptorType        34 Report
  wDescriptorLength      20

Nhưng cái đó là mất tích.

Có một vấn đề lạ với sự kết hợp cụ thể của Phần cứng và Phần mềm hoặc Lập trình viên lười biếng và không triển khai Mô tả Báo cáo, vì Trình điều khiển riêng của họ có thể không cần đến nó. Nhưng hầu hết có lẽ điều đó khiến Driver tạo ra thiết bị đầu vào bị nhầm lẫn.

Bạn có thể thử sử dụng libusb để đọc 4 byte từ điểm cuối. Có lẽ công trình bỏ phiếu. Hoặc hãy xem giao tiếp USB khi bạn sử dụng thiết bị với trình điều khiển gốc. Và vâng, điều này rất khó khăn nếu bạn không có một trong những Bộ ghi USB đắt tiền được đặt xung quanh. Nhưng Linux Kernel có hỗ trợ Ghi nhật ký phần mềm USB và có một số Trình ghi nhật ký phần mềm cho Windows.


4

Cuối cùng tôi cũng có thời gian để viết bản triển khai của riêng mình bằng thư viện PyUSB, một trình bao bọc cho Libusb.

Tôi đang đăng mã ở đây. Giúp đỡ ai đó.

Tôi có một đoạn mã khác tạo tệp cấu hình được sử dụng ở đây. Không ánh xạ tất cả các khóa từ xa vì tôi không cần tất cả chúng.

import usb.core
import usb.util
import ConfigParser 
import shlex
import subprocess
import logging

# find our device
diction={
  6402315641282315:'1',
  6402415641282415:'2',
  6402515641282515:'3',
  6402615641282615:'4',
  6402715641282715:'5',
  6402815641282815:'6',
  6402915641282915:'7',
  6403015641283015:'8',
  6403115641283115:'9',
  }



def load_config():
    dict={}
    config = ConfigParser.RawConfigParser()
    config.read('/codes/remote/remote.cfg')

    dict['vendor']=config.getint('Settings','idVendor')

    dict['product']=config.getint('Settings','idProduct')

    dict['interface']=config.getint('Settings', 'interface')

    r=config.options('Key Mappings')

    for item in r:
        if config.get('Key Mappings',item)!='': 
            dict[item]=config.get('Key Mappings',item)
            #print config.get('Key Mappings',item)
    return dict

def pyus():

    try:
        load_log()
        dict=load_config()
        join_int = lambda nums: int(''.join(str(i) for i in nums))
        #print dict

        dev = usb.core.find(idVendor=dict['vendor'], idProduct=dict['product'])
        interface=dict['interface']

        if dev is None:
            raise ValueError('Device not found')

        if dev.is_kernel_driver_active(interface) is True:
                #print "but we need to detach kernel driver"
                dev.detach_kernel_driver(interface)
        #dev.detatch_kernel_driver(interface) 
        # set the active configuration. With no arguments, the first
        # configuration will be the active one
        dev.set_configuration()

        # get an endpoint instance
        cfg = dev.get_active_configuration()
        interface_number = cfg[(0,0)].bInterfaceNumber
        alternate_setting = usb.control.get_interface(dev,interface_number)
        intf = usb.util.find_descriptor(
            cfg, bInterfaceNumber = interface_number,
            bAlternateSetting = alternate_setting
        )

        ep = usb.util.find_descriptor(
            intf,
            # match the first IN endpoint
            custom_match = \
            lambda e: \
                usb.util.endpoint_direction(e.bEndpointAddress) == \
                usb.util.ENDPOINT_IN
        )

        assert ep is not None
        #print 'packet details',ep.bEndpointAddress , ep.wMaxPacketSize

        while 1:
            try:
                data = dev.read(ep.bEndpointAddress, ep.wMaxPacketSize*2,interface,1000)
                data=data.tolist()
                key=join_int(data)
                #print "Key is " , key
                if  key in diction:

                    try:
                        args=shlex.split(dict[diction[key]])
                        #print args
                        p=subprocess.Popen(args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
                        #print "Pressed key is ",diction[key]
                    except:
                        pass


            except usb.core.USBError as e:
                pass
    except:
        pass

pyus()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.