Hallo.
Ich versuche seit einiger Zeit einen kleinen Touchscreen Monitor mit
einem atmega32ux dazu zu bewegen, das Android auf ihn reagiert.
Leider bin ich mittlerweile so durcheinander gekommen, das ich erstmal
keine Codeschnuipsel posten kann.
Hatte zwar schon einen 'Touch' bekommen, aber die Koordinaten werden
nicht ünertragen.
Mein Grundgerüst war die LUFA Mouse Class Demo.
Hatte dann den Report geändert. Also die X/Y Koordinaten auf 16 Bit
unsigned (uint16_t) sowie den Mouse-Descriptor geändert.
Das Gerät wird auch unter Windows (meist) einwandfrei erkannt, aber viel
passiert trotzdem nicht.
Hat wer vielleicht schon ein ähnliches Problem gehabt und eine Lösung
dafür?
Ich möchte nur absolute Koordinaten und (mindestens) einen Touch-Event
übertragen.
Wie wäre egal. Kann auch eine Maus mit absoluten Koordinaten sein. Das
funzt zwar unter Windows, aber nicht unter Android.
Verwendet wird die Android Version 4.2.2 (FInless 1.5) mit Kernel
3.0.36+ auf einem Tropnsmart MK908 mit 2G/8G.
Die Touch Auswertung läuft auch halbwegs (Verbesserungspotential gibts
ja immer). Es fehlt nur die Anbindung an den Android-Stick.
Zur Kontrolle nehme ich immer das HID Descriptor Tool von USB.org und
erstelle auch damit den Descriptor.
Recherchen i Internet waren immer recht erfolglos.
Ich schau noch, ob ich den Descriptor mit Touch finde (muss von anderer
Partition booten) und reiche den nach.
Viele Grüsse
Jürgen
Hier mal der Descriptor, bei dem es mit der geänderten
LUFA CLASS MOUSE DEMO
mit dem Touch funktioniert:
1
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
2
0x09, 0x02, // USAGE (Mouse)
3
0xa1, 0x01, // COLLECTION (Application)
4
0x09, 0x01, // USAGE (Pointer)
5
0xa1, 0x00, // COLLECTION (Physical)
6
0x05, 0x0d, // USAGE_PAGE (Digitizers)
7
0x09, 0x33, // USAGE (Touch)
8
0x19, 0x01, // USAGE_MINIMUM (Digitizer)
9
0x29, 0x01, // USAGE_MAXIMUM (Digitizer)
10
0x15, 0x00, // LOGICAL_MINIMUM (0)
11
0x25, 0x01, // LOGICAL_MAXIMUM (1)
12
0x95, 0x01, // REPORT_COUNT (1)
13
0x75, 0x01, // REPORT_SIZE (1)
14
0x81, 0x02, // INPUT (Data,Var,Abs)
15
0x95, 0x01, // REPORT_COUNT (1)
16
0x75, 0x07, // REPORT_SIZE (7)
17
0x81, 0x01, // INPUT (Cnst,Ary,Abs)
18
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
19
0x09, 0x30, // USAGE (X)
20
0x09, 0x31, // USAGE (Y)
21
0x15, 0x00, // LOGICAL_MINIMUM (0)
22
0x26, 0xff, 0x03, // LOGICAL_MAXIMUM (1023)
23
0x65, 0x00, // UNIT (None)
24
0x75, 0x10, // REPORT_SIZE (16)
25
0x95, 0x02, // REPORT_COUNT (2)
26
0x81, 0x02, // INPUT (Data,Var,Abs)
27
0xc0, // END_COLLECTION
28
0xc0 // END_COLLECTION
29
[/code>]
30
31
Datei für das HID Descriptor Tool von USB.org im Anhang.
32
33
Weiter habe och in der Mouse.c
34
den Teil der Button und Joystick Abfrage geändert, so dass sinnvolle Werte entstehen.
35
[code}
36
if (JoyStatus_LCL & JOY_UP)
37
{
38
MouseReport->X = 100;
39
MouseReport->Y = 100;
40
MouseReport->Button |= (1 << 0);
41
}
42
43
if (JoyStatus_LCL & JOY_DOWN)
44
{
45
MouseReport->X = 100;
46
MouseReport->Y = 200;
47
MouseReport->Button |= (1 << 0);
48
}
49
50
if (JoyStatus_LCL & JOY_LEFT)
51
{
52
MouseReport->X = 200;
53
MouseReport->Y = 100;
54
MouseReport->Button |= (1 << 0);
55
}
56
57
if (JoyStatus_LCL & JOY_RIGHT)
58
{
59
MouseReport->X = 200;
60
MouseReport->Y = 200;
61
MouseReport->Button |= (1 << 0);
62
}
63
64
if (JoyStatus_LCL & JOY_PRESS)
65
MouseReport->Button |= (1 << 0);
Dann noch den Report angepasst:
1
typedef struct
2
{
3
uint8_t Button; // unverändert
4
uint16_t X; // von int8_t auf uint16_t geändert
5
uint16_t Y; // von int8_t auf uint16_t geändert
6
} ATTR_PACKED USB_MouseReport_Data_t;
Wie gesagt:
Touch funktionert.
Anm einer freien auf dem Bildschrim kommt bei langem Touch der Dialog
für den Hintergrund. Es lasen sich, mit der Maus vorher entsprechend
positioniert, auch Apps starten.
Arno Nüm schrieb:> uint16_t X; // von int8_t auf uint16_t geändert> uint16_t Y; // von int8_t auf uint16_t geändert
Nach meinem Verständnis sind die logical values immer signed. Solange
man nur Werte >=0 und <=32767 verwendet ist das aber egal. Ich hab bei
mir die Werte min=-32768 und max=32768 verwendet um genauer
positionieren zu könnnen (SubPixel Mouse Movement :-), ist aber
vielleicht doch etwas übertrieben.
> 0x05, 0x0d, // USAGE_PAGE (Digitizers)
> 0x09, 0x33, // USAGE (Touch)
Ob man die Usage Digitizers:Touch oder Desktop:Mouse verwendet scheint
keine große Rolle zu spielen, zumindest unter Windows und Mac OSX. Je
nachdem welcher Treiber sich dafür zuständig fühlt kann es sich aber
auswirken.
Windows hat die Einschränkung, dass man ohne eigenen Treiber auf den
ersten Bildschirm beschränkt ist.
Bei MacOS gibt es 15% logischen Rand um den eigentliche Desktop (mit dem
Standard-Treiber und Standard Settings), d.h. für min=0 und max=1023
bewegt sich der Pointer nur zwischen den Werten 76 und 946, ansonsten
klebt er am Rand.
Ich hab das letztens für den Arduino Leonardo (ATmega32U4) umgesetzt,
d.h. den Core angepasst. Siehe auch Kommentare und Verweis auf den
Pull-Request in Git:
[https://github.com/arduino/Arduino/issues/1417#ref-commit-7b77d1e]
Michael
Hallo und danke für die Antwort.
Leider kann ich das mit einem Arduino Leonardo noch nicht tsten, da die
grad erst bestellt wurden.
Habe sonst nur noch einen MattairTech MT-DB-U4 hier, der aber, trotz
gewisser Konpatibilitäten, nicht so will. Mein XP muckt auch nach
einiger Zeit...
Würde bei dem Porjekt auch gerne bei AVRStudio bleiben, auch, wenn ich
schon eine ganze Kiste von Arduino Teilen habe. Di emeisten aber ohne
Bootloader, da alles über AVRStudio...
Wobei ich mir ja zumindest mal den Descriptor auslesen könnte, wenns
funzt. :D
Arno Nüm schrieb:> Leider kann ich das mit einem Arduino Leonardo noch nicht tsten, da die> grad erst bestellt wurden.
Das muss kein Arduino Board sein. Ich hab das auch hauptsächlich mit
einem Teensy 1.0++ mit AT90USB646 und einem FLIP Bootloader gemacht. Es
geht ja nicht um das Board oder den Bootloader, sondern nur um die USB
HID Features.
> Habe sonst nur noch einen MattairTech MT-DB-U4 hier, der aber, trotz> gewisser Konpatibilitäten, nicht so will. Mein XP muckt auch nach> einiger Zeit...
Deine Report-Struktur kommt mir komisch vor:
1
typedef struct
2
{
3
uint8_t Button; // unverändert
4
uint16_t X; // von int8_t auf uint16_t geändert
5
uint16_t Y; // von int8_t auf uint16_t geändert
6
} ATTR_PACKED USB_MouseReport_Data_t;
Der Compiler wird höchstwahrscheinlich zwischen 'Button' und 'X' ein
Füllbyte einfügen. Das siehst du am einfachsten, wenn Du die erwartete
Strukturgröße (5 Byte) mit der tatsächlichen (ich vermute: 6 Byte)
vergleichst. Ich kann das heute zeitlich nicht mehr überprüfen.
Außerdem sollte man bei Netzwerk-Protokollen nicht auf die endianess der
CPU verlassen (USB benötigt 'little endian') und die Bytes besser direkt
dahin schreiben wo sie hin müssen.
Probier mal folgendes:
//0x66, 0x00, 0x00 // Unit (None) TODO: is this a good idea and is it correct?
36
0x75, 0x10, // REPORT_SIZE (16)
37
0x95, 0x03, // REPORT_COUNT (3)
38
0x81, 0x02, // INPUT (Data,Var,Abs)
39
0xc0, // END_COLLECTION
40
0xc0, // END_COLLECTION
Wenn Du aus dem #if 0 ein #if 1 machst, wird anstatt der Maus ein
Digitizer emuliert.
Die ReportID brauchst du wohl nicht, wenn du nicht unterschiedliche
Reports pro Endpoint schicken willst
Ich habe 3 Maus-Buttons, eine x-, y- und eine wheel-Achse definiert.
Michael
Soooooo...
Ansatzweise habe ich es!
Descriptor für 800x480:
1
0x05, 0x0d, // USAGE_PAGE (Digitizers)
2
0x09, 0x01, // USAGE (Digitizer)
3
0xa1, 0x01, // COLLECTION (Application)
4
0x09, 0x04, // USAGE (Touch Screen)
5
0xa1, 0x00, // COLLECTION (Physical)
6
0x05, 0x0d, // USAGE_PAGE (Digitizers)
7
0x09, 0x33, // USAGE (Touch)
8
0x09, 0x32, // USAGE (In Range)
9
0x15, 0x00, // LOGICAL_MINIMUM (0)
10
0x25, 0x01, // LOGICAL_MAXIMUM (1)
11
0x75, 0x01, // REPORT_SIZE (1)
12
0x95, 0x02, // REPORT_COUNT (2)
13
0x81, 0x02, // INPUT (Data,Var,Abs)
14
0x75, 0x01, // REPORT_SIZE (1)
15
0x95, 0x06, // REPORT_COUNT (6)
16
0x81, 0x03, // INPUT (Cnst,Var,Abs)
17
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
18
0x09, 0x30, // USAGE (X)
19
0x15, 0x00, // LOGICAL_MINIMUM (0)
20
0x26, 0x20, 0x03, // LOGICAL_MAXIMUM (800)
21
0x75, 0x10, // REPORT_SIZE (16)
22
0x95, 0x01, // REPORT_COUNT (1)
23
0x81, 0x02, // INPUT (Data,Var,Abs)
24
0x09, 0x31, // USAGE (Y)
25
0x15, 0x00, // LOGICAL_MINIMUM (0)
26
0x26, 0xe0, 0x01, // LOGICAL_MAXIMUM (480)
27
0x75, 0x10, // REPORT_SIZE (16)
28
0x95, 0x01, // REPORT_COUNT (1)
29
0x81, 0x02, // INPUT (Data,Var,Abs)
30
0xc0, // END_COLLECTION
31
0xc0 // END_COLLECTION
Touch funzt, Position funzt.
Der Rest vom COde (weiter oben) ist unverändert.
Naja, die Auswertung der Eingänge hat sich ein wenig geändert und die
Auswahl des Wertes für den/die Button(s) habe ich auf ein #define
umgelegt, um das ewige Editieren zu umgehen.
@Michael
Vielen Dank für Deine Mühe. Werde mir das auf alle Fälle auch mal
genauer anschauen.
Das mit den Descriptoren habe ich mittlerweile wohl geschnallt.
Zumindest den Aufbau. Ob sie funktionieren ist was anderes...
Das mit den Füllbits habe ich auch schon gelernt.
1
0x75, 0x01, // REPORT_SIZE (1)
2
0x95, 0x06, // REPORT_COUNT (6)
Damit kommt man dann auf glatte Bytes (oder so - mir felhen manchmal die
Fachausdrücke).
Das ganze aufzudröselön ist auch keine schlechte Idee.
Da merkt man, das Du 'etwas' mehr drauf hast als ich.
Werde dann mal anfangen, die Panelauswertung mit dem USB Kram zu
verbinden.
Der (über)nächste Schritt ist dann, die Daten aus dem Navianschluss
meines Alpine Radios auszuwerten und einen H/V -> Composite-Sync Adapter
sowie das Signal des HDMI -> VGA Wandlers einzuspeisen.
Und schon bin ich der erste mit 'nem Auroradio, Android 4.2 und Quadcore
CPU/GPU!
Hallo
Auf der Suche nach einem Touch Screen HID device descriptor hat mich
Google hierher gebracht und ich habe beide oben geposteten Descriptoren
getestet.
Mein Vorhaben war einen universalen HID Descriptor zu finden der auf
ALLEN Betriebssystemen funktioniert.
Die beiden Deskriptoren von Arno und Michael oben taugen dafür beide
nicht.
Das Probem mit USAGE_PAGE (Digitizers) ist z.B. daß Windows XP diese
nicht unterstützt.
Der Touchscreen von Michael verwendet DREI buttons!
Kein realer Touchscreen hat 3 Finger oder 3 Stifte.
Mit solchen selbstgebauten Deskriptoren hat man vielleicht Glück auf
seinem Heimcomputer, aber sobald man damit in die weite Welt geht, wird
man unweigerlich Betriebssysteme finden die das nicht akzeptieren. Ein
Treiber für einen Touchscreen ist nicht für 3 Buttons ausgelegt.
Der Linux X11 Server ist voller Bugs und hat schon Probleme mit einer
Maus die absolute Koordinaten sendet!
Ich bin deshalb auf Nummer Sicher gegangen und habe einen echten
Touchscreen von ELO Touchsystems geklont.
Wer an einem universellen Touchscreen für alle Betriebssystem
interessiert ist, der lese meinen Artikel auf Codeproject:
http://www.codeproject.com/Articles/1001891/A-USB-HID-Keyboard-Mouse-Touchscreen-emulator-with
Elmü Meister schrieb:> Der Touchscreen von Michael verwendet DREI buttons!> Kein realer Touchscreen hat 3 Finger oder 3 Stifte.> Mit solchen selbstgebauten Deskriptoren hat man vielleicht Glück auf> seinem Heimcomputer, aber sobald man damit in die weite Welt geht, wird> man unweigerlich Betriebssysteme finden die das nicht akzeptieren. Ein> Treiber für einen Touchscreen ist nicht für 3 Buttons ausgelegt.
Die Idee hinter HID ist, dass es keine spezifischen Treiber für Mäuse,
Tastaturen, Touchscreens, etc. mehr gibt sondern genau einen HID Treiber
der das alles kann.
Man definiert und implementiert gegen die HID Spec, welche keine
Einschränkungen bei der Anzahl der Buttons macht und nicht gegen die
Implementierung irgendeines 3rd Party Treiberherstellers welcher
implizite Annahmen in seinem Code macht.
Der Stift für den Digitizer meines alten Notebooks Toshiba M200 hatte 3
physikalische Buttons: links, rechts, radierer
Auf wie viele HID Buttons diese abgebildet wurden habe ich nicht
geprüft.
> Mein Vorhaben war einen universalen HID Descriptor zu finden der auf ALLEN
Betriebssystemen funktioniert.
> Die beiden Deskriptoren von Arno und Michael oben taugen dafür beide nicht.
Kannst du das mal etwas genauer ausführen, damit ich meinen Descriptor
korrigieren kann?
Michael
Hallo Michael
Wie gesagt: Es kann sein dass bei dir dein Descriptor funktioniert.
Aber auf Linux ist das alles sehr buggy implementiert und wenn du willst
dass dein Descriptor auch auf Linux sicher funktioniert empfehle ich dir
auf Nummer sicher zu gehen.
> Kannst du das mal etwas genauer ausführen,> damit ich meinen Descriptor korrigieren kann?
Offenbar hast du meinen Artikel auf Codeproject nicht gelesen ?
Auch Microsoft macht seine Anforderungen an Touchscreens die von deinem
nicht erfüllt werden:
https://msdn.microsoft.com/en-us/library/windows/hardware/ff553737%28v=vs.85%29.aspx
Du mußt einen TipSwitch und InRange definieren.
Aber wenn du diesen Descriptor benutzt wird er auf Windows XP nicht
funktionieren.
Deshalb empfehle ich dir meinen (von ELO kopierten) zu nehmen, den ich
bereits auf etlichen Betriebssystemen getestet habe.