ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Arduino双舵机写字机器人:从坐标映射到标定法的入门实战

Arduino双舵机写字机器人:从坐标映射到标定法的入门实战 1. 项目缘起与整体设计思路1.1 为什么选择写字机器人作为入门项目很多人玩Arduino都是从点灯、蜂鸣器、超声波测距开始的这些项目确实简单但做完之后总觉得少了点“作品感”。写字机器人不一样它能把代码变成看得见摸得着的物理动作而且成品摆在桌上确实像那么回事。我第一次看到别人用两个舵机加一支笔在纸上写字的视频时第一反应是“这玩意儿到底怎么控制笔画的”后来自己动手做了一台才发现核心逻辑比想象中简单得多但细节坑是真不少。这个项目的本质是双轴平面定位系统。两个舵机分别控制笔在X轴和Y轴方向的位置通过PWM信号控制舵机转角再通过连杆机构把角度变化转换成笔尖的平面位移。听起来像那么回事实际上你完全可以把它理解成一个“用两根棍子推着笔在纸上画线”的装置。适合谁做有基础Arduino编程经验、会插面包板、能看懂简单电路图的人。完全零基础也能做但建议先把Arduino IDE装好、跑通一个舵机来回转的例程再开始。1.2 机械结构选型为什么是双舵机而不是步进电机市面上写字机器人方案大致分三类步进电机同步带、双舵机连杆、总线舵机机械臂。步进电机方案精度高、写字快但成本直接翻倍而且需要驱动模块和更复杂的电源设计。总线舵机机械臂方案灵活度高但一套下来少说几百块调试门槛也高。双舵机方案最大的优势是成本极低、结构简单、调试直观。两个SG90舵机不到二十块加上一些杜邦线、亚克力板或者硬纸板总成本能控制在五十块以内。但双舵机方案有个天然缺陷舵机的角度分辨率有限。SG90的PWM控制精度大约是每度对应11微秒左右的脉宽变化而Arduino的analogWrite或者Servo库输出的脉宽分辨率大约是1微秒理论上能分辨0.09度。但实际因为舵机内部电位器的死区和齿轮间隙有效分辨率大概在0.5到1度之间。这意味着笔尖的定位精度大概在毫米级别写大字没问题写小字会糊。所以这个项目的定位很明确做一台能写5厘米以上大字的写字机器人用来演示原理和体验动手乐趣而不是追求印刷级精度。1.3 控制逻辑的核心从坐标到角度的映射写字机器人的核心算法其实就一句话把你想写的字的笔画拆成一系列坐标点然后通过逆运动学算出每个点对应的两个舵机角度。逆运动学这个词听着唬人但在双舵机连杆结构里它就是一个简单的几何关系。假设两个舵机分别位于纸面的左下角和右下角笔尖通过两根连杆分别连接到两个舵机上。已知笔尖坐标(x, y)两个舵机的固定位置分别是(0, 0)和(L, 0)那么笔尖到左舵机的距离d1 sqrt(x² y²)到右舵机的距离d2 sqrt((L-x)² y²)。再根据连杆长度和舵机臂长度用余弦定理就能算出两个舵机需要转到的角度。这个计算在Arduino里用atan2和acos函数几行代码就能搞定。但实际做的时候你会发现纯几何计算出来的角度和实际需要的角度总有偏差因为舵机臂和连杆的连接点不在舵机转轴上而且连杆长度也不可能完全精确。所以实操中更常用的方法是标定法先让舵机转到几个已知角度记录笔尖的实际位置然后拟合出一条角度到位置的映射曲线。这个方法虽然“不优雅”但极其有效而且能补偿掉大部分机械误差。2. 核心细节解析与实操要点2.1 舵机选型SG90、MG90S还是MG996RSG90是最常见的小舵机塑料齿轮扭矩约1.8kg·cm重量9克。优点是便宜、轻、对电源要求低直接接Arduino的5V引脚就能转。缺点是塑料齿轮容易扫齿尤其是写字机器人这种需要频繁正反转的场景用不了多久齿轮间隙就会变大导致笔迹抖动。我第一台写字机器人用的就是SG90写了大概两百多个字之后X轴舵机就开始出现明显的回程差笔尖回到同一个坐标时位置偏了差不多两毫米。MG90S是SG90的金属齿轮版本扭矩略大价格贵几块钱但耐用性提升明显。如果你打算长期玩这个项目强烈建议直接上MG90S省得中途换舵机重新标定。MG996R是更大一号的舵机扭矩11kg·cm金属齿轮但重量55克对支架强度要求高而且堵转电流能到2.5AArduino的5V引脚根本带不动必须外接电源。对于写字机器人这种轻负载场景MG996R属于杀鸡用牛刀没必要。还有一个容易被忽略的参数是复位电流。舵机在每次上电时都会有一个复位动作瞬间电流可能达到正常工作电流的三到五倍。如果你用Arduino的5V引脚直接给两个舵机供电复位瞬间很可能导致Arduino重启或者程序跑飞。我踩过这个坑后来老老实实给舵机单独接了一个5V 2A的电源适配器问题就再也没出现过。2.2 电源方案为什么不能只用USB供电Arduino Uno的5V引脚来自板载的AMS1117稳压芯片最大输出电流大约800mA但这是在输入电压7-12V且散热良好的情况下。如果你用USB供电5V引脚的实际可用电流更小大概只有400-500mA。两个SG90舵机在空载时每个电流约100mA加起来200mA看起来够用。但写字过程中舵机需要频繁启停和换向峰值电流轻松超过500mA再加上复位电流USB供电几乎必然出问题。我的建议是舵机电源和Arduino电源完全分开。Arduino用USB供电或者9V电池供电都行舵机用一个独立的5V 2A电源适配器然后把两个电源的GND连在一起。这样舵机的电流波动不会影响Arduino程序运行稳定得多。如果你非要用一个电源那就选一个5V 3A以上的适配器同时给Arduino和舵机供电但要注意Arduino的5V引脚不能直接接外部5V电源得从VIN引脚输入7V以上电压或者从USB口输入5V。2.3 机械结构搭建从纸板到亚克力的升级路径第一台原型机完全可以用硬纸板和热熔胶搞定。找一块A3大小的硬纸板做底板两个舵机用热熔胶固定在底板的两个角上舵机臂上打孔用回形针或者细铁丝做连杆笔用橡皮筋绑在连杆末端。这个结构粗糙但能用主要目的是验证代码和运动逻辑。但纸板结构有个致命问题刚度不够。舵机一转纸板跟着变形笔尖位置就飘了。而且热熔胶在受力后会有微小的蠕变用久了舵机位置会偏移。所以第二版建议用3mm亚克力板用激光切割或者手工锯出底板和舵机支架用M3螺丝固定舵机。亚克力的刚度足够而且加工精度比纸板高一个数量级。如果你没有加工条件也可以用现成的舵机支架套件网上有卖双舵机云台支架的十几块钱一套省事很多。连杆的选择也有讲究。回形针太软写字时会有弹性形变细铁丝好一些但容易弯最理想的是碳纤维杆或者铝管直径2mm左右刚度高重量轻。连接点用M2螺丝加尼龙锁紧螺母既牢固又能微调松紧。笔的固定方式推荐用笔夹扎带比橡皮筋稳定而且换笔方便。3. 实操过程与核心环节实现3.1 硬件连接与供电改造先把两个舵机的信号线分别接到Arduino的9号和10号引脚红线接5V电源正极棕线接电源负极。注意这里舵机的5V不要接Arduino的5V引脚而是接独立电源的正极。然后把独立电源的负极和Arduino的GND连起来这一步千万不能忘否则信号电平没有参考地舵机会乱转。如果你用的是MG90S可以在舵机电源正负极之间并一个1000μF的电解电容用来吸收复位电流和换向时的电流尖峰。这个电容相当于一个“小水库”舵机瞬间要电的时候先从这个电容里取不会把电源电压拉低。实测下来加了电容之后舵机复位时的抖动明显减小。代码方面Arduino自带的Servo库就够用了。但要注意Servo库默认使用Timer1会影响到9号和10号引脚的PWM输出。如果你同时要用其他PWM功能可能会冲突。解决办法是用ServoTimer2库或者换到其他引脚。不过对于写字机器人这个项目只用两个舵机直接用Servo库最省事。3.2 坐标到角度的标定流程前面说了纯几何计算会有偏差所以实操中我推荐三点标定法。具体操作是先让两个舵机都转到90度中位记录笔尖位置然后左舵机转到45度右舵机不动记录笔尖位置再左舵机转到135度右舵机不动记录笔尖位置。用这三个点拟合出左舵机角度和笔尖X坐标的关系。右舵机同理。这个标定过程听起来麻烦但做一次之后就能用很久。而且标定数据可以直接存在Arduino的EEPROM里下次上电不用重新标。我自己的标定代码大概三十行核心就是用map函数做线性插值。如果你想要更高精度可以标五个点做二次拟合但实际体验下来三点线性插值的精度已经够写大字了。标定的时候有个小技巧在笔尖下面垫一张坐标纸这样你能直接读出笔尖的X、Y坐标不用拿尺子量。坐标纸网上几块钱一大张比自己做标记方便得多。3.3 写字轨迹的生成与优化写字机器人的轨迹生成有两种思路一种是矢量法把每个字的笔画拆成直线和圆弧然后离散成点另一种是位图法把字渲染成黑白图片然后逐行扫描提取笔迹坐标。矢量法写出来的字边缘光滑但需要手动拆笔画工作量大。位图法自动化程度高但写出来的字有锯齿感而且逐行扫描会导致笔尖频繁抬落写字速度很慢。我实际用的是混合法先用矢量法把常用字拆好存成一个坐标数组对于不常见的字用位图法临时生成。矢量法的坐标数组格式很简单就是一个二维数组每一行是一个笔画的起点和终点坐标。比如写“一”字就是{{10, 50}, {90, 50}}表示从(10,50)画到(90,50)。写“十”字就是两个笔画{{50, 10}, {50, 90}}和{10, 50}, {90, 50}。但直接画直线会有问题舵机从起点转到终点的过程中笔尖走的不是直线而是一条弧线。这是因为两个舵机的角度变化不是线性的而是三角函数关系。解决办法是把每条直线离散成20到50个小段每段单独计算舵机角度这样笔尖走的就近似直线了。离散点数越多线条越直但舵机动作越频繁写字速度越慢。实测下来每毫米两个点是比较好的平衡点。3.4 完整代码框架与关键函数代码整体分三块初始化、坐标转换、轨迹执行。初始化部分设置舵机引脚、读取EEPROM里的标定数据、把笔抬到起始位置。坐标转换部分就是前面说的逆运动学计算封装成一个函数xyToAngles(float x, float y, int angle1, int angle2)。轨迹执行部分遍历坐标数组对每一段直线做离散化然后逐个点设置舵机角度。关键函数xyToAngles的实现逻辑是这样的先计算笔尖到两个舵机转轴的距离然后用余弦定理算出连杆和舵机臂之间的夹角再加上舵机臂的初始角度偏移。这个偏移量就是标定要解决的问题。代码里用atan2算方向角用acos算夹角最后转换成舵机角度。注意acos的参数要限制在-1到1之间否则浮点误差会导致返回NaN舵机就会乱转。还有一个容易忽略的点是舵机运动速度控制。如果直接让舵机从当前角度跳到目标角度舵机会以最大速度冲过去笔尖会剧烈抖动写出来的线像蚯蚓爬。解决办法是在两个角度之间做插值每次增加一小步延时几毫秒让舵机平滑过渡。这个插值步长和延时决定了写字速度步长越小、延时越长写字越慢但越稳。我一般用步长1度、延时15毫秒写一个字大概需要十几秒。4. 常见问题与排查技巧实录4.1 舵机抖动、复位、发热的排查思路舵机抖动是最常见的问题原因通常有三个电源功率不足、信号线干扰、机械负载过大。排查顺序建议从电源开始。先用万用表量一下舵机电源电压在舵机转动时如果电压从5V掉到4.5V以下那就是电源功率不够换个大电流的适配器或者加电容。如果电压稳定但还抖检查信号线是不是和电源线捆在一起了分开走线试试。如果还抖把舵机从机械结构上拆下来空载转如果空载不抖负载抖那就是机械结构卡涩检查连杆有没有别劲。舵机复位问题前面提过主要是复位电流导致的电压跌落。除了加电容和独立供电还可以在代码里加一个延时上电后先等两秒再初始化舵机给电源一个稳定时间。另外Servo库的attach函数会立即让舵机转到中位如果你不希望上电时舵机突然动一下可以先attach再慢慢转到目标角度。舵机发热一般是堵转或者频繁启停导致的。写字机器人正常工作时舵机应该是温的不至于烫手。如果烫手先检查机械结构有没有卡死再检查代码里有没有让舵机长时间保持在极限角度。SG90的极限角度是0到180度但实际可用范围建议限制在10到170度之间留一点余量避免内部限位机构受力。4.2 写字歪斜、笔画不直的机械原因写字歪斜通常不是代码问题而是机械问题。最常见的原因是两个舵机的转轴不在同一条水平线上。如果左舵机比右舵机高了两毫米笔尖走的水平线就会变成斜线。解决办法是用一个直角尺校准两个舵机的安装位置确保转轴等高。另一个原因是连杆长度不一致左右连杆差一毫米笔尖的轨迹就会偏。用游标卡尺量一下尽量做到等长。笔画不直还有可能是舵机齿轮间隙导致的。SG90的塑料齿轮用久了会有回程差笔尖从A点到B点再回到A点位置会偏。这个问题没法完全消除只能换金属齿轮舵机或者接受这个误差。如果你发现某个方向的笔画特别不直检查一下那个方向的舵机是不是齿轮磨损更严重。4.3 上传项目出错与IDE配置问题Arduino上传项目出错的原因很多最常见的是串口被占用。如果你同时打开了串口监视器和其他串口软件上传时会提示端口被占用。关掉串口监视器再上传就行。另一个常见原因是开发板型号选错比如你用的是Arduino Uno但IDE里选的是Arduino Nano上传会失败。在“工具”菜单里确认开发板和端口选对了。还有一个坑是USB线的问题。有些USB线只能供电不能传数据插上之后电脑能识别到端口但上传总是失败。换一根线试试最好是带屏蔽的数据线。如果IDE里根本看不到端口检查一下驱动装了没有Arduino Uno用的是CH340或者ATmega16U2不同版本驱动不一样。对于ESP32开发板上传时要注意按住BOOT键。ESP32在上电时会检测某个引脚的电平来决定运行模式如果程序里把这个引脚拉低了下次上传就会失败。解决办法是上传时按住BOOT键等出现“Connecting...”再松开。这个坑我踩过好几次后来养成了上传前先按BOOT的习惯。4.4 常见问题速查表现象可能原因排查方法解决方案舵机抖动电源功率不足万用表测舵机电源电压换2A以上适配器加1000μF电容舵机复位复位电流拉低电压观察上电瞬间电压跌落独立供电上电延时2秒舵机发热机械卡涩或堵转拆下舵机空载测试调整连杆限制角度范围写字歪斜舵机转轴不等高直角尺校准重新安装舵机支架笔画不直齿轮间隙或离散点太少检查回程差增加离散点换MG90S每毫米2个点上传失败串口占用或板型选错检查端口和开发板设置关闭串口监视器重选板型ESP32上传失败BOOT引脚电平不对观察上传时提示按住BOOT键再上传笔尖位置漂移标定数据不准重新三点标定存EEPROM定期校准4.5 几个让我少走弯路的实操心得第一个心得是先调机械再调代码。很多人一上来就埋头写代码结果机械结构松松垮垮代码调得再好也写不出好字。我的做法是先把机械结构装好用手转动舵机臂感受一下整个运动范围内有没有卡涩笔尖能不能覆盖到纸面的每个角落。机械顺了代码调试会快很多。第二个心得是标定数据一定要存EEPROM。我第一版代码没存每次上电都要重新标定烦得要命。后来加了EEPROM读写标定一次能用几个月。EEPROM的读写次数有限大概十万次但标定数据只在手动触发时才写完全够用。第三个心得是写字速度不要贪快。我一开始把延时设成5毫秒写字确实快但笔迹抖得厉害而且舵机发热严重。后来改成15毫秒写字慢了一半但笔迹明显干净舵机也只是温温的。写字机器人不是打印机慢一点反而更有“手写”的感觉。第四个心得是笔的选择比想象中重要。圆珠笔太滑笔尖容易在纸上打滑铅笔太软写几个字就钝了中性笔最合适0.5mm的笔尖粗细刚好出水流畅又不会洇墨。笔的固定也很关键一定要夹紧否则写字时笔会轻微晃动笔迹就会发虚。5. 功能扩展与进阶玩法5.1 从写字到画图轨迹数据的通用化写字机器人的核心是坐标轨迹只要把轨迹数据换掉它就能画图。你可以用Inkscape把SVG矢量图导出成坐标点然后转成Arduino能读的数组格式。我试过画一个简单的五角星和一只猫的轮廓效果还不错。但要注意SVG里的曲线需要离散成足够密的点否则画出来会有棱角。Inkscape有个“扁平化贝塞尔曲线”的功能可以把曲线转成很多小直线段导出后直接能用。如果你想让机器人画得更精细可以把坐标数据存到SD卡里Arduino从SD卡读取。这样就不受Flash容量限制了画复杂的图也没问题。SD卡模块几块钱一个用SPI接口和Arduino连接代码也不复杂。5.2 加入ESP32实现无线控制Arduino Uno没有无线功能每次改字都要重新插USB线上传很麻烦。换成ESP32之后可以做一个简单的Web服务器在手机浏览器里输入文字ESP32收到后生成轨迹并控制舵机写字。ESP32的Arduino核心自带WiFi库几十行代码就能搭一个Web服务器。我做过一个版本手机连上ESP32的热点打开网页输入“你好”机器人就写“你好”体验很流畅。但ESP32的PWM频率和Arduino Uno不一样Servo库在ESP32上需要改用ESP32Servo库。这个库的API和Servo库基本兼容但引脚编号要按ESP32的GPIO来。另外ESP32的供电是3.3V舵机信号线接上去也能用但最好加一个电平转换模块确保信号稳定。5.3 用Wokwi仿真平台先验证代码如果你还没有买硬件或者担心代码有问题烧坏舵机可以先用Wokwi仿真平台跑一遍。Wokwi支持Arduino Uno和ESP32可以拖拽添加舵机、电阻、LED等元件代码直接在浏览器里运行。虽然仿真里的舵机不会真的转但你可以通过串口输出看到角度计算是否正确逻辑有没有问题。我每次改完代码都会先在Wokwi里跑一遍确认没有数组越界或者死循环再下载到真机上。Wokwi的舵机元件可以显示当前角度你可以在仿真里直观地看到两个舵机的角度变化对于调试逆运动学算法特别有用。而且Wokwi支持串口监视器你可以把计算过程中的中间变量打印出来方便定位问题。5.4 从双舵机到总线舵机机械臂的升级路径双舵机写字机器人玩透了之后如果你想挑战更复杂的项目可以考虑总线舵机机械臂。总线舵机通过串口通信每个舵机有唯一的ID可以串联在一起只需要两根信号线就能控制十几个舵机。飞特舵机是市面上比较常见的选择他们的总线舵机支持位置、速度、扭矩多种控制模式精度也比PWM舵机高得多。但总线舵机的门槛也高不少。首先是成本一个总线舵机就要几十到上百块一套六轴机械臂下来至少五六百。其次是通信协议需要看手册配置波特率、ID、工作模式调试起来比PWM舵机麻烦。不过如果你已经做过写字机器人对舵机控制、坐标变换、轨迹规划有了基本概念升级到总线舵机机械臂会顺利很多。我自己的路径就是先做写字机器人再做总线舵机机械臂后者虽然复杂但核心逻辑是相通的。5.5 用激光测距辅助标定的思路写字机器人的标定一直是个麻烦事每次换笔或者调整机械结构都要重新标。后来我想了个办法在笔尖旁边装一个激光测距模块实时测量笔尖到纸面的距离。虽然这个距离不能直接给出X、Y坐标但可以用来检测笔尖是否接触纸面以及纸面是否平整。如果纸面有起伏激光测距的数据会变化你可以据此调整笔的抬落高度避免笔尖悬空或者压得太紧。这个思路来自我玩STM32时做的一个项目当时用RTOS配置运行舵机和激光测距把数据解析后发送到电脑串口。那个项目让我意识到激光测距模块比如VL53L0X体积小、精度高完全可以集成到写字机器人上。不过这个功能属于锦上添花不是必须的建议先把基础功能做稳定再考虑。6. 写在最后的一些个人体会做写字机器人这个项目最大的收获不是最后写出来的那几个字而是过程中踩过的那些坑。电源问题让我学会了看数据手册算电流机械抖动让我理解了刚度和间隙的重要性标定偏差让我明白了理论计算和实际系统之间的差距。这些东西在书本上是学不到的只有亲手做过、错过、改过才能真正变成自己的经验。如果你正在做这个项目我的建议是不要追求一次成功。第一版能动能写就行哪怕字歪歪扭扭也没关系。然后在这个基础上一点点改进换金属齿轮舵机、换亚克力底板、加电容、优化标定算法。每改一次你都会对系统有更深的理解。我自己的写字机器人改了五版从纸板到亚克力从SG90到MG90S从USB供电到独立电源每一版都比上一版好一点这个过程本身就很有意思。最后分享一个小技巧如果你觉得逆运动学计算太麻烦可以先用查表法。把舵机角度从0到180度分成36份每份5度然后手动测量每个角度组合对应的笔尖位置做成一个二维查找表。写字的时候根据目标坐标在表里找最近的点直接用对应的角度。这个方法精度取决于表的密度但胜在简单粗暴不需要任何三角函数计算特别适合数学基础薄弱的朋友。等查表法玩熟了再回头理解逆运动学会发现其实没那么难。
返回列表