tobozo / ESP32-USB-Soft-Host

An Arduino wrapper to @sdima1357's usb_soft_host esp-idf example
GNU Affero General Public License v3.0
293 stars 44 forks source link

mouse example #5

Open ivo1981 opened 3 years ago

ivo1981 commented 3 years ago

Hi, Can you provide an example on how i can catch data from a connected mouse? the mouse gets detected, but nothing more then that. if I plug in a keyboard i at least get raw data

photo5805244790353279680

tobozo commented 3 years ago

hey @ivo1981 thanks for your feedback

see how it was detected in issue #4, the cable length/quality, mouse type and wiring really matter to get a clear signal

ivo1981 commented 3 years ago

but i shouldn't have to make any changes to the code itself to at least get data. the cable is 1m long the chip it uses is a A2803 (just for future refference)

tobozo commented 3 years ago

I can't really tell since I haven't fully tested a mouse myself, but this library is quite close to the esp-idf example so it should at least work as in the example and report the mouse events after it is detected.

@zbx-sadman did you have to modify the code to get the mouse events ?

ivo1981 commented 3 years ago

so i did some testing; i cut the wires, replaced it with a high quality one, soldered it directly to the pins and pcb, length was 6cm. No joy.... also tried an HP laser mouse, instant data. now to find out what the issue is, as the mouse works fine on any os I tried (ubuntu 20, win10, osx) and has completely USB HID ver1.1 compatibility. It is compatible with Microsoft 3D IntelliMouse. mouse was brand new by the way. i don't think it's an issue with the mouse, but how it's handled by the software

tobozo commented 3 years ago

A few changes had to be done in order to get the original library to work with esp-idf 3.3, and it may have created more failure opportunities indeed.

If you're positive it works fine with the original library, then I can look into it, but I don't have a fully working example for myself (most mouses I tried failed too) so I'm not sure where to begin.

zbx-sadman commented 3 years ago

No, @tobozo , I do not maked any changes with code, only enable debug in the sdima's sources.

When i was connect USB data wires to the ESP directly, i saw data.

zbx-sadman commented 3 years ago

So strange.

I tried just now my setup again with yhe same code and Logitech K120 keyboard & B100 mouse and see mouse detection report only (keyboard is OK - report & data present):

image

Screenshoot from issue #4 maked when this mouse was connected: ASUS Optical USB Black #M-UV55A . It's like that:

image

I will take back this short-cabled mouse ~ May 11 and re-test connection.

tobozo commented 3 years ago

maybe a noise filter could help ?

[edit] both the mouse and the ESP32 serial cable would need it

image

ivo1981 commented 3 years ago

honestly i dont think a noise is the issue; if it was the mouse also wouldn't work on a pc. at least not with any accuracy as it would be skipping beats where the data is corrupted. also using a 6cm (thats like 2 inches if you're state side) high quality shielded cable would definitly do the trick; especially considering it's clean power going in already. I'm pretty confident we are overlooking something on the software side. I'm not saying it's because of the arduino port specificaly as i haven't tested it yet with the toolchain, i went the arduino route so I didn't have to install it. I will try to free up some more time so i can setup the toolchain and try with that. we should at least get some idea of the origin of the issue that way. I think it's an issue with catching the data, but we'll see

tobozo commented 3 years ago

some ideas for the software side:

  #define DP_P0  16  // always enabled
  #define DM_P0  17  // always enabled
  #define DP_P1 18 // -1 to disable
  #define DM_P1  19 // -1 to disable
  #define DP_P2  -1 // -1 to disable
  #define DM_P2  -1 // -1 to disable
  #define DP_P3  -1 // -1 to disable
  #define DM_P3  -1 // -1 to disable
zbx-sadman commented 3 years ago

A few more information...

Just now i has some play with oscilloscope and level shifter (have no luck again). But i catched my Logitech B100 when it being works. Mouse is powered from the ESP32 board with 5V.

I also noticed that on "live connection" mouse's LED is on constantly, and on "dead connection" just blinks on connection and turned off. May be it's power problem? Who knows...

Sketch "config":

