EncoderMotor Driver Unit
EncoderMotorDriverUnit 类通过 I2C 控制 Unit EncoderMotor Driver,支持电机正反转的开环 PWM 控制、位置控制、速度控制、编码器反馈、电机休眠、软启动和软停止、RGB LED 控制及输入电压和电流监测。
支持以下产品:
UiFlow2 应用示例
基本电机控制
在 UiFlow2 中打开 m5cores3_unit_encoder_motor_driver_basic_example.m5f2 项目。
选择 CoreS3 作为主机,将 Unit 连接到 Port A 端口(SDA=G2、SCL=G1,I2C 频率为 100 kHz)。Unit 的默认地址为 0x2F。
m5ui 页面提供三个触摸按键:
+:每按一次,PWM 控制值加 20;当前值为 80 时,再按一次归零。
-:每按一次,PWM 控制值减 20;当前值为 -80 时,再按一次归零。
STOP:将 PWM 控制值归零,停止电机。
PWM 控制值的正负表示相反的转动方向,绝对值表示占空比百分数。屏幕中央显示当前设置值,范围为 -80~80,初始值为 0;此处显示的是 PWM 设置值,而非转速或编码器计数。
备注
本示例使用 Unit 默认的开环模式,电机驱动需处于启用状态。若之前的程序切换到了闭环模式或禁用了驱动,请先调用 set_motor_mode(MODE_OPEN_LOOP) 切回开环模式,并调用 enable_motor() 启用驱动。重启 Unit 也可恢复这些默认设置。运行前请接好电机电源,结束示例前请按 STOP 停止电机。
UiFlow2 代码块:
示例输出:
CoreS3 屏幕显示当前的 PWM 设置值。例如,启动后连续按两次 +,屏幕显示
40;按 STOP 后显示0。
MicroPython 应用示例
基本电机控制
按上述方式接线并设置 Unit 后,在 CoreS3 上运行以下示例。+、- 和 STOP 按键的功能与 UiFlow2 项目相同。
MicroPython 代码块:
1# SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD 2# 3# SPDX-License-Identifier: MIT 4 5import os, sys, io 6import M5 7from M5 import * 8import m5ui 9import lvgl as lv 10from unit import EncoderMotorDriverUnit 11from hardware import Pin 12from hardware import I2C 13 14 15page0 = None 16label_title = None 17button_speed_up = None 18button_speed_down = None 19label_speed = None 20button_stop = None 21i2c0 = None 22encodermotordriver_0 = None 23speed = None 24 25 26def button_stop_short_clicked_event(event_struct): 27 global \ 28 page0, \ 29 label_title, \ 30 button_speed_up, \ 31 button_speed_down, \ 32 label_speed, \ 33 button_stop, \ 34 i2c0, \ 35 encodermotordriver_0, \ 36 speed 37 speed = 0 38 encodermotordriver_0.set_motor_pwm_duty(speed) 39 label_speed.set_text(str(speed)) 40 41 42def button_speed_up_short_clicked_event(event_struct): 43 global \ 44 page0, \ 45 label_title, \ 46 button_speed_up, \ 47 button_speed_down, \ 48 label_speed, \ 49 button_stop, \ 50 i2c0, \ 51 encodermotordriver_0, \ 52 speed 53 if speed < 80: 54 speed = speed + 20 55 else: 56 speed = 0 57 encodermotordriver_0.set_motor_pwm_duty(speed) 58 label_speed.set_text(str(speed)) 59 60 61def button_speed_down_short_clicked_event(event_struct): 62 global \ 63 page0, \ 64 label_title, \ 65 button_speed_up, \ 66 button_speed_down, \ 67 label_speed, \ 68 button_stop, \ 69 i2c0, \ 70 encodermotordriver_0, \ 71 speed 72 if speed > -80: 73 speed = speed - 20 74 else: 75 speed = 0 76 encodermotordriver_0.set_motor_pwm_duty(speed) 77 label_speed.set_text(str(speed)) 78 79 80def button_stop_event_handler(event_struct): 81 global \ 82 page0, \ 83 label_title, \ 84 button_speed_up, \ 85 button_speed_down, \ 86 label_speed, \ 87 button_stop, \ 88 i2c0, \ 89 encodermotordriver_0, \ 90 speed 91 event = event_struct.code 92 if event == lv.EVENT.SHORT_CLICKED and True: 93 button_stop_short_clicked_event(event_struct) 94 return 95 96 97def button_speed_up_event_handler(event_struct): 98 global \ 99 page0, \ 100 label_title, \ 101 button_speed_up, \ 102 button_speed_down, \ 103 label_speed, \ 104 button_stop, \ 105 i2c0, \ 106 encodermotordriver_0, \ 107 speed 108 event = event_struct.code 109 if event == lv.EVENT.SHORT_CLICKED and True: 110 button_speed_up_short_clicked_event(event_struct) 111 return 112 113 114def button_speed_down_event_handler(event_struct): 115 global \ 116 page0, \ 117 label_title, \ 118 button_speed_up, \ 119 button_speed_down, \ 120 label_speed, \ 121 button_stop, \ 122 i2c0, \ 123 encodermotordriver_0, \ 124 speed 125 event = event_struct.code 126 if event == lv.EVENT.SHORT_CLICKED and True: 127 button_speed_down_short_clicked_event(event_struct) 128 return 129 130 131def setup(): 132 global \ 133 page0, \ 134 label_title, \ 135 button_speed_up, \ 136 button_speed_down, \ 137 label_speed, \ 138 button_stop, \ 139 i2c0, \ 140 encodermotordriver_0, \ 141 speed 142 143 M5.begin() 144 Widgets.setRotation(0) 145 m5ui.init() 146 page0 = m5ui.M5Page(bg_c=0x000000) 147 label_title = m5ui.M5Label( 148 "Encoder Motor Control", 149 x=20, 150 y=5, 151 text_c=0x079EE1, 152 bg_c=0xFFFFFF, 153 bg_opa=0, 154 font=lv.font_montserrat_24, 155 parent=page0, 156 ) 157 button_speed_up = m5ui.M5Button( 158 text="+", 159 x=50, 160 y=165, 161 bg_c=0x2196F3, 162 text_c=0xFFFFFF, 163 font=lv.font_montserrat_24, 164 parent=page0, 165 ) 166 button_speed_down = m5ui.M5Button( 167 text="-", 168 x=230, 169 y=165, 170 bg_c=0x2196F3, 171 text_c=0xFFFFFF, 172 font=lv.font_montserrat_24, 173 parent=page0, 174 ) 175 label_speed = m5ui.M5Label( 176 "00", 177 x=132, 178 y=75, 179 text_c=0x079EE1, 180 bg_c=0xFFFFFF, 181 bg_opa=0, 182 font=lv.font_montserrat_40, 183 parent=page0, 184 ) 185 button_stop = m5ui.M5Button( 186 text="STOP", 187 x=112, 188 y=165, 189 bg_c=0xF32121, 190 text_c=0xFFFFFF, 191 font=lv.font_montserrat_24, 192 parent=page0, 193 ) 194 195 button_stop.add_event_cb(button_stop_event_handler, lv.EVENT.ALL, None) 196 button_speed_up.add_event_cb(button_speed_up_event_handler, lv.EVENT.ALL, None) 197 button_speed_down.add_event_cb(button_speed_down_event_handler, lv.EVENT.ALL, None) 198 199 i2c0 = I2C(0, scl=Pin(1), sda=Pin(2), freq=100000) 200 encodermotordriver_0 = EncoderMotorDriverUnit(i2c0, 0x2F) 201 speed = 0 202 encodermotordriver_0.set_motor_pwm_duty(speed) 203 page0.screen_load() 204 205 206def loop(): 207 global \ 208 page0, \ 209 label_title, \ 210 button_speed_up, \ 211 button_speed_down, \ 212 label_speed, \ 213 button_stop, \ 214 i2c0, \ 215 encodermotordriver_0, \ 216 speed 217 M5.update() 218 219 220if __name__ == "__main__": 221 try: 222 setup() 223 while True: 224 loop() 225 except (Exception, KeyboardInterrupt) as e: 226 try: 227 m5ui.deinit() 228 from utility import print_error_msg 229 230 print_error_msg(e) 231 except ImportError: 232 print("please update to latest firmware")
示例输出:
屏幕中央显示当前的 PWM 设置值。未检测到 Unit 时,屏幕会提示检查连接。
API参考
EncoderMotorDriverUnit
- class unit.encoder_motor_driver.EncoderMotorDriverUnit(i2c, address=micropython.const)
基类:
object通过 I2C 控制 Unit EncoderMotor Driver。
Unit 支持电机正反转的开环 PWM 控制、位置控制、速度控制、编码器反馈、电机休眠、软启动和软停止、RGB LED 控制及输入电压和电流监测。驱动使用传入的 I2C 总线,不会关闭该总线。未检测到指定地址时,请检查 Unit 的 Grove 接线、供电和 I2C 地址。
- 参数:
UiFlow2 代码块:

