Forum: Mikrocontroller und Digitale Elektronik Pi Pico - USB HID Joystick 16 bit


von ansi90 (Gast)


Angehängte Dateien:

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
)

von Norbert (Gast)


Lesenswert?

ansi90 schrieb:
> Hat jemand eine Idee woran es liegen könnte? Offensichtlicher Fehler im
> Descriptor?
Einer? Singular? Du meine Güte!

von Matthias 🟠. (homa)


Lesenswert?

0x16,0x00,0x80,   //  LOGICAL_MINIMUM (-32768)
 0x26,0xFF,0x7F,   //  LOGICAL_MAXIMUM(32767)

von ansi90 (Gast)


Lesenswert?

Matthias 🟠. schrieb:
> 0x16,0x00,0x80,   //  LOGICAL_MINIMUM (-32768)
>  0x26,0xFF,0x7F,   //  LOGICAL_MAXIMUM(32767)

Wenn die Werte so bei mir ersetze habe ich nach wie vor das gleiche 
Problem. Bei einem Wert von 127 habe ich den Maximalausschlag der Achse 
erreicht. Bei 0 ist sie genau in der Mitte.

von Thomas Z. (usbman)


Lesenswert?

ansi90 schrieb:
> 0x27, 0xff, 0xff, 0x00, 0x00,  #   Logical Maximum (65535)

das ist Käse:
-> 0x20 | 0x04 | 3 -> 3 Bytes du sendest aber 4 bytes.

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

von ansi90 (Gast)


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.

von ansi90 (Gast)


Lesenswert?

Meine ursprünglichen Werte kommen übrigens aus dem HID Descriptor Tool 
von usb.org

von ansi90 (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.