#define DP_P0  18  // always enabled
#define DM_P0  19  // always enabled
#define DP_P1  -1 // -1 to disable
#define DM_P1  -1 // -1 to disable
#define DP_P2  -1 // -1 to disable
#define DM_P2  -1 // -1 to disable
#define DP_P3  -1 // -1 to disable
#define DM_P3  -1 // -1 to disable

Below is dumps with uncomments some driver's debug lines.

Case N1, "dead mouse connection":

desc.bcdUSB          = 200
desc.bDeviceClass    = 00
desc.bDeviceSubClass = 00
desc.bDeviceProtocol = 00
desc.bMaxPacketSize0 = 08
desc.idVendor        = 46d
desc.idProduct       = c077
desc.bcdDevice       = 7200
desc.iManufacturer   = 01
desc.iProduct        = 02
desc.iSerialNumber   = 00
desc.bNumConfigurations = 01

Case N2, "live mouse connection":

desc.bcdUSB          = 200
desc.bDeviceClass    = 00
desc.bDeviceSubClass = 00
desc.bDeviceProtocol = 00
desc.bMaxPacketSize0 = 08
desc.idVendor        = 46d
desc.idProduct       = c077
desc.bcdDevice       = 7200
desc.iManufacturer   = 01
desc.iProduct        = 02
desc.iSerialNumber   = 00
desc.bNumConfigurations = 01

cfg.bLength         = 09
cfg.bType           = 02
cfg.wLength         = 22
cfg.bNumIntf        = 01
cfg.bCV             = 01
cfg.bIndex          = 00
cfg.bAttr           = a0
cfg.bMaxPower       = 50

sIntf.bLength      = 09
sIntf.bType        = 04
sIntf.iNum         = 00
sIntf.iAltString   = 00
sIntf.bEndPoints   = 01
sIntf.iClass       = 03
sIntf.iSub         = 01
sIntf.iProto       = 2
sIntf.iIndex       = 0

hid.bLength          = 09
hid.bDescriptorType  = 21
hid.bcdHID           = 111
hid.bCountryCode     = 00
hid.bNumDescriptors  = 01
hid.bReportDescriptorType = 22
hid.wItemLengthH         = 00
hid.wItemLengthL         = 2e

pcurrent->epCount = 1
epd.bEPAdd        = 81
epd.bAttr         = 03
epd.wPayLoad      = 04
epd.bInterval     = 0a

in :00 38 f1 00 
in :00 7f ce 00 
in :00 06 fe 00 
in :00 01 01 00 
in :00 00 01 00 
in :00 e6 00 00 

Case N3, "live keyboard connection":

desc.bcdUSB          = 110
desc.bDeviceClass    = 00
desc.bDeviceSubClass = 00
desc.bDeviceProtocol = 00
desc.bMaxPacketSize0 = 08
desc.idVendor        = 46d
desc.idProduct       = c31c
desc.bcdDevice       = 6400
desc.iManufacturer   = 01
desc.iProduct        = 02
desc.iSerialNumber   = 00
desc.bNumConfigurations = 01

cfg.bLength         = 09
cfg.bType           = 02
cfg.wLength         = 3b
cfg.bNumIntf        = 02
cfg.bCV             = 01
cfg.bIndex          = 03
cfg.bAttr           = a0
cfg.bMaxPower       = 45

sIntf.bLength      = 09
sIntf.bType        = 04
sIntf.iNum         = 00
sIntf.iAltString   = 00
sIntf.bEndPoints   = 01
sIntf.iClass       = 03
sIntf.iSub         = 01
sIntf.iProto       = 1
sIntf.iIndex       = 2

hid.bLength          = 09
hid.bDescriptorType  = 21
hid.bcdHID           = 110
hid.bCountryCode     = 00
hid.bNumDescriptors  = 01
hid.bReportDescriptorType = 22
hid.wItemLengthH         = 00
hid.wItemLengthL         = 41

pcurrent->epCount = 1
epd.bEPAdd        = 81
epd.bAttr         = 03
epd.wPayLoad      = 08
epd.bInterval     = 0a

sIntf.bLength      = 09
sIntf.bType        = 04
sIntf.iNum         = 01
sIntf.iAltString   = 00
sIntf.bEndPoints   = 01
sIntf.iClass       = 03
sIntf.iSub         = 00
sIntf.iProto       = 0
sIntf.iIndex       = 2

hid.bLength          = 09
hid.bDescriptorType  = 21
hid.bcdHID           = 110
hid.bCountryCode     = 00
hid.bNumDescriptors  = 01
hid.bReportDescriptorType = 22
hid.wItemLengthH         = 00
hid.wItemLengthL         = 9f

pcurrent->epCount = 2
epd.bEPAdd        = 82
epd.bAttr         = 03
epd.wPayLoad      = 04
epd.bInterval     = ff

in :00 00 51 00 00 00 00 00 
in :00 00 00 00 00 00 00 00 

Mouse connected:

image

P.S. I've add big capacitor on mouse power line - no any changes. It detects in 10-25% of all connection tries.

tobozo commented 3 years ago

if the ESP32 cannot provide enough power, you can add another 5v power source to your mouse/keyboard, then disconnect the VCC between between the ESP and the USB HID devices (only keep GND, Din, Dout)

you can eventually use an external battery + regulator, but I prefer picking 5v from another port of the same PC using a DIY cable

image

zbx-sadman commented 3 years ago

@tobozo i downloaded latest sources, trying fork task on Core 0, increase memory and maximize priority: xTaskCreatePinnedToCore(USB_SOFT_HOST::TimerTask, "USB Soft Host Timer Task", 20480, NULL, configMAX_PRIORITIES, NULL, 0);

No changes.

I've powered ESP32 from USB-port (500mA), mouse must take 100mA, and i connected capacitor 2200uF. I think this must be enough...

May be perepheral device sometime take more time for init and internal process do not take it in account?

P.S. I used connected mouse periodically within 4 hours. HID reports received w/o errors, ESP no hanged. Seems that problem is happens on init stage...

ivo1981 commented 3 years ago

i did some research on the different all in one optical mouse packages and went over several data sheets, it can take up to 10ms for the init to complete. What i find interesting is that @zbx-sadman reports a 10-25% success rate; that makes me think we are either to slow or to quick with handeling the init. I guess i'll be desoldering my super short cable mouse as I think we can rule out it's cables causing the issue.

tobozo commented 3 years ago

thanks for this research

I seem to have missed some changes from usb_soft_host repository.

So I did some integration+testing, somehow hoping that a better calibration at init would solve the mouse events detection problem, but I can't observe any improvement.

Since it doesn't seem to break anything either, I've pushed those changes on the main branch.

@ivo1981 this kind of change could eventually impact the software side your were mentioning earlier, but my guess is it probably won't.

zbx-sadman commented 3 years ago

Yes, I just a number times pressed reset button on ESP board, and do not re-plug mouse, which always was powered. Sometime mouse fired up led (init completed) and works, sometimes blinking and did not work later.

ivo1981 commented 3 years ago

so the reset trick doesn't seem to work for me (tested on the older default firmware) will need to try it out with debug enabled on the new version.

i set up the mouse supplying power separately now: injecting both 3.3V to the esp and 5V to the usb. (it could now pull several amps, so powerdip is not an issue ;P )

ivo1981 commented 3 years ago

i uploaded the latest code, enabled debug. I gathered all the wired usb mouses I had laying around. all are hp branded they range from 90's to present day. they all seem to work. the amount of initial ack's range from 12-18, the non working mouses are the most recent i bought. They just ack 6 times, they seem to be working, just not parsing data. I understand that the amount of acks doesn't mean anything by itself, but the fact that all the funtioning mouses have at least double the initial acks, makes me think that things go south during the init stage.

zbx-sadman commented 3 years ago

@ivo1981 , short video for you: https://disk.yandex.ru/i/Qg1eQxovXJYzZA I'll deletes it when you watch or download it (notify me, please).

Tomorrow i'll can test this setup with other mouses of various brands.

tobozo commented 3 years ago

Found a mouse that gets detected every time and fires all events :partying_face:, it's a LogiLink, looks like that mouse you get for free when you buy a new computer, very lightweight and gives a feeling it won't have a long lifetime, still beats all Microsof, Logitech and SteelSeries I've tried before :-)