MicroPython 代码块:
from hardware import I2C, Pin from unit import EncoderMotorDriverUnit i2c0 = I2C(0, scl=Pin(1), sda=Pin(2), freq=100000) encodermotordriver_0 = EncoderMotorDriverUnit(i2c0, 0x2F)
电机控制模式常量:
MODE_OPEN_LOOP = 0:开环 PWM 控制。MODE_POSITION = 1:位置控制。MODE_SPEED = 2:速度控制。
编码器相位常量:
ENCODER_MODE_AB = 0:AB 相位顺序。ENCODER_MODE_BA = 1:BA 相位顺序。
- set_motor_mode(mode)
设置电机控制模式。
- 参数:
mode (int) – 使用
MODE_OPEN_LOOP、MODE_POSITION或MODE_SPEED。- 返回:
None.
UiFlow2 代码块:


- set_motor_pwm_duty(percent)
设置电机在开环模式下的 PWM 控制值。
UiFlow2 代码块:

- get_motor_pwm_duty()
获取电机当前的 PWM 控制值。
开环模式下返回设置的 PWM 控制值;闭环模式下,固件可能会根据实时电机输出更新该值。
- 返回:
PWM 控制值,范围为 -100~100。正负表示相反的转动方向,绝对值表示占空比百分数。
- 返回类型:
UiFlow2 代码块:

- read_motor_speed()
读取电机当前的速度读数。
- 返回:
速度读数,可正可负,范围为 -127~127,固件每 20 ms 更新一次。该值未换算为转速(RPM),协议未提供相应的物理单位换算关系。
- 返回类型:
UiFlow2 代码块:

- stop_motor()
停止电机,并将控制模式设为开环模式。
切换模式前后都会将 PWM 控制值清零,避免之前的闭环输出在切换后继续驱动电机。
- 返回:
None.
UiFlow2 代码块:

- read_encoder_count()
读取当前编码器计数,读取操作不会将计数清零。
- 返回:
编码器计数,可正可负,范围为 -2147483648~2147483647。
- 返回类型:
UiFlow2 代码块:

- set_encoder_count(count)
设置当前编码器计数。
- 参数:
count (int) – 编码器计数,可正可负,范围为 -2147483648~2147483647。
- 返回:
None.
UiFlow2 代码块:

- clear_encoder_count()
将编码器计数清零。
- 返回:
None.
UiFlow2 代码块:

- set_encoder_mode(mode)
设置编码器 AB 或 BA 相位顺序。
修改相位顺序后,设置会保存到 Unit 的 Flash 中,并立即触发 Unit 重启。本方法会等待 Unit 重新响应当前 I2C 地址后返回。请避免重复写入相同设置,以减少 Flash 写入次数。
- 参数:
mode (int) – 使用
ENCODER_MODE_AB或ENCODER_MODE_BA。- 返回:
None.
UiFlow2 代码块:


- set_position_pid(kp, ki, kd)
设置位置环 PID 系数。
UiFlow2 代码块:

- get_position_pid()
获取位置环 PID 系数。
- 返回:
PID 系数元组
(kp, ki, kd),依次为比例、积分、微分系数,每项范围均为 0~255。- 返回类型:
UiFlow2 代码块:

- set_position_target_count(count)
设置位置控制的目标位置,以编码器计数为单位。
- 参数:
count (int) – 目标位置,以编码器计数为单位,可正可负,范围为 -2147483648~2147483647。
- 返回:
None.
UiFlow2 代码块:

- get_position_target_count()
获取已设置的目标位置,以编码器计数为单位。
- 返回:
目标位置,以编码器计数为单位,可正可负,范围为 -2147483648~2147483647。
- 返回类型:
UiFlow2 代码块:

- set_position_speed_limit(speed_limit)
设置位置控制时的速度上限。
位置控制使用该设置值的绝对值作为速度上限。该值为设备使用的速度数值,协议未提供其与转速(RPM)的换算关系。
- 参数:
speed_limit (int) – 速度上限设置值,范围为 -127~127,实际限速取该值的绝对值。
- 返回:
None.
UiFlow2 代码块:

- get_position_speed_limit()
获取位置控制时的速度上限设置。
- 返回:
速度上限设置值,范围为 -127~127,实际限速取该值的绝对值。该值为设备使用的速度数值,单位不是转速(RPM)。
- 返回类型:
UiFlow2 代码块:

- set_speed_pid(kp, ki, kd)
设置速度环 PID 系数。
UiFlow2 代码块:

- get_speed_pid()
获取速度环 PID 系数。
- 返回:
PID 系数元组
(kp, ki, kd),依次为比例、积分、微分系数,每项范围均为 0~255。- 返回类型:
UiFlow2 代码块:

- set_speed_target(speed)
设置闭环速度控制的目标值。
- 参数:
speed (int) – 目标速度设置值,可正可负,范围为 -127~127。该值为设备使用的速度数值,单位不是转速(RPM)。
- 返回:
None.
UiFlow2 代码块:

- get_speed_target()
获取已设置的闭环速度控制目标。
- 返回:
目标速度设置值,可正可负,范围为 -127~127。该值为设备使用的速度数值,单位不是转速(RPM)。
- 返回类型:
UiFlow2 代码块:

- enable_soft_start()
在开环模式下启用软启动和软停止。
设置保存在 Unit 的 Flash 中。已启用时重复调用,不会再次写入 Flash。
- 返回:
None.
UiFlow2 代码块:

- disable_soft_start()
在开环模式下禁用软启动和软停止。
设置保存在 Unit 的 Flash 中。已禁用时重复调用,不会再次写入 Flash。
- 返回:
None.
UiFlow2 代码块:

- enable_motor()
启用电机驱动,将 Motor nSleep 切换到运行状态。
- 返回:
None.
UiFlow2 代码块:

- disable_motor()
禁用电机驱动,将 Motor nSleep 切换到休眠状态。
- 返回:
None.
UiFlow2 代码块:

- set_rgb_color(color)
设置板载 RGB LED 颜色。
- 参数:
color (int) –
0xRRGGBB格式的 RGB888 颜色,范围为 0x000000~0xFFFFFF。- 返回:
None.
UiFlow2 代码块:

- get_rgb_color()
获取板载 RGB LED 颜色。
- 返回:
0xRRGGBB格式的 RGB888 颜色,范围为 0x000000~0xFFFFFF。- 返回类型:
UiFlow2 代码块:

- set_rgb_brightness(percent)
设置板载 RGB LED 亮度。
UiFlow2 代码块:

- read_input_voltage_adc()
读取电机供电电压的原始 12 位 ADC 采样值。
- 返回:
原始 ADC 采样值,范围为 0~4095。如需读取以 V 为单位的电压,请使用
read_input_voltage()。- 返回类型:
UiFlow2 代码块:













