Forum: Mikrocontroller und Digitale Elektronik V-USB Hid Joystick


von C.C. (Gast)


Lesenswert?

Hallo! Ich bastel gerade an einem USB-Joystick und habe das Problem, 
dass das Gerät nicht erkannt wird...
Testweise lese ich ein Poti am ADC1-Eingang aus und möchte dieses als 
eine Joystick-Achse von Windows erkennen lassen. Ich vermute mal der 
Report-Descriptor ist falsch:
1
const PROGMEM char usbHidReportDescriptor[24] = { /* USB report descriptor */
2
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
3
    0x09, 0x04,                    // USAGE (Joystick)
4
    0xa1, 0x01,                    // COLLECTION (Application)
5
    0xa1, 0x00,                    //   COLLECTION (Physical)
6
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
7
    0x09, 0x32,                    //     USAGE (Z)
8
    0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
9
    0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
10
    0x75, 0x08,                    //     REPORT_SIZE (8)
11
    0x95, 0x01,                    //     REPORT_COUNT (1)
12
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
13
    0xc0,                          //    END_COLLECTION
14
    0xc0                           //  END_COLLECTION
15
};

Hier der relevante Code:
1
static void buildReport(void) {
2
    reportBuffer[0] = 0;
3
    reportBuffer[1] = getadc(1);
4
}
5
6
int main(void) {
7
    odDebugInit();
8
    usbDeviceDisconnect();
9
    _delay_ms(100);
10
    usbDeviceConnect();
11
    wdt_enable(WDTO_1S);
12
    usbInit();
13
    sei();
14
    for(;;){
15
      wdt_reset();
16
      usbPoll();
17
  if(usbInterruptIsReady()) {
18
         buildReport();
19
         usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
20
  }
21
  if (getbutton() == 0) { led(1); }
22
  else { led(0); }
23
    }
24
    return 0;
25
}

Die Funktion getadc(1) liefert einen 8Bit-Wert zwischen -127 und 127 
zurück.

Habt ihr eine Idee warum das Gerät nicht erkannt wird?

Gruss,
Chris C

von C.C. (Gast)


Lesenswert?

Habe mal mit dem "USB Device Tree Viewer" nachgeguckt, das USB-Gerät 
wird zwar als HID erkannt, aber mit dem "Problem-Code: 10 
(CM_PROB_FAILED_START)"...

von Pudel (Gast)


Lesenswert?


von CC (Gast)


Lesenswert?

Danke, aber das Gerät ist ein HID, dh. es sind keine Treiber notwendig. 
Am fehlenden/falschen Treiber kanns also nicht liegen...

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Schau dir mal andere Joystick Projekte an:
http://www.obdev.at/products/vusb/prjhid.html

Hast du in usbconfig.h die richtige Länge des Descriptors auch 
eingestellt?

Hier ist mal der Descriptor für eine Maus mit absoluten Koordinaten (HID 
Adapter für ein serielles Tablett mit 3 von 4 Buttons, mehr gehen 
nicht), vllt. hilft das ja auch - zumindest für die absoluten 
Koordinaten:
1
PROGMEM char usbHidReportDescriptor[60] = {
2
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
3
    0x09, 0x02,                    // USAGE (Mouse)
4
    0xa1, 0x01,                    // COLLECTION (Application)
5
    0x09, 0x01,                    //   USAGE (Pointer)
6
    0xa1, 0x00,                    //   COLLECTION (Physical)
7
    0x05, 0x09,                    //     USAGE_PAGE (Button)
8
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
9
    0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
10
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
11
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
12
    0x95, 0x03,                    //     REPORT_COUNT (3)
13
    0x75, 0x01,                    //     REPORT_SIZE (1)
14
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
15
    0x95, 0x01,                    //     REPORT_COUNT (1)
16
    0x75, 0x05,                    //     REPORT_SIZE (5)
17
    0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
18
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
19
    0x09, 0x30,                    //     USAGE (X)
20
    0x09, 0x31,                    //     USAGE (Y)
21
    0x35, 0x00,                    //     PHYSICAL_MINIMUM (0)
22
    0x46, 0x9d, 0x0b,              //     PHYSICAL_MAXIMUM (2973)
23
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
24
    0x26, 0x9d, 0x0b,              //     LOGICAL_MAXIMUM (2973)
25
    0x65, 0x11,                    //     UNIT (SI Lin:Distance)
26
    0x55, 0x0e,                    //     UNIT_EXPONENT (-2)
27
    0x75, 0x10,                    //     REPORT_SIZE (16)
28
    0x95, 0x02,                    //     REPORT_COUNT (2)
29
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
30
    0xc0,                          //   END_COLLECTION
31
    0xc0                           // END_COLLECTION
32
};