image

ivo1981 commented 3 years ago

@zbx-sadman all the hp's I tried also always work. The problem is the ones that don't (from which I bought 10 to use with esp's :)

I installed the esp-idf toolchain and ran the 'official' version, has the same issue, so it's not an arduino porting issue.

zbx-sadman commented 3 years ago

Every mouse tested 10 times (via ESP32 board reset). All items checked on PC preliminarily. Success rate marked as X/10.

1) ASUS (Logitech) Optical USB Black #M-UV55A [idVendor = 0x046d, idProduct = 0xc016]. Data recieves - 7/10 , led fired (complete init?) - 10/10; 2) A4Tech OP-720 [idVendor = 0x093a, idProduct = 0x2510]. Data recieves - 5/10, led fired - 10/10; 3) Microsoft Wheel Mouse [idVendor = 0x045e, idProduct = 0x0040] (have ferrite barell noise filter. and no model specified on device, looks like that: https://www.amazon.com/Microsoft-D66-00029-Wheel-Mouse-Optical/dp/B00006B7HB). Data recieves - 6/10, led fired - 6/10; 4) A4Tech SWOP-48 [idVendor = 0x093a. idProduct = 0x2510]. Data recieves - 10/10 , led fired - 10/10; 5) Oklick-305m. Data recieves - 0/10 (sic!), led fired - 10/10 (i guess it always turned on, independing of init result ); 6) Exegate SH-9018. Data recieves - 0/10, led fired - 10/10. Device reaction looks like Oklick-305m; 7) Genius Netscroll 110X [idVendor = 0x0458, idProduct = 0x003a]. Data recieves - 10/10, led fired - 10/10; 8) Logitech M-BT83 [idVendor = 0x046d, idProduct = 0xc03e], Data recieves - 5/10, led fired - 5/10; 9) A4Tech X-7??? , gaming mouse w/o label [ VID_09DA&PID_8090&REV_0606&MI_00 ]. Not recognized by driver, no any info in the Serial Monitor exist.

Oklick-305m & Exegate SH-9018 mouses connection report sometime stopped on desc.bNumConfigurations = 0x01 message, sometime gave more connection info, but i saw no moving/clicking report on the terminal window.

Trying to find another vendors mouses... Report will be updated.

tobozo commented 3 years ago

thanks @zbx-sadman thanks for this list :+1: I'll be adding it to the readme.

Could you also collect the idVendor/idProduct too for completeness?

zbx-sadman commented 3 years ago

@tobozo, i had updated post and add IDs from Serial Monitor. Unfortunately some mouses i returned to it owners, and can't get it's IDs.

tobozo commented 3 years ago

@zbx-sadman thanks!

I'm currently playing with a Markdown editor to make a nice table in the readme, will update soon

[edit] that's the ticket

Status Brand Model Name/ID idVendor idProduct Init Events Comments
:smile: LogiLink ID0062 0x1a2c 0x0042 10/10 10/10 Low cost 3 buttons mouse
:smile: Microsoft Intellimouse 1.1 0x045e 0x0039 10/10 10/10
:smile: A4Tech SWOP-48 0x093a 0x2510 10/10 10/10
:smile: Genius Netscroll 110X 0x0458 0x003a 10/10 10/10
:no_mouth: Logitech M-UV55A 0x046d 0xc016 10/10 7/10 Brand is advertised as ASUS/Logitech
:no_mouth: Microsoft Wheel Mouse 0x045e 0x0040 6/10 6/10
:no_mouth: A4Tech OP-720 0x093a 0x2510 10/10 5/10
:cold_face: Logitech M-BT83 0x046d 0xc03e 5/10 5/10
:cold_face: Logitech B100 0x046d 0xc077 10/10 3/10
:skull: Oklick 305m n/a n/a 10/10 0/10
:skull: Exegate SH-9018 n/a n/a 10/10 0/10 Device reaction looks like Oklick-305m
:skull: A4Tech X-7??? 0x09da 0x8090 0/10 0/10 Gaming mouse w/o label