Servo2 Module

Servo2 is an updated servo driver module in the M5Stack stackable module series. It uses a PCA9685 16-channel PWM controller to drive up to 16 servos simultaneously. Power input is 6–12 V DC, with two SY8368AQQC chips for step-down regulation.

Support the following products:

Servo2Module

UiFlow2 Example

Servo angle control

Open the m5core_module_servo2_example.m5f2 project in UiFlow2.

This example initializes the Servo2 module on the I2C bus, drives two servo channels, and shows the current angle on screen. Button A sets both servos to 0°, Button B to 45°, and Button C to 90°; one channel is released after setup.

UiFlow2 Code Block:

m5core_module_servo2_example.png

Example output:

None

MicroPython Example

Servo angle control

This example initializes the Servo2 module on the I2C bus, drives two servo channels, and shows the current angle on screen. Button A sets both servos to 0°, Button B to 45°, and Button C to 90°; one channel is released after setup.

MicroPython Code Block:

 1# SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
 2#
 3# SPDX-License-Identifier: MIT
 4
 5import os, sys, io
 6import M5
 7from M5 import *
 8from module import Servo2Module
 9
10
11
12title = None
13label_angle = None
14servo2_0 = None
15angle = None
16
17
18def btna_was_clicked_event(state):
19  global title, label_angle, servo2_0, angle
20  angle = 0
21  label_angle.setText(str((str('Angle: ') + str(angle))))
22  servo2_0.position(1, degrees=angle)
23  servo2_0.position(2, degrees=angle)
24
25
26def btnb_was_clicked_event(state):
27  global title, label_angle, servo2_0, angle
28  angle = 45
29  label_angle.setText(str((str('Angle: ') + str(angle))))
30  servo2_0.position(1, degrees=angle)
31  servo2_0.position(2, degrees=angle)
32
33
34def btnc_was_clicked_event(state):
35  global title, label_angle, servo2_0, angle
36  angle = 90
37  label_angle.setText(str((str('Angle: ') + str(angle))))
38  servo2_0.position(1, degrees=angle)
39  servo2_0.position(2, degrees=angle)
40
41
42def setup():
43  global title, label_angle, servo2_0, angle
44
45  M5.begin()
46  Widgets.setRotation(1)
47  Widgets.fillScreen(0x222222)
48  title = Widgets.Title("Module Servo2 Example", 3, 0xffffff, 0x0000FF, Widgets.FONTS.DejaVu24)
49  label_angle = Widgets.Label("Angle: ", 46, 98, 1.0, 0xffffff, 0x222222, Widgets.FONTS.DejaVu24)
50
51  BtnA.setCallback(type=BtnA.CB_TYPE.WAS_CLICKED, cb=btna_was_clicked_event)
52  BtnB.setCallback(type=BtnB.CB_TYPE.WAS_CLICKED, cb=btnb_was_clicked_event)
53  BtnC.setCallback(type=BtnC.CB_TYPE.WAS_CLICKED, cb=btnc_was_clicked_event)
54
55  servo2_0 = Servo2Module(0x40, 50, 400, 2350, 180)
56  angle = 0
57  label_angle.setText(str((str('Angle: ') + str(angle))))
58  servo2_0.position(1, degrees=angle)
59  servo2_0.position(2, degrees=angle)
60  servo2_0.release(0)
61
62
63def loop():
64  global title, label_angle, servo2_0, angle
65  M5.update()
66
67
68if __name__ == '__main__':
69  try:
70    setup()
71    while True:
72      loop()
73  except (Exception, KeyboardInterrupt) as e:
74    try:
75      from utility import print_error_msg
76      print_error_msg(e)
77    except ImportError:
78      print("please update to latest firmware")

Example output:

None

API

Servo2Module

class module.Servo2Module(address=0x40, freq=50, min_us=400, max_us=2350, degrees=180)

Create a Servo2 module instance on the I2C bus.

Parameters:
  • address (int) – I2C address of the PCA9685 (default 0x40).

  • freq (int) – PWM frequency in Hz (default 50).

  • min_us (int) – Minimum pulse width in microseconds (default 400).

  • max_us (int) – Maximum pulse width in microseconds (default 2350).

  • degrees (int) – Maximum angle in degrees (default 180).

UiFlow2 Code Block:

init.png

MicroPython Code Block:

from module import Servo2Module

servo2 = Servo2Module(address=0x40, freq=50, min_us=400, max_us=2350, degrees=180)
position(index, degrees=None, radians=None, us=None, duty=None)

Set the servo position for the given channel.

Parameters:
  • index (int) – Channel index (0-15).

  • degrees (float) – Angle in degrees (optional).

  • radians (float) – Angle in radians (optional).

  • us (int) – Pulse width in microseconds (optional).

  • duty (float) – Duty cycle in percent (optional). Exactly one of degrees, radians, us, or duty may be given.

UiFlow2 Code Block:

set_degrees.png

set_duty.png

set_pulse_width.png

set_radians.png

MicroPython Code Block:

servo2.position(0, degrees=90)
servo2.position(0, duty=50)
servo2.position(0, us=1500)
servo2.position(0, radians=1.57)
release(index)

Release the servo (stop driving the channel).

Parameters:

index (int) – Channel index (0–15).

UiFlow2 Code Block:

release.png

MicroPython Code Block:

servo2.release(0)
deinit()

Release the module. No-op for Servo2Module; provided for compatibility.

MicroPython Code Block:

servo2.deinit()