【静音步进电机控制实践过程帖】网页上位机设计
本文介绍了 TMC2209 步进电机驱动板结合树莓派Pico实现串口控制,进一步设计Web网页上位机实现步进电机的可视化UI界面控制的项目设计,包括硬件连接、串口指令控制、网页上位机设计等。
项目介绍
硬件连接:TMC2209 模块、扩展板、树莓派Pico扩展板、OLED、系统接线示意图、实物图;
工程测试:MicoPython 编程,实现串口 JSON 指令控制步进电机旋转方向、角度和速度;
网页设计:Web 界面及功能模块设计,连接串口并发送 JSON 消息,实现步进电机的转速和角度控制。
硬件连接
包括 TMC2209、OLED、步进电机、树莓派Pico的接线方式。
TMC2209
TMC2209 模块与树莓派 Pico 的接线方式如下
| TMC2209 | RPi Pico | Note |
| Dir | GP 16 | Direction |
| Step | GP 17 | Step pulse |
| EN | GP 18 | Enable |
| GND | GND | Ground |
| VIO | 3V3 | Power |
TMC2209 与步进电机的接线方式与相序判断方法详见:【静音步进电机控制实践过程帖】树莓派Pico扩展板设计 .
UART
| USB-TTL | RPi Pico | Note |
| TXD | GP1 (RX) | Transmite |
| RXD | GP0 (TX) | Receive |
| GND | GND | Ground |
系统连接


实物连接效果如下


OLED 连接详见:【静音步进电机控制实践过程帖】树莓派Pico扩展板设计 .
流程图


工程代码
运行 Thonny IDE 新建文件,添加如下代码
'''
电机:42步进电机
电压:直流12V
步距角:1.8度
细分:8
'''
from machine import Pin, I2C, UART
import ssd1306
import time
import ujson
# ==== Define hardware pinout =====
dir_pin = Pin(16, Pin.OUT)
step_pin = Pin(17, Pin.OUT)
en_pin = Pin(18, Pin.OUT)
# Initialize OLED I2C
i2c = I2C(0, scl=Pin(5), sda=Pin(4))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# Initialize UART
uart = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1))
# ======== Angle Calculation ==========
step_angle = 1.8 # 步距角
step_cycle = 360 / 1.8 # 360 / 1.8 = 200 步/圈
# microstep mode, default is 1/8 so 8
# another ex: 1/16 microstep would be 16
microMode = 8
# full rotation multiplied by the microstep divider
steps = step_cycle * microMode # 200 * 8细分 = 1600 脉冲/圈
# n 脉冲/度
STEPS_PER_DEGREE = steps / 360
# ======== OLED Display ===========
def display_motor(status="READY", angle=0.0, speed=1200, dir_str="STOP"):
oled.fill(0)
oled.text("==== MOTOR ====", 0, 0)
oled.text(f"Status: {status}", 0, 15)
oled.text(f"Angle: {angle:.1f} deg", 0, 27)
oled.text(f"Direction: {dir_str}", 0, 39)
oled.text(f"Speed: {speed}us", 0, 51)
oled.show()
# ======= Motor Control =========
def rotate_angle(angle, speed_us):
en_pin.value(0)
dir_pin.value(angle > 0) # Rotate direction
dir_str = "CW" if angle > 0 else "CCW"
display_motor("RUN", angle, speed_us, dir_str) # rotate direction display
target_angle = abs(angle)
total_steps = int(target_angle * STEPS_PER_DEGREE) # rotate steps
# Start rotate
for _ in range(total_steps):
step_pin.value(1)
time.sleep_us(speed_us)
step_pin.value(0)
time.sleep_us(speed_us)
print("Rotate %.1f degree i.e. %d steps" % (angle, total_steps))
release()
display_motor("STOP", angle, speed_us, dir_str)
def release():
en_pin.value(1)
# ======== UART Control =========
def uart_control():
while True:
if uart.any():
cmd = uart.read()
try:
data = ujson.loads(cmd)
angle = float(data['angle'])
speed = int(data.get('speed', 1200))
rotate_angle(angle, speed)
uart.write('OK\r\n')
except:
uart.write('Invalid command\r\n')
release()
else:
release()
time.sleep_ms(50)
# ======== main ==========
display_motor()
while True:
uart_control()保存代码。
串口指令
Thonny IDE 运行 stepper_uart_control.py 程序;
打开串口调试助手软件,发送 JSON 格式的旋转方向、角度和速度指令 {"angle": 90, "speed": 1500} ;


通过角度数值的正负控制旋转方向;
步进电机按照串口 JSON 指令,以目标速度旋转目标角度。
网页设计
网页设计包括串口配置、发送测试、运行测试、运行日志等模块。
上位机代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>步进电机 Web Serial 控制器</title>
<style>
* {box-sizing: border-box; font-family: Arial, sans-serif;}
body {max-width: 480px; margin: 20px auto; padding: 0 15px; background: #f5f5f5;}
.card {background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); margin-bottom: 15px;}
h2 {text-align: center; color: #333; margin-top: 0;}
.group {margin: 12px 0;}
label {display: block; margin-bottom: 6px; font-weight: bold; color: #555;}
input {width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px;}
button {width: 100%; padding: 12px; border: none; border-radius: 6px; font-size: 16px; color: white; margin: 5px 0; cursor: pointer;}
.btn-connect {background: #007bff;}
.btn-send {background: #28a745;}
.btn-stop {background: #dc3545;}
.log {background: #1e1e1e; color: #dcdcaa; padding: 10px; height: 160px; border-radius: 6px; overflow-y: auto; font-size: 14px; line-height: 1.4;}
</style>
</head>
<body>
<div>
<h2>步进电机控制器</h2>
<div>
<label>旋转角度(正数=CW,负数=CCW)</label>
<input type="number" id="angle" value="180" step="0.1">
</div>
<div>
<label>速度(单位:us,越小越快)</label>
<input type="number" id="speed" value="1000" min="200" max="5000">
</div>
<button id="connect">连接串口</button>
<button id="send">发送指令</button>
<div id="log"></div>
</div>
<script>
let port;
let reader;
let logBox = document.getElementById('log');
function log(msg) {
logBox.innerHTML += msg + '<br>';
logBox.scrollTop = logBox.scrollHeight;
}
document.getElementById('connect').addEventListener('click', async () => {
try {
port = await navigator.serial.requestPort();
await port.open({ baudRate: 115200 });
log('✅ 串口已连接 (115200)');
reader = port.readable.getReader();
readLoop();
} catch (e) {
log('连接失败:' + e.message);
}
});
async function readLoop() {
while (true) {
try {
const { value, done } = await reader.read();
if (done) break;
let decoder = new TextDecoder();
let data = decoder.decode(value);
log('← ' + data.trim());
} catch (e) {
log('读取失败');
break;
}
}
}
document.getElementById('send').addEventListener('click', async () => {
if (!port) {
log('请先连接串口');
return;
}
let angle = parseFloat(document.getElementById('angle').value);
let speed = parseInt(document.getElementById('speed').value);
let cmd = JSON.stringify({ angle, speed });
const encoder = new TextEncoder();
const writer = port.writable.getWriter();
await writer.write(encoder.encode(cmd));
writer.releaseLock();
log('→ ' + cmd);
});
</script>
</body>
</html>保存代码。
控制方案
双击打开网页,或使用浏览器加载 HTML 文件;
点击连接串口按钮,选择目标串口并连接;
设置目标旋转角度、速度;
点击发送指令按钮,步进电机转动,完成后反馈 OK 字样;


动态演示
Web 网页上位机运行后,步进电机按照设定的角度和速度旋转;


总结
本文介绍了 TMC2209 步进电机驱动板结合树莓派Pico实现串口控制,进一步设计Web网页上位机实现步进电机的可视化UI界面控制的项目设计,包括硬件连接、串口指令控制、网页上位机设计等,为相关产品的快速开发和应用设计提供了参考。
我要赚赏金
