USB Module

The USB Module is a module that uses the SPI interface to expand USB functionality, implemented with the MAX3421E.

Support the following products:

USB Module

Micropython Example

Note

Before using the following examples, please check the DIP switches on the module to ensure that the pins used in the example match the DIP switch positions. For specific configurations, please refer to the product manual page. The SPI configuration has been implemented internally, so users do not need to worry about it.

Input/Output Pin Control

The module exposes 5 IN (input) pins and 5 OUT (output) pins through headers. This example demonstrates controlling the high and low level switching of the output pins, as well as reading and printing the level status of the input pins.

 1# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
 2#
 3# SPDX-License-Identifier: MIT
 4import os, sys, io
 5import M5
 6from M5 import *
 7from module import USBModule
 8import time
 9
10
11module_usb_0 = None
12last_time = None
13i = None
14last_set_time = None
15value = None
16state = None
17toggle = None
18
19
20def setup():
21    global module_usb_0, last_time, last_set_time, value, state, toggle, i
22    M5.begin()
23    Widgets.fillScreen(0x222222)
24    module_usb_0 = USBModule(pin_cs=1, pin_int=10)
25    module_usb_0.write_gpout(0, 0)
26    module_usb_0.write_gpout(1, 1)
27    module_usb_0.write_gpout(2, 0)
28    module_usb_0.write_gpout(3, 1)
29    module_usb_0.write_gpout(4, 0)
30    state = [0] * 5
31    toggle = True
32
33
34def loop():
35    global module_usb_0, last_time, last_set_time, value, state, toggle, i
36    M5.update()
37    module_usb_0.poll_data()
38    if (time.ticks_diff((time.ticks_ms()), last_time)) > 200:
39        last_time = time.ticks_ms()
40        for i in range(5):
41            value = module_usb_0.read_gpin(i)
42            state[int((i + 1) - 1)] = value
43        print(state)
44    if (time.ticks_diff((time.ticks_ms()), last_set_time)) > 1000:
45        last_set_time = time.ticks_ms()
46        if toggle:
47            for i in range(5):
48                module_usb_0.write_gpout(i, 1)
49        else:
50            for i in range(5):
51                module_usb_0.write_gpout(i, 0)
52        toggle = not toggle
53
54
55if __name__ == "__main__":
56    try:
57        setup()
58        while True:
59            loop()
60    except (Exception, KeyboardInterrupt) as e:
61        try:
62            from utility import print_error_msg
63
64            print_error_msg(e)
65        except ImportError:
66            print("please update to latest firmware")

Mouse

Implementing USB host to capture mouse input

 1# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
 2#
 3# SPDX-License-Identifier: MIT
 4import os, sys, io
 5import M5
 6from M5 import *
 7from module import USBModule
 8
 9
