Pi Pico - USB HID Joystick 16 bit

Gast #7013683
Lesenswert?

Ich baue gerade an einem USB-Joystick auf Grundlage eines Pi Pico mit 
CircuitPython. Das ganze funktioniert mit mehreren Achsen und Buttons 
wie erwartet. Ich benötige für meine Achsen allerdings eine höhere 
Auflösung als 8 Bit.

Ich habe dafür den HID descriptor und den offiziellen Beispielcode in 
hid_gamepad.py (siehe 
https://github.com/adafruit/Adafruit_CircuitPython_HID/blob/main/examples/hid_gamepad.py) 
angepasst auf 16 Bit. Das Problem ist das nach wie vor Windows nur 8 Bit 
Werte akzeptiert obwohl ich 16 Bit pro Achse sende. D.h. alle Werte über 
127 ergeben einen vollen Ausschlag der Achse, nicht wie erwartet erst ab 
65535. Ich habe auch schon andere Wertebereiche für logical 
minimum/maximum probiert (-32767 to 32767, 0 to 32767, 0 to 65535) das 
ändert aber leider auch nichts.

Hat jemand eine Idee woran es liegen könnte? Offensichtlicher Fehler im 
Descriptor? Hat Windows etwas dagegen wenn das Gerät plötzlich einen 
neuen Descriptor liefert?
1
import usb_hid
2

3
# This is only one example of a gamepad descriptor, and may not suit your needs.
4
GAMEPAD_REPORT_DESCRIPTOR = bytes((
5
    0x05, 0x01,  # Usage Page (Generic Desktop Ctrls)
6
    0x09, 0x05,  # Usage (Game Pad)
7
    0xA1, 0x01,  # Collection (Application)
8
    0x85, 0x04,  #   Report ID (4)
9
    0x05, 0x09,  #   Usage Page (Button)
10
    0x19, 0x01,  #   Usage Minimum (Button 1)
11
    0x29, 0x10,  #   Usage Maximum (Button 16)
12
    0x15, 0x00,  #   Logical Minimum (0)
13
    0x25, 0x01,  #   Logical Maximum (1)
14
    0x75, 0x01,  #   Report Size (1)
15
    0x95, 0x10,  #   Report Count (16)
16
    0x81, 0x02,  #   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
17
    0x05, 0x01,  #   Usage Page (Generic Desktop Ctrls)
18
    #0x16, 0x01, 0x80,  #   Logical Minimum (0)
19
    #0x26, 0xff, 0x7f,  #   Logical Maximum (32767)
20
    
21
    0x15, 0x00,  #   Logical Minimum (0)
22
    0x27, 0xff, 0xff, 0x00, 0x00,  #   Logical Maximum (65535)
23
    
24
    0x35, 0x00,  #   Physical Minimum (0)
25
    0x47, 0xff, 0xff, 0x00, 0x00,  #   Physical Maximum (65535)  
26
    
27
    0x09, 0x30,  #   Usage (X)
28
    0x09, 0x31,  #   Usage (Y)
29
    0x09, 0x32,  #   Usage (Z)
30
    0x09, 0x35,  #   Usage (Rz)
31
    0x75, 0x10,  #   Report Size (16)
32
    0x95, 0x04,  #   Report Count (4)
33
    0x81, 0x02,  #   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
34
    0xC0,        # End Collection
35
))
36

37
gamepad = usb_hid.Device(
38
    report_descriptor=GAMEPAD_REPORT_DESCRIPTOR,
39
    usage_page=0x01,           # Generic Desktop Control
40
    usage=0x05,                # Gamepad
41
    report_ids=(4,),           # Descriptor uses report ID 4.
42
    in_report_lengths=(10,),   # This gamepad sends 10 bytes in its report.
43
    out_report_lengths=(0,),   # It does not receive any reports.
44
)
45

46
usb_hid.enable(
47
    (gamepad,)
48
)
Angehängte Dateien:
Gast #7014451
Lesenswert?

Thomas Z. schrieb:
> ansi90 schrieb:
>> 0x27, 0xff, 0xff, 0x00, 0x00,  #   Logical Maximum (65535)
>
> das ist Käse:
> -> 0x20 | 0x04 | 3 -> 3 Bytes du sendest aber 4 bytes.
>

Was wäre in dem Fall dann der korrekte Wert?

Ich habe ich das ganze mal anhand von Lufa 
(https://github.com/abcminiuser/lufa/blob/cfbbbb4ac0c6d85be67009143b1acfc8968bef91/LUFA/Drivers/USB/Class/Common/HIDReportData.h) 
und den offiziellen Standards nachvollzogen. Mit meinen Werten komme ich 
auf 0x27 für mein Beispiel:

Berechnung anhand von Lufa:
1
0x04 = type
2
0x20 = tag
3
0x03 = 32 data bits (also 4 byte bezogen auf Grenzwert im Descriptor, nicht die Joystickdaten)
4

5
=> 0x04 | 0x20 | 0x03 = 0x27

Berechnung anhand von usb.org:
1
Part Description
2
bSize Numeric expression specifying size of data:
3
0 = 0 bytes
4
1 = 1 byte
5
2 = 2 bytes
6
3 = 4 bytes
siehe https://www.usb.org/sites/default/files/hid1_11.pdf Seite 36
1
Logical Maximum 0010 01 nn Extent value in logical units. This is the
2
maximum value that a variable or array item will
3
report.
siehe https://www.usb.org/sites/default/files/hid1_11.pdf Seite 45
1
=> 0010 01 nn | 0x03 = 0x24 | 0x03 = 0x27

> Übrigens sind schon 8 Bit mit den üblichen Potis wegen des begrenzten
> Drehwinkels nur schwer zu erreichen. 16 Bit ist einfach unmöglich

Das ist mir bewusst. Deswegen kommt auch kein Poti zum Einsatz sondern 
hochauflösende Encoder. Am Ende werde ich im Bereich 12 bis 14 Bit 
Auflösung, nicht Genauigkeit, landen.
Gast #7024360
Lesenswert?

Nach langem hin und her hat sich herausgestellt, dass das Problem nicht 
der Descriptor war sondern Windows. Windows kam nicht damit klar dass 
sich das Gerät verändert hat. Nach einem Reset des Controllers auf 
Standardwerte ging direkt alles.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren