简介:EEZYbotARM MK2是一款以4个舵机驱动、具备3自由度运动能力的开源3D打印机械臂,面向电子竞赛选手、高校师生及机器人DIY爱好者,解决传统机械臂制造成本高、结构加工门槛高的问题,可低成本完成机械结构搭建与舵机控制实践。资源包共63个文件,含22个STL格式打印图纸、37张零件预览图片,另有说明文档与授权信息,压缩包整体11.42MB,可直接用于FDM打印机制作全套结构件。目前已有1701人学习下载。图纸覆盖底座、主臂、副臂、连杆、齿轮传动组与夹爪等完整零件,预览图片可辅助核对打印质量与装配顺序。借助开源设计,用户可灵活调整尺寸与结构细节,以远低于成品的成本获得桌面级机械臂本体,适合电子竞赛备赛、教学实验及创客项目参考。
1. EEZYbotARM MK2:一份 STL 图纸,让舵机机械臂从“看看就行”变成“真能抓东西”
三轴舵机机械臂听起来很高端,但 EEZYbotARM MK2 是少有的能把“3D 打印机械臂”从演示视频拉进现实的开源方案:整套机械手结构全部由 STL 文件组成,你只要有一台 FDM 打印机,就能把底座、大臂、小臂、腕部和爪指挨个打出来,再配上几颗标准舵机就能动起来。很多人的第一个六轴机械臂项目就是从这里起步的,也有不少人直接拿它做毕业设计或者 ROS 仿真前的实物对照。它解决的是“没图纸、没参数、不知道从哪下手”的问题——所有零件开箱即打,舵机型号明确,控制逻辑也就是 Arduino 的 Servo 库水平。适合想亲手拆一遍机械臂结构、又不想一上来就碰高成本金属臂的入门者,也适合需要快速搭建实物测试平台的嵌入式工程师。
2. 把 EEZYbotARM MK2 的 STL 图纸变成实打实的塑料零件:切片参数与打印取向
2.1 图纸里有什么:从底座到爪指的文件清单
MK2 的图纸不是一张整体模型,而是按运动关节拆成十几个 STL 文件。拿到压缩包后先别急着全选打印,花十分钟把零件按“结构件、关节件、连接件”分个类,后面能省掉大量返工时间。
典型文件清单长这样:
| 部件 | 数量 | 作用 | 打印要点 |
|---|---|---|---|
| base | 1 | 底座,承载整个机械臂 | 底面大,注意首层附着 |
| turntable | 1 | 底座旋转台 | 外圆需要支撑 |
| shoulder | 1 | 肩关节主体 | 舵机安装孔公差敏感 |
| upper_arm | 1 | 大臂 | 长杆件,注意翘曲 |
| elbow | 1 | 肘关节 | 连接大臂与小臂 |
| forearm | 1 | 小臂 | 内部有舵机槽 |
| wrist | 1 | 腕部 | 小件,注意打印速度 |
| gripper_left / gripper_right | 各1 | 爪指左右 | 对称件,一次打一对 |
| pin / shaft | 若干 | 连接销轴 | 用支撑耗材或紧固件替代 |
打印取向是这类图纸最影响成品质量的地方。底座和旋转台这类大面积零件,我一般把底面平贴打印平台,这样既能省支撑又能保证安装面平整;大臂和小臂这种长条形零件,竖着打强度最好但容易失败,横着打成功率更高——折中方案是把长边沿 Y 轴水平摆放,层间剪切力由填充率兜底。
2.2 切片参数与摆放方向:先保能装,再保好看
MK2 的零件不以“美观”为目标,能用、能装、舵机孔位不打滑才是第一诉求。参数设置上我按 PLA 材料给出一套实测过的起点:
| 参数项 | 推荐值 | 说明 |
|---|---|---|
| 层高 | 0.2 mm | 兼顾表面质量与打印速度,孔位公差稳定 |
| 首层高度 | 0.28 mm | 首层压实,防止底座边缘翘起 |
| 壁厚 | 1.2 mm(3 层) | 舵机安装处受力集中,壁太薄容易裂 |
| 填充率 | 25%~30% | 机械臂需要刚性,200% 没必要,20% 偏软 |
| 支撑类型 | 接触底板支撑 | 圆形舵机孔与沉头孔处必须开支撑 |
| 打印速度 | 40~50 mm/s | 太快容易拉丝,孔位精度下降 |
| 温度 | 205℃ | 常见 PLA 的稳妥区间 |
切片时的支撑策略比温度更关键。MK2 图纸里很多舵机安装孔是垂直向下的圆形通孔,如果没有支撑,孔的上半部分会变成“悬垂”,打出来就是畸形孔位,舵机根本塞不进去。我自己习惯用“接触底板”加“悬垂角度大于 50 度才生成支撑”的组合,这样既保住孔位,又不至于让支撑长得满模型都是。
在 Cura 这类切片软件里可以直接用命令行参数复现这套配置,方便批量调整:
curaengine slice -s layer_height="0.2" -s line_width="0.4" \ -s wall_line_count="3" -s infill_sparse_density="25" \ -s support_enable="true" -s support_type="touching_buildplate" \ -s support_angle="50" -s adhesion_type="skirt" \ -e ceezybotarm_mk2_base.stl这段命令做的事是把刚才表格里的参数一次性传给切片核心:layer_height=0.2控制层高,infill_sparse_density=25让填充率达到 25%,support_type=touching_buildplate表示只生成接触底板的支撑,把孔洞里的无根支撑留给模型自身。实际使用中如果你发现底座底板粘不牢,就把adhesion_type从skirt改成brim,代价是底板边缘多一圈单层薄膜,拆的时候稍微刮一下就行。
打完所有零件后别急着拆支撑。先拿游标卡尺量一下舵机安装槽的宽度:很多打印件打出来比设计尺寸小 0.2~0.4 mm,这是收缩和下料误差,属于正常现象。解决办法不是改图纸,而是用美工刀或者小锉刀把槽内壁微修一下——这是最笨也最有效的方法。
3. 舵机选型与供电:SG90 与 MG996R 的账,以及为什么你的机械臂会“抖”
3.1 舵机选型:先算扭矩,再选 90 度还是 270 度
ETZYbotARM MK2 原设计用的是标准模拟舵机,很多初学者上来就装 SG90,结果大臂抬不起来或一抖一抖,最后归咎于“图纸不稳”。实际上单独一颗 SG90 的扭矩大约是 1.8 kg·cm,驱动 MK2 的大臂在接近水平角度时非常勉强;而 MG996R 的扭矩可以达到 9.4~11 kg·cm,预留了足够余量。选型逻辑很简单:底座和肩关节用大扭矩舵机,爪指这种负载小的地方可以用 SG90,但混用不同舵机时要注意——它们的脉宽映射范围往往不一样,装上去会出现角度偏转不一致的现象。
| 舵机型号 | 扭矩(kg·cm) | 适用位置 | 注意点 |
|---|---|---|---|
| SG90 | 1.8 | 爪指、腕部 | 信号线橙色,电源线红色,地线棕色 |
| MG90S | 2.2 | 爪指、腕部 | 金属齿轮,比 SG90 耐磨损 |
| MG996R | 9.4~11 | 肩关节、肘关节、底座 | 电流大,需要外接电源 |
如果你买的套件里给的是“270 度改装舵机”,那就要警惕了。标准 180 度舵机的输出轴有一个塑料限位块,改装舵机是把这个限位块挖掉了,让齿轮能旋转更多圈。好处是机械臂的理论活动范围变大了,坏处是控制代码里一个不小心的角度写入就会让机械臂撞到底座结构件,轻则卡死,重则烧毁舵机。我的建议是:如果是自己组装,优先用 180 度标准舵机;如果只能用 270 度舵机,就在代码里把角度上限硬编码成 135 度以内。
3.2 Arduino 接线与脉宽下限:为什么机械臂回不了中位
EEZYbotARM MK2 的控制核心一般用 Arduino UNO,五个舵机的信号线分别接数字引脚,电源线和地线则不能全部依赖 Arduino 的板载电源。MK2 的肩关节和肘关节在运动时需要高电流,USB 口供电一旦不足,现象往往是“舵机没反应”或者“动一下就复位”。
接线顺序建议按机械结构分层:底座舵机接 D3,肩关节接 D5,肘关节接 D6,腕部接 D9,爪指接 D10。每根信号线旁边要配对两根电源线——舵机的红色电源线接 5V 或 6V 外置电源正极,棕色地线接电源负极,同时把 Arduino 的地线和电源地线共地。不共地会导致舵机信号参考电平和控制板不一致,结果是舵机乱转。
测试舵机是否正常工作的最小代码块长这样:
#include <Servo.h> Servo shoulderServo; // 肩关节 const int shoulderPin = 5; const int minPulse = 500; // 对应 0 度 const int maxPulse = 2500; // 对应 180 度 void setup() { shoulderServo.attach(shoulderPin, minPulse, maxPulse); shoulderServo.writeMicroseconds(1500); // 中位 delay(1000); } void loop() { shoulderServo.write(45); delay(500); shoulderServo.write(135); delay(500); }attach的第三个和第四个参数是脉宽微秒范围,不传的话默认是 500~2500 us,对应 0 度到 180 度。write(45)是写入角度,由库自动换算成脉宽;而writeMicroseconds(1500)是直接写脉宽,1500 us 正好是标准舵机的中位。这里有个容易踩的细节:如果你用了 270 度改装舵机,标准库范围 500~2500 us 会让它的实际物理转动超过 180 度,所以代码里要么缩小attach范围,要么在业务逻辑里 clamp 角度值。
3.3 供电设计:为什么一上电就重启,或者电脑直接掉串口
机械臂五个舵机同时运动的总电流峰值可以到 2A 以上,如果直接从 Arduino 的 5V 引脚取电,瞬间压降会触发板载复位,电脑端表现就是串口断开。这不是代码问题,是供电问题。
我在这个阶段一般会外接一个 6V/5A 的稳压模块,或者用 4 节镍氢电池组做独立电源。注意不要用 9V 方块电池——它虽然电压合适,但内阻大,舵机启动瞬间就把电压拉到保护阈值以下,续航也撑不住。另一个常见问题是:多个舵机的电源线并联供电时,线径太细。18 AWG 以上的硅胶线才行,细杜邦线在 2A 负载下会发热,甚至导致接触不良,特征是“碰一下线,机械臂就抖一下”。
如果你打算长期拿这台机器做实验,建议在电源正极串联一个 470 uF 的电解电容,放在舵机电源入口处。这个电容的作用是吸收舵机启动瞬间的电流尖峰,电容上的电荷能在几十毫秒内提供补偿,减少电源模块掉压的可能。我第一次装的时候没加电容,肩关节一加力就把镍氢电池模块的过流保护打掉了,加了电容以后同样的动作就出不出现这种情况。
4. 把 STL 零件变成能动的机械臂:组装顺序、中位校准与固件配置
4.1 组装顺序与中位校准:先让所有舵机回到 90 度
EEZYbotARM MK2 的组装顺序有一个讲究:从底座往上装,每一级关节装好后,用手转动该级舵机输出轴确认能自由旋转,再装下一级。很多人喜欢先把整个架子搭起来再插舵机,最后发现某个关节卡死,得从顶上拆到最底下才能排故——这种返工非常耽误时间。
在把机械臂零件装配到舵机输出轴上之前,必须先把所有舵机上电并写入 90 度中位。方法很简单:写一个 setup 里只包含servo.write(90)的程序,把每个舵机依次接到控制板上,通电,然后把机械臂的安装件对准舵机输出臂的垂直方向装上去。如果这一步不做,装出来的机械臂初始姿态是歪的,后面所有关节角度的坐标系都偏了。
一个基本的回中测试代码:
#include <Servo.h> Servo servos[5]; int pins[5] = {3, 5, 6, 9, 10}; void setup() { for (int i = 0; i < 5; i++) { servos[i].attach(pins[i], 500, 2500); servos[i].write(90); } } void loop() { // 保持中位,等待机械臂安装 }这段代码做的事情很单纯:五组舵机全部挂载到指定引脚上,写入 90 度,然后停在 loop 里不动。注意attach时的500, 2500是脉宽范围,如果用的是 180 度舵机,这个范围是匹配的;如果是 270 度改装舵机,写 90 度依然是 90 度,不需要改这里,需要改的是后面角度上限。
4.2 固件配置:从舵机抖动到稳定回中的参数细节
固件层面的问题多数集中在三处:舵机信号刷新频率、角度阻尼、多舵机协同时的电流波动。Servo 库默认的信号周期是 50 Hz(20 ms),对 MK2 这类塑料舵机是合适的——不需要调高,调高了舵机内部电路会有啸叫,调低了则会产生明显的运动卡顿。
多舵机协同运动时要避免“瞬间写入多个目标角度”。比如让肩关节和肘关节同时从 0 度转到 90 度,如果在一个循环里连续 write,Arduino 会串行发送脉宽信号,此时舵机之间会有几毫秒的时间差,但机械臂看起来是平滑的。真正的坑在“目标角度差值过大”,比如底座从 0 度直接写入 180 度,塑料齿轮在高速冲击下很容易扫齿。我的一般做法是加一个步进式的缓动函数:
void smoothMove(Servo s, int fromAngle, int toAngle, int stepMs) { int dir = (toAngle > fromAngle) ? 1 : -1; for (int current = fromAngle; current != toAngle; current += dir) { s.write(current); delay(stepMs); } }stepMs控制每次角度递增的时间间隔,数值越大运动越慢越稳。实测中 MK2 的塑料齿轮用stepMs = 15左右比较合适,太快了惯性冲击大,太慢了动作显得拖泥带水。这个方法本质上是把大角度差拆成若干小步,每次只改变 1 度,让舵机的 PID 控制环跟得上目标信号。
4.3 手动示教:用控制代码记录一组点位序列
机械臂组装完成后,最常见的第一个实用性动作是“抓乒乓球从一个点放到另一个点”。你可以先用手掰着舵机把机械臂摆到目标位置,然后从串口读角度数据记录下来,再写进程序回放。这是最原始的手动示教流程,也是理解关节空间和笛卡尔空间区别的入口。
手动示教的核心是一段监听串口数据的代码:
#include <Servo.h> Servo servos[5]; int pins[5] = {3, 5, 6, 9, 10}; void setup() { Serial.begin(115200); for (int i = 0; i < 5; i++) { servos[i].attach(pins[i], 500, 2500); servos[i].write(90); } } void loop() { if (Serial.available() > 0) { int incoming = Serial.parseInt(); if (incoming >= 0 && incoming <= 180) { for (int i = 0; i < 5; i++) { servos[i].write(incoming); } Serial.print("move all to: "); Serial.println(incoming); } } }上面这段是“所有关节同时转同一个角度”的简化版本,实际示教你肯定需要五个通道分别调。一个可用的协议是逗号分隔的五个数值,45,30,60,90,0,前一位是底座角度、后一位是爪指角度。串口字符串解析要做长度和数值范围校验,否则一个非法输入就能让舵机猛甩一下,容易掰断打印件。我一般会把 0~180 度之外的数据包直接丢弃,并且把每次接收的数据包限制在 32 字节以内,这样既防误操作,也防止 Arduino 内存被灌满。
5. 常见问题排查:EEZYbotARM MK2 装好之后翻车的四条血泪经验
5.1 现象:机械臂上电后舵机“咔咔”抖动,无法定位
这是 MK2 玩家最常见的问题。抖动意味着舵机在不停接收信号,但输出轴无法稳定在某一角度。原因通常不是代码写错,而是供电不足,或者信号线接触不良。
解决方法是先查供电:给舵机单独供 5V/6V 电源,确认电流能力不低于 2A;然后查信号线排线——杜邦线插在 Arduino 引脚上容易虚接,建议用扎带把排线固定在底板边缘。如果还是抖,把舵机从机械臂上拆下来空载测试,排除塑料件卡阻的可能。
5.2 现象:大臂在水平位置无力,稍微碰一下就会垂下去
很多人的肩关节用了 SG90,表现就是带负载能力极差。SG90 的堵转扭矩也就 1.8 kg·cm,在 MK2 大臂加小臂全展开的状态下,力臂长度接近 20 cm,需要的扭矩远超过它的能力。
解决方法是换装 MG996R 或更高扭矩舵机。注意换舵机后要重新校一下attach的脉宽范围——不同舵机的死区时间不一样,SG90 的 0 度信号可能和 MG996R 的 5 度信号重叠,导致机械臂零点偏移。我用过的方法是在代码里写一个校准程序,让舵机慢慢转,记录它从死角刚动起来的那一刻对应的脉宽值,然后把这个值作为 0 度起点。
5.3 现象:打印件在舵机安装孔处开裂
PLA 打印的零件在长时间受力后容易沿层纹开裂,特别是舵机安装部位,螺丝拧紧后应力集中在层间薄弱处。这不是图纸问题,是打印方向和材料选择问题。
解决方法是调整打印朝向:让舵机安装孔的轴线垂直于打印平台,这样拉力方向与层纹方向垂直,强度能提升不少。材料上可以换成 PLA+ 或者 PETG,如果不方便换材料,就在开裂处补一层环氧树脂胶,再在外部加一个扎带加固。我一般打印关键受力件时会多打一个备件放着,开裂了就换新件而不是勉强粘回去。
5.4 现象:电一插,Arduino 就重启,电脑提示 USB 设备无法识别
这是典型的舵机电流过载把板载电压拉垮了。舵机启动瞬间的电流可以打到正常工作电流的 3 倍,多个舵机同时启动时,总电流尖峰会击穿 Arduino 板载稳压器的限流阈值。
解决方法是把舵机电源彻底从 Arduino 的 5V 引脚断开,改用外部电源,并确保 Arduino 的地和外部电源地是连通的。如果手头只有一个电源,可以把电源输出并联一个大电容,但不要指望它替代稳压模块。从那以后我每次接新的机械臂,都强制走一遍“先独立供电,再共地,最后插 USB”的顺序,再没遇到过一插电掉串口的问题。
6. 进阶玩法:逆运动学角度解算与抓取偏移量的校正技巧
EEZYbotARM MK2 只有三轴加一个爪子,直接逆解其实不复杂:把机械臂简化成两连杆模型,底座旋转角单独解算,大臂和小臂组成平面两连杆,末端坐标到关节角的映射可以通过几何法在两行公式里完成。
假设大臂长度 l1=130 mm,小臂长度 l2=145 mm,末端坐标是 (x, y),先算肩关节角度 q1 和肘关节角度 q2:
import math def solve_2link_ik(x, y, l1, l2): # 末端到肩关节的距离 r = math.sqrt(x * x + y * y) if r > l1 + l2 or r < abs(l1 - l2): return None # 超出可达空间 # 肘关节角度,余弦定理 cos_q2 = (l1 * l1 + l2 * l2 - r * r) / (2 * l1 * l2) q2 = math.acos(max(-1.0, min(1.0, cos_q2))) # 肩关节角度 beta = math.atan2(y, x) phi = math.acos(max(-1.0, min(1.0, (l1 * l1 + r * r - l2 * l2) / (2 * l1 * r)))) q1 = beta - phi return math.degrees(q1), math.degrees(q2)这段代码的核心是余弦定理。cos_q2这一步判断目标点是否在机械臂可达半径内,如果r大于l1 + l2,说明目标太远,直接返回None,避免给舵机写入一个无法到达的角度。beta是末端点在极坐标系下的方位角,phi是大臂与连线的夹角,两者相减得到肩关节的真实角度。这里有个细节需要注意:acos的参数要 clamp 在 [-1, 1] 之间,因为浮点误差可能导致它超出合法范围,返回 NaN 后整个控制器就崩了。
实际抓取时,爪指不是理想点,它有一个张开宽度和纵向偏移。我的做法是给末端坐标加一个固定偏置值——比如爪子中心距腕关节末端还有 38 mm,那逆运动学输入的 (x, y) 要减去这个偏置后再解算。更进阶的做法是把爪指的张开角度也作为一个自由度,与抓取目标宽度作匹配:宽物件开大一点,窄物件收小一点,配合串口传感器做闭环。
我建议你把逆解代码跑通后,先用一个绘图软件画一条直线路径,每隔 10 mm 取一个目标点,依次输入逆解函数,观察得到的 q1、q2 角度变化平不平滑。如果某个目标点附近的角度跳变剧烈,说明路径穿过了奇异点或者超出了可达范围——这时候不是调代码,而是要重新规划路径点。从那以后我每次给这个机械臂写抓取程序,都强制走一遍“几何参数实测 → 逆解脚本验证 → 舵机角度限幅 → 示教回放”四条固定步骤,已经成了肌肉记忆。用这个流程,MK2 抓乒乓球、抓小积木块都没有翻车过。希望这套经验也帮到你。
本文还有配套的精品资源,点击获取