10title0 = None
11label_x = None
12label_y = None
13module_usb_0 = None
14x = None
15y = None
16mouse_move = None
17dx = None
18dy = None
19
20
21def setup():
22    global title0, label_x, label_y, module_usb_0, x, y, mouse_move, dx, dy
23    M5.begin()
24    Widgets.fillScreen(0x222222)
25    title0 = Widgets.Title(
26        "Module USB Example mouse", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18
27    )
28    label_x = Widgets.Label("x", 130, 90, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
29    label_y = Widgets.Label("y", 180, 90, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
30    module_usb_0 = USBModule(pin_cs=1, pin_int=10)
31    x = 0
32    y = 0
33
34
35def loop():
36    global title0, label_x, label_y, module_usb_0, x, y, mouse_move, dx, dy
37    module_usb_0.poll_data()
38    if module_usb_0.is_left_btn_pressed():
39        print("click left")
40    if module_usb_0.is_right_btn_pressed():
41        print("click right")
42    if module_usb_0.is_middle_btn_pressed():
43        print("click middle")
44    mouse_move = module_usb_0.read_mouse_move()
45    dx = mouse_move[0]
46    dy = mouse_move[1]
47    if dx != 0 or dy != 0:
48        print((str("move: ") + str((str(dx) + str((str(", ") + str(dy)))))))
49        x = min(max(x + dx, 0), 320)
50        y = min(max(y + dy, 0), 240)
51        label_x.setText(str(x))
52        label_y.setText(str(y))
53
54
55if __name__ == "__main__":
56    try:
57        setup()
58        while True:
59            loop()
60    except (Exception, KeyboardInterrupt) as e:
61        try:
62            from utility import print_error_msg
63
64            print_error_msg(e)
65        except ImportError:
66            print("please update to latest firmware")

Keyboard

Implementing USB host to capture keyboard input

 1# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
 2#
 3# SPDX-License-Identifier: MIT
 4import os, sys, io
 5import M5
 6from M5 import *
 7from module import USBModule
 8
 9
10module_usb_0 = None
11modifier = None
12indata = None
13
14
15def setup():
16    global module_usb_0, modifier, indata
17    M5.begin()
18    Widgets.fillScreen(0x222222)
19    module_usb_0 = USBModule(pin_cs=1, pin_int=10)
20
21
22def loop():
23    global module_usb_0, modifier, indata
24    M5.update()
25    module_usb_0.poll_data()
26    modifier = module_usb_0.read_kb_modifier()
27    if modifier & 0x01:
28        print("Left Control pressed")
29    if modifier & 0x02:
30        print("Left Shift pressed")
31    if modifier & 0x04:
32        print("Left Alt pressed")
33    if modifier & 0x08:
34        print("Left GUI pressed")
35    if modifier & 0x10:
36        print("Right Control pressed")
37    if modifier & 0x20:
38        print("Right Shift pressed")
39    if modifier & 0x40:
40        print("Right Alt pressed")
41    if modifier & 0x80:
42        print("Right GUI pressed")
43    indata = module_usb_0.read_kb_input(True)
44    if indata:
45        print(indata)
46
47
48if __name__ == "__main__":
49    try:
50        setup()
51        while True:
52            loop()
53    except (Exception, KeyboardInterrupt) as e:
54        try:
55            from utility import print_error_msg
56
57            print_error_msg(e)
58        except ImportError:
59            print("please update to latest firmware")

UIFlow2.0 Example

Input/Output Pin Control

gpio_example.png

cores3_module_usb_gpio_example.m5f2

Mouse

mouse_example.png

cores3_module_usb_mouse_example.m5f2

Keyboard

kb_example.png

cores3_module_usb_kb_example.m5f2

class USBModule

Constructors

class USBModule(pin_cs: int = 1, pin_int: int = 10)
Parameters:
  • pin_cs (int) – (RST) 复位引脚

  • pin_irq (int) – (INT) 中断引脚

UIFLOW2:

init.png

poll_data()

poll data

Note: It needs to be called in the main loop

UIFlow2.0

poll_data.png

is_left_btn_pressed() bool

Check if the left mouse button is pressed.

UIFlow2.0

is_left_btn_pressed.png

is_right_btn_pressed() bool

Check if the right mouse button is pressed.

UIFlow2.0

is_right_btn_pressed.png

is_middle_btn_pressed() bool

Check if the middle mouse button is pressed.

UIFlow2.0

is_middle_btn_pressed.png

is_forward_btn_pressed() bool

Check if the forward mouse button is pressed.

UIFlow2.0

is_forward_btn_pressed.png

is_back_btn_pressed() bool

Check if the back mouse button is pressed.

UIFlow2.0

is_back_btn_pressed.png

read_mouse_move() tuple[int, int]

Read Mouse Cursor Movement

Returns a tuple (x, y) containing the horizontal displacement x and vertical displacement y of the mouse; x range: -127 to 127; 0 indicates no movement, negative values indicate movement to the left, and positive values indicate movement to the right; y range: -127 to 127; 0 indicates no movement, negative values indicate movement upward, and positive values indicate movement downward.

Example:

move = usb_module.read_mouse_move()
x = move[0]
y = move[1]

UIFlow2.0

read_mouse_move.png

read_wheel_move() int

Read Mouse Wheel Movement

Returns a value in the range of -127 to 127, 0 indicates no movement, Positive values indicate forward scrolling, Negative values indicate backward scrolling.

UIFlow2.0

read_wheel_move.png

read_kb_input(convert: bool = True) list

Read keyboard input

  • convert Whether to convert HID Keycode to the corresponding string.

Returns a list containing keyboard inputs (up to 6 elements, meaning a maximum of 6 key values can be input at once).

Example:

res = usb_module.read_kb_input(convert=True)
# output ['a', 'b', 'Enter']

res = usb_module.read_kb_input(convert=False)
# output [0x04, 0x05, 0x28]

UIFlow2.0

read_kb_input.png

read_kb_modifier() int

Read the keyboard modifier keys, namely “Ctrl”, “Shift”, “Alt”, and “Win” keys.

  • Return: The status of the keyboard modifier keys, usually represented by a bit mask to indicate the status of different modifier keys.
    • 0x01: Left Control key

    • 0x02: Left Shift key

    • 0x04: Left Alt key

    • 0x08: Left Windows key (Left GUI)

    • 0x10: Right Control key

    • 0x20: Right Shift key

    • 0x40: Right Alt key

    • 0x80: Right Windows key (Right GUI)

Example:

modifier = module_usb.read_kb_modifier()
if modifier & 0x01:
    print("left ctrl key pressed")

UIFlow2.0

read_kb_modifier.png

read_gpin(pin) int

Read input pin value

  • pin pin number

  • Return 1 represents high level, and 0 represents low level.

UIFlow2.0

read_gpin.png

write_gpout(pin, value)

Write output pin value

  • pin pin number

  • Return 1 represents high level, and 0 represents low level.

UIFlow2.0

write_gpout.png