Skip to content

Commit b8f6058

Browse files
committed
basic mouse circuitpython example
1 parent 5fe76b9 commit b8f6058

File tree

1 file changed

+70
-0
lines changed
  • USB_Host_Examples/CircuitPython_Mouse_Basic

1 file changed

+70
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
"""
4+
This example is made for a basic mouse with
5+
two buttons and a wheel that can be pressed.
6+
7+
It assumes there is a single mouse connected to USB Host.
8+
"""
9+
import array
10+
import usb.core
11+
import adafruit_usb_host_descriptors
12+
13+
# button names
14+
# This is ordered by bit position.
15+
BUTTONS = ["left", "right", "middle"]
16+
17+
# scan for connected USB device and loop over any found
18+
for device in usb.core.find(find_all=True):
19+
# print device info
20+
print(f"{device.idVendor:04x}:{device.idProduct:04x}")
21+
print(device.manufacturer, device.product)
22+
print(device.serial_number)
23+
24+
# try to find mouse endpoint on the current device.
25+
mouse_interface_index, mouse_endpoint_address = (
26+
adafruit_usb_host_descriptors.find_boot_mouse_endpoint(device)
27+
)
28+
if mouse_interface_index is not None and mouse_endpoint_address is not None:
29+
mouse = device
30+
print(
31+
f"mouse interface: {mouse_interface_index} "
32+
+ f"endpoint_address: {hex(mouse_endpoint_address)}"
33+
)
34+
35+
# detach the kernel driver if needed
36+
if mouse.is_kernel_driver_active(0):
37+
mouse.detach_kernel_driver(0)
38+
39+
# set configuration on the mouse so we can use it
40+
mouse.set_configuration()
41+
42+
break
43+
44+
# buffer to hold mouse data
45+
buf = array.array("b", [0] * 8)
46+
47+
# main loop
48+
while True:
49+
try:
50+
# attempt to read data from the mouse
51+
# 10ms timeout, so we don't block long if there
52+
# is no data
53+
count = mouse.read(0x81, buf, timeout=10)
54+
except usb.core.USBTimeoutError:
55+
# skip the rest of the loop if there is no data
56+
continue
57+
58+
# string with delta x, y values to print
59+
out_str = f"{buf[1]},{buf[2]}"
60+
61+
# loop over the button names
62+
for i, button in enumerate(BUTTONS):
63+
# check if each button is pressed using bitwise AND shifted
64+
# to the appropriate index for this button
65+
if buf[0] & (1 << i) != 0:
66+
# append the button name to the string to show if
67+
# it is being clicked.
68+
out_str += f" {button}"
69+
70+
print(out_str)

0 commit comments

Comments
 (0)