Skip to content

Add check to skip over keyboard #3111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

RetiredWizard
Copy link
Contributor

@RetiredWizard RetiredWizard commented Aug 19, 2025

When both a USB keyboard and a USB mouse are connected to a Fruit Jam, "most" times, the mouse did not work. If you removed the USB keyboard then the mouse always worked, however in order to start the game in this mode you need to have a serial connection to a host computer running the terminal.

I believe the issue was that the loop that searched for the mouse hardware stopped on the first device it found (EDIT: actually it always assigns the last device found as a mouse... either way, this should fix it). I've taken the test from Larsio_Paint_Music and used it in that loop to allow the program to skip over devices that don't appear to be mice.

This change allows the Minesweeper game to be run on the Fruit Jam when it's not connected to a host computer.

@TheKitty
Copy link
Collaborator

I have advocated, unsuccessfully, for some comprehensive USB device checking in a library to allow program devs to know what's connected easily. I have some code, works well, just a bit bulky, it could likely use a refactor.

Comment on lines 142 to 155
buf = array.array("b", [0] * 4)
try:
# Try to read some data with a short timeout
data = mouse.read(0x81, buf, timeout=100)
print(f"Mouse test read successful: {data} bytes")
break
except usb.core.USBTimeoutError:
# Timeout is normal if mouse isn't moving
print("Mouse connected but not sending data (normal)")
break
except Exception as e: # pylint: disable=broad-except
print(f"Mouse test read failed: {e}")
# Continue to try next device or retry
mouse = None
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use find_boot_mouse_endpoint() from adafruit_usb_host_descriptors to find the mouse instead of assuming a device will be the mouse. I think that should resolve the issue with it not working when a keyboard is connected.

Or for higher level API the code could use https://github.com/adafruit/Adafruit_CircuitPython_USB_Host_Mouse/, but that is perhaps a bit larger of a change then just changing the bit that finds the mouse.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested the code to use find_boot_mouse_endpoint which seems to work fine, but when I turned on the mouse option in Fruit Jam OS the apps and/or the launcher started throwing USB errors (endpoint 0x81 not found). I tried for hours to get reliable steps for causing the problem without success. I also tried reproducing with simple code files with no luck either.

The error is really strange because the app will print the "Mouse test read successful" message from the above code snippet and then throw the endpoint not found when the same read is performed later in the code.

I was able to resolve (maybe?) the issue by adding an extra read during the initial mouse configuration. My thinking was that there was some leftover data in the USB queue that was causing problems but the extra read always came back with no data. I don't understand why the extra read helped which is why I'm skeptical it's a complete fix.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't a mouse buffer 6 or maybe even 8 bytes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I tried increasing it to 6 at one point, but who knows what the overall state was at the time :/

I'm stepping away for a bit, I'll play with buffer size a little when I come back to it....

@RetiredWizard RetiredWizard marked this pull request as draft August 19, 2025 19:20
@RetiredWizard
Copy link
Contributor Author

So I tried the higher level approach from adafruit_usb_host_mouse import find_and_init_boot_mouse and if I used the mouse in the Fruit Jam OS launcher to start minesweeper, I got the following:

/apps/Metro_RP2350_Minesweeper/code.py output:
scanning usb
413c:2105
None None

Traceback (most recent call last):
  File "/apps/Metro_RP2350_Minesweeper/code.py", line 124, in <module>
  File "adafruit_usb_host_mouse.py", line 62, in find_and_init_boot_mouse
  File "adafruit_usb_host_descriptors.py", line 79, in get_configuration_descriptor
  File "adafruit_usb_host_descriptors.py", line 56, in get_descriptor
usb.core.USBError: 

Code done running.

line 124 is:
mouse = find_and_init_boot_mouse()

If I used the keyboard to start minesweeper, then I got a number of the no endpoint 0x81 messages, but the mouse worked anyway. That tells me that with the original code I probably should have just been catching and ignoring the no endpoint messages.

I think there's something going on where the mouse/usb is left in some state which doesn't get completley reset during a supervisor.reload()/Ctrl-D which is causing the error shown above. But that's probably a core problem and I think the best we're going to do right now is work out some work-around.

@RetiredWizard RetiredWizard marked this pull request as ready for review August 19, 2025 20:33
@RetiredWizard
Copy link
Contributor Author

This version now works reliably with or without the launcher mouse enabled. Using the higher level usb_host_mouse library is a probably a cleaner approach but the mouse location data returned is in a completely different format so would require some work to integrate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants