跳到正文
XiaoGao 的个人博客

NO.22 · 机器人

双轴步进电机同步运动控制:Sync_CalcParams 与 AVR446 梯形加减速

双轴步进电机同步运动控制完整工程——Sync_CalcParams 参数比例缩放实现两轴同时启停,AVR446 整数递推梯形加减速无浮点规划速度曲线,ESP8266 无线透传 + Python 上位机实时轨迹可视化。

发布 DATE
字数 WORDS
1,186
阅读 READ
3 分钟

两轴各走各的梯形曲线,步数不同就会不同时停。这个项目用一个漂亮的数学观察解决了同步问题:只要两轴的 speed/accel、speed/decel 相同,三段运动时间就完全一致——于是把从轴参数按步数比例统一缩放即可。全整数运算,无浮点、无查表。

系统架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌───────────────────────────┐   TCP :5000    ┌───────────────────────────┐
│ Python 上位机 │ <============> │ ESP8266(TCP 透传) │
│ 指令下发 / 轨迹可视化 │ └─────────────┬─────────────┘
└───────────────────────────┘ │ USART3 115200
v
┌──────────────────────────────────────────────────────────────────────┐
│ STM32F103VET6 │
│ │
│ USART3 中断(IDLE 帧判定)→ 指令解析(8 参数) │
│ → Sync_CalcParams 双轴同步算法(参数缩放) │
│ → MSD_Move1 / MSD_Move2 同时启动 │
│ │
│ TIM3 中断 → 电机 1 脉冲(加速 / 匀速 / 减速状态机) │
│ TIM4 中断 → 电机 2 脉冲(加速 / 匀速 / 减速状态机) │
│ │
│ USART1 115200 → 调试信息打印 │
└──────────────────────────────────────────────────────────────────────┘

核心算法一:Sync_CalcParams 双轴同步

问题:两轴各自独立执行梯形加减速时,若步数不同,就会在不同时刻停止,无法同步到达。

原理:梯形速度曲线的关键时间参数为:

1
2
t_accel = speed / accel      (加速段时间)
t_decel = speed / decel (减速段时间)

只要两轴的 speed/accel、speed/decel 相同,三段运动时间就完全一致。因此选出步数较多的轴为主轴(参数不变),从轴的速度与加/减速度统一乘以步数比例:

1
2
3
4
ratio       = steps_slave / steps_master
speed_slave = speed_master × ratio
accel_slave = accel_master × ratio
decel_slave = decel_master × ratio

ratio 在时间公式中被约去:t = (speed×ratio) / (accel×ratio) = speed / accel,从轴在时间轴上与主轴完全对齐。步数相差多少,缩放比例就是多少,与方向无关。

示例:2000 200 200 75 | 1000 200 200 75

参数 电机 1(主轴) 电机 2(从轴,缩放后)
步数 2000 1000
速度 75 75 × 0.5 = 37
加速度 200 200 × 0.5 = 100
减速度 200 200 × 0.5 = 100

电机 2 以一半的速度、一半的加速度走一半的路程,与电机 1 同时出发、同时到达。

工程保护:缩放乘法用 32 位中间量防溢出,缩放结果下限钳位为 1 杜绝除零,步数为 0 的轴跳过计算,步数取绝对值比较(方向不影响同步)。

核心算法二:AVR446 整数梯形加减速

速度规划基于 Atmel AVR446 应用笔记的整数算法,全部整数乘除与平方根查算:

1
2
3
4
min_delay  = A_T_x100 / speed                            # 最高速度最小脉冲间隔
step_delay = T1_FREQ_148 × sqrt(A_SQ / accel) / 100 # 加速度首步脉冲间隔
max_s_lim = speed² / (A_x20000 × accel / 100) # 达到最高速度所需步数
accel_lim = step × decel / (accel + decel) # 开始减速的临界步数

定时器中断内以递推方式逼近理论速度曲线:

1
2
new_delay = delay - (2 × delay + rest) / (4 × accel_count + 1)
rest = (2 × delay + rest) % (4 × accel_count + 1)

余数 rest 携带到下一次迭代,使整数运算不产生累计误差:

1
2
STOP ──> ACCEL ──> RUN ──> DECEL ──> STOP
启动 加速段 匀速段 减速段 到达目标步数

每个脉冲下降沿完成一次状态评估与延时更新(软件步进计数),保证双轴脉冲互不干扰。

通信协议

文本指令协议:8 个整数、空格分隔、\r\n 结尾,以 IDLE 空闲中断判定帧结束,无帧头帧尾开销。

1
2
3
step1 accel1 decel1 speed1 step2 accel2 decel2 speed2

示例:2000 200 200 75 1000 200 200 75

用户只需给出两轴各自步数与主轴速度参数,从轴参数由固件自动按比例缩放。

硬件与软件

器件 说明
MCU STM32F103VET6(Cortex-M3,72 MHz,512 KB Flash)
执行机构 微步细分步进电机驱动器 ×2(PUL / DIR / ENA)
无线模块 ESP8266(AT 固件,STA 模式 TCP 客户端)

固件架构:裸机前后台——中断负责实时脉冲输出与串口不定长帧接收,主循环负责指令解析与运动调度,全程无阻塞延时。双定时器独立中断通道(TIM3/TIM4)驱动两轴,时基精度 1 µs;DWT 周期计数器实现微秒级精确延时;ESP8266 检测到 CLOSED 后自动重连。

Python 上位机(server.py):TCP 服务器(端口 5000)+ Matplotlib 实时可视化——按脉冲当量(默认 2000 步/cm)换算位移,实时绘制双轴位置与运动轨迹,移动记录持久化,后台线程打印 STM32 调试信息。

一个值得记住的细节

两轴步数相差越悬殊,从轴速度越低;低速时梯形曲线可能退化为纯加减速(无匀速段),但时间同步仍然成立——因为同步的前提是时间参数比例一致,而不是速度曲线形状一致。这个不变量是整套算法能够成立的关键。

仓库

    ↑↓ 选择↵ 打开>theme · >random · >top · >archive