To read data from a mouse in CircuitPython, you must use a device that supports USB Host, such as the Metro RP2350 or Feather RP2040 USB Host.
Feather RP2040 USB Host Wiring
Connecting to the Feather RP2040 USB Host requires plugging in a USB C cable to the Feather's Host port and connecting the other end to a USB Hub breakout such as the CH334F.
Metro RP2350 USB Host Wiring
Connecting to the Metro RP2350 USB Host port requires soldering pins to the broken-out USB Host connections as shown on this guide page. Make the following connections between the Metro USB Host pins and the CH334F host connection opposite the USB C connector.
- GND to GND with Black or Blue
- D+ to D+ with Green
- D- to D- with White
- 5V to 5V with Red
Note that the data pins are swapped on the Metro compared to the CH334F breakout. On the Metro D- is next to 5V, whereas on the CH334F D- is next to GND.
Be sure to connect D- on the breakout to D- on the Metro, and D+ on the breakout to D+ on the Metro.
USB Host is under active development. As of CircuitPython version 10.0.0-alpha.2, the wired USB Mouse only works on CircuitPython when connected through a USB hub such as the CH334F.
Demo Code: Read Data
This example uses the USB Host API to read data from the mouse and prints out the relevant values to the serial console. The CircuitPython USB Host API is made to mimic PyUSB from CPython.
To read data from the mouse, the code must first scan the connected devices and find one with a boot mouse endpoint. Once a mouse device and endpoint are found, the code will try to read data from them in the main loop. If no data is sent, it will timeout and simply keep trying again until data is present. Once it reads data from the mouse, it will print any buttons that are pressed along with the delta X and delta Y values that represent how far the mouse has been moved and in which directions.
The list BUTTONS
is created with values "left"
, "right"
, and "middle"
. The order and indexes of these values align with the mouse protocol, which will use bits in the same positions to denote whether each button is being pressed or not.
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries # SPDX-License-Identifier: MIT """ This example is made for a basic mouse with two buttons and a wheel that can be pressed. It assumes there is a single mouse connected to USB Host. """ import array import usb.core import adafruit_usb_host_descriptors # button names # This is ordered by bit position. BUTTONS = ["left", "right", "middle"] # scan for connected USB device and loop over any found for device in usb.core.find(find_all=True): # print device info print(f"{device.idVendor:04x}:{device.idProduct:04x}") print(device.manufacturer, device.product) print(device.serial_number) # try to find mouse endpoint on the current device. mouse_interface_index, mouse_endpoint_address = ( adafruit_usb_host_descriptors.find_boot_mouse_endpoint(device) ) if mouse_interface_index is not None and mouse_endpoint_address is not None: mouse = device print( f"mouse interface: {mouse_interface_index} " + f"endpoint_address: {hex(mouse_endpoint_address)}" ) # detach the kernel driver if needed if mouse.is_kernel_driver_active(0): mouse.detach_kernel_driver(0) # set configuration on the mouse so we can use it mouse.set_configuration() break # buffer to hold mouse data buf = array.array("b", [0] * 8) # main loop while True: try: # attempt to read data from the mouse # 20ms timeout, so we don't block long if there # is no data count = mouse.read(0x81, buf, timeout=20) except usb.core.USBTimeoutError: # skip the rest of the loop if there is no data continue # string with delta x, y values to print out_str = f"{buf[1]},{buf[2]}" # loop over the button names for i, button in enumerate(BUTTONS): # check if each button is pressed using bitwise AND shifted # to the appropriate index for this button if buf[0] & (1 << i) != 0: # append the button name to the string to show if # it is being clicked. out_str += f" {button}" print(out_str)
Here is a sample output using the Adafruit mouse. If you have a different mouse, the identification information will likely be different, but the functionality should be the same.
Page last edited May 06, 2025
Text editor powered by tinymce.