: Bearbeitet durch User
von greg (Gast)


Lesenswert?

Hast du schon einmal mit anderem Report Descriptor herumprobiert? Wenn 
ich mich richtig erinnere, merkt sich Windows leider den Report 
Descriptor anhand von VID/PID. Also wenn du den änderst, bringt das 
erstmal nichts. Du musst den Report Descriptor aus der Registry löschen. 
Google mal danach. Alternativ kannst du einfach die PID hochzählen o.ä.

von Chrud (ruder)


Lesenswert?

Schau mal da nach: Beitrag "R/C-Fernsteuerung -> USB Konverter in C (V-USB, HID-Joystick, PPM-Dekoder)"

Wird als USB-Joystick erkannt. Habe ich erst gerade nachgebaut und 
erfolgreich unter Windows 7 & 8.1 getestet.

von CC (Gast)


Lesenswert?

Hallo! Habe das ganze mal getestet, leider wird das USB-Gerät nicht 
erkannt... Habe die C-sourcen auf meinen Aufbau angepasst und 
kompiliert, das USB-Gerät wird auch enumeriert, aber trotzdem nicht 
unter den "USB-Gamecontrollern" in Windows angezeigt...

Reicht es grundsätzlich, bei einem V-USB-Tastaturprojekt (zB der 
"EasyLogger") den Report Descriptor auf einen 1-Achsen-Joystick zu 
ändern und anstatt des Tastatur-Keys eine 8-Bit-Zahl (die den Achsenwert 
darstellen soll) zu übergeben?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

CC schrieb:
> Reicht es grundsätzlich, bei einem V-USB-Tastaturprojekt (zB der
> "EasyLogger") den Report Descriptor auf einen 1-Achsen-Joystick zu
> ändern und anstatt des Tastatur-Keys eine 8-Bit-Zahl (die den Achsenwert
> darstellen soll) zu übergeben?

Nein. GameController sind eine andere Klasse und z.B. einer Maus 
ähnlicher als einem Keyboard. Der Descriptor muss dazu u.a. (und 
deswegen habe ich dir oben den Descriptor gepostet) den Wertebereich des 
'analogen' Signals angeben, in PHYSICAL_MINIMUM und PHYSICAL_MAXIMUM.

von Seppel (Gast)


Lesenswert?

Versuche mal das USB Descriptor Tool ( 
http://www.usb.org/developers/hidpage/dt2_4.zip )
Da sind auch Beispiele dabei, incl. Joystick.
Hat mir damals auch geholfen, als ich einen einfachen USB-Touchopanel 
Descriptor brauchte.

Wenn Du dann verinnerlicht hast, wie so ein Descriptor aufgebaut ist, 
klappt das auch besser mit dem eigenen Descriptor.
So erging es mir jedenfalls.

von Seppel (Gast)


Lesenswert?

Ach noch was, wie sieht eigentlich die Hardware aus?
Hatte mal ein Problem mit einem Chinamodul (ATMega32), wo man erst eine 
Brücke reinmachen musste, damit USB lief. Wenn ich das nicht zufällig 
gefunden hätte, wäre das Board in die Tonne gewandert.
Das Board hat 5 Taster und 8 LEDs und es steht JY-MCU JY-MEGA16/32 Demo 
V1.3 auf der Unterseite. Hatte das mal geholt, weil die auch 'nen JTAG 
Connector haben.

von CC (Gast)


Lesenswert?

Hallo!
Das mit dem Descriptor habe ich nun soweit verstanden, habe zum testen 
einen Descriptor (von hier: 
http://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/) für 
ein Gamepad genommen, mit dem Descriptor-Tool geschrieben und einfach 
damit den Descriptor des "Easyloggers" ersetzt (und natürlich die 
DESCRITPTOR_LENGTH und andere Werte in der usbconfig.h angepasst).
Das Gerät müsste nun ja zumindest von Windows als Gamecontroller erkannt 
werden, es wird aber merkwürdigerweise immer noch als HID-Tastatur 
erkannt...

Reicht es also aus, nur den Report Descriptor zu ändern um ein anderen 
Gerätetyp zu erhalten oder muss ich noch mehr ändern (zB die 
usbFunctionSetup()-Funktion oder das ReportBuffer[]-Array)?

von Putin (Gast)


Lesenswert?

CC schrieb:
> Das mit dem Descriptor habe ich nun soweit verstanden,

Ich glaub nicht. Du sprichst immer allgemein vom Descriptor, meinst aber 
den Report bzw. HID Descriptor. Wahrscheinlich musst du mindestens noch 
den Interface Descriptor anpassen... InterfaceClass, InterfaceSubClass & 
InterfaceProtocol

http://www.beyondlogic.org/usbnutshell/usb5.shtml#InterfaceDescriptors

von Seppel (Gast)


Lesenswert?

Also ich würde jetzt erstmal eine funktionierende/existierende Software 
(z.B. von dem o.g. USB-Joystick) versuchen, um herauszufinden, ob die 
Hardware USB-seitig funktioniert und erkannt wird.
In der V-USB Projektsammlung wird es ja wohl was geben, was auf Deiner 
Hardware, zu der Du noch immer kein Wort verraten hast, läuft oder 
leicht angepasst werden kann.

von CC (Gast)


Lesenswert?

Moin,
wie gesagt, die Software von dem o.g. Joystick funktioniert soweit, 
umfasst aber erheblich mehr als ich brauche, ein einfaches Ändern ist 
aber nicht möglich, schon wegen der Datenstruktur, Report Descriptor 
usw.

@Putin: Das mit dem Interface Descriptor klingt gut, leider hat Google 
da nichts brauchbares zu gefunden... An die V-USB Experten: Ist so ein 
Descriptor (zusätzlich zum Report-Descr.) nötig, wenn ja wo kann ich ihn 
in der V-USB-Bibliothek ändern?

Gruß,CC

von CC (Gast)


Lesenswert?

PUUUUSH it ;)

von CC (Gast)


Lesenswert?

Noch wer eine Idee?

von Hopper (Gast)


Lesenswert?

Hi, bist du weitergekommen? Ich bin ebenfalls gerade an nem ähnlichen 
Projekt dran. Für meinen 6 Tasten - Joystick habe ich diesen 
ReportDescriptor benutzt, der geht soweit.

const PROGMEM char usbHidReportDescriptor[29] = {
  0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
  0x09, 0x05,                    // USAGE (Joystick)
  0xa1, 0x01,                    //   COLLECTION (Application)
  0x05, 0x09,                    //   USAGE_PAGE (Button)
  0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
  0x29, 0x06,                    //   USAGE_MAXIMUM (Button 6)
  0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
  0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
  0x95, 0x06,                    //   REPORT_COUNT (6)
  0x75, 0x01,                    //   REPORT_SIZE (1)
  0x81, 0x02,                    //   INPUT (Data,Var,Abs)
  0x95, 0x01,                    //   REPORT_COUNT (1)
  0x75, 0x02,                    //   REPORT_SIZE (2)
  0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
  0xc0
};

Gruß Hopper

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.