自制Arduino Uno兼容单板:从硬件设计到grbl固件烧录全攻略
前阵子整理工作台,翻出一块自己画了打样的Single-Board Arduino Uno Shield-Compatible开发套件,正好有朋友在问这类板子怎么用、以及怎么给它们烧grbl固件的事。这里就把我从硬件设计思路到grbl 1.1h.20190825.zip烧录、再到实际跑CNC任务的完整过程捋一遍。这篇文章适合三类人:一是想把手头Arduino Uno项目“缩小成一整块板子”的玩家,二是做雕刻机、激光雕刻机准备上grbl固件的朋友,三是想理解Uno盾板兼容标准到底卡在哪、别一插上去就烧东西的硬件爱好者。
1. 先想明白:单板化和Shield兼容这件事到底在解决什么问题
1.1 传统“Uno + 多块盾板叠叠乐”的三个真实痛点
很多人玩Arduino Uno都会经历一个阶段:主控板插上CNC Shield,CNC Shield上再插三个A4988驱动模块,然后飞线接限位开关、主轴继电器、激光模块PWM…… 板子堆得很高,侧面看去像一栋违章加盖的小楼。每次要换一个电机相位,手都得伸进线堆里抠半天。
这种堆叠方式在纯学习阶段没问题,但一旦你想把这个东西做成一个可以反复拆装、带去展会演示、或者塞进一个小机箱里的“设备”,问题就逐条暴露了:
- 机械高度和稳定性:三层板子叠在一起,高度接近40mm以上,插针的握持力要同时承受三块板的重量,稍微振动一下就容易接触不良。CNC类设备运行时步进电机的震动很大,这种不良接触会直接造成信号毛刺,表现就是电机丢步、乱走。
- 供电环路太长:CNC Shield的VMOT通常从外部电源接入,5V逻辑则从Uno板载稳压器出来。两套电源回路绕了大半个板子,地线压差大,步进电机一启动,逻辑电源就被拉出噪声。实测下来,USB供电时A4988一使能,Uno板载3.3V能被拉低0.4V以上,这在模拟采集场景里完全是灾难。
- 接口资源浪费:Uno原生排针把数字口、模拟口都铺开,但一个具体项目通常只用其中6到10个引脚,其余引脚只是作为“扩展可能性”占着位置。真做项目时,这堆空引脚并不带来价值,只是增加走线长度。
所以我做这块板子时,核心目标不是“做一块高仿Uno”,而是把Uno R3标准里被项目实际用到的那些引脚和电源资源保留下来,其余部分尽量内聚成单板。但是,有一个底线必须守住:任何标准Uno Shield插上来,电气和机械上都必须能正常工作。做不到这一点,就不配叫Shield-Compatible。
1.2 “兼容”不是长得像,而是电气和机械的双重对齐
Uno R3的Shield兼容标准,其实就三条硬规矩:
- 引脚顺序完全一致:左右两排插针的位置和引脚编号必须和官方Uno R3完全一致,包括那块多出来的ICSP 6Pin头,位置也必须在板子左上角那个特定区域。
- 电气参数一致:5V输出、3.3V输出、IOREF电平、RESET引脚的复位逻辑,都得符合Arduino规范。比如IOREF是5V表示逻辑电平为5V,如果盾板上带电平转换,就能据此自动切换。
- 机械干涉最小化:USB座、电源插座、ICSP头的朝向和高度不能和常见盾板的元件区域冲突。
这里面很多人抄板时最容易翻车的是ICSP头的方向。Arduino Uno R3的ICSP头有一个防呆缺口,但缺口方向在不同板卡上并不统一。如果你自己画单板,一定要拿着真正要插的Shield实物比划一下,或者下载官方Uno R3的Gerber文件对照孔位和丝印方向。我在早期打样时就在这个位置栽过:ICSP头画反了180度,结果用ISP烧熔丝位时死活连不上,最后只能飞线救火。
1.3 什么场景下这类板子最值得做
按我这几年的使用经验,单板Uno兼容套件最合适的场景是这三类:
- 固定功能的小型CNC/激光雕刻机控制板:把grbl固件烧进ATmega328P,板子只引出一组CNC Shield兼容扩展排针,然后直接怼上A4988驱动阵列板。
- 自动化工装里的“逻辑核心”:比如一个检测设备里只需要固定用几个IO去控制继电器、读取传感器,单板化可以大大减少接线点。
- 教学演示箱:学生拿到一块板子,既能体验Arduino标准生态,又能少踩“接触不良”的坑。
换句话说,它是“Arduino生态的兼容层”和“最终产品的主控板”之间一个很好的中间形态。
2. 硬件设计上,能和Uno Shield无缝插拔的关键细节
这一节我不会把原理图整张贴出来,那是另一篇文章的篇幅,重点讲五个决定“兼容性成败”的硬件细节。
2.1 引脚映射:ATmega328P与Uno排针的对应关系
先给一张我实际画板时放在手边的对照表。这张表的作用是,当你把Uno的库和固件往自研单板上移植时,能快速确认某个Arduino引脚编号到底对应到AVR的哪个端口。
| Arduino引脚编号 | AVR引脚 / 端口 | 排针位置 | 备注 |
|---|---|---|---|
| D0 | PD0 / RXD | 数字侧第1脚 | 接USB转串口TX,设计跳线切换 |
| D1 | PD1 / TXD | 数字侧第2脚 | 接USB转串口RX |
| D2 | PD2 | 数字侧第3脚 | grbl默认X轴STEP |
| D3 | PD3 | 数字侧第4脚 | grbl默认X轴DIR,也支持PWM |
| D4 | PD4 | 数字侧第5脚 | grbl默认Y轴STEP |
| D5 | PD5 | 数字侧第6脚 | grbl默认Y轴DIR |
| D6 | PD6 | 数字侧第7脚 | grbl默认Z轴STEP |
| D7 | PD7 | 数字侧第8脚 | grbl默认Z轴DIR |
| D8 | PB0 | 数字侧第9脚 | 可用于限位 |
| D9 | PB1 | 数字侧第10脚 | 定时器PWM,可用于主轴/激光 |
| D10 | PB2 | 数字侧第11脚 | SS,也带PWM |
| D11 | PB3 | 数字侧第12脚 | SPI MOSI,grbl默认主轴PWM输出 |
| D12 | PB4 | 数字侧第13脚 | SPI MISO |
| D13 | PB5 | 数字侧第14脚 | SPI SCK,板载LED |
| A0-A5 | PC0-PC5 | 电源侧 | 同时兼作数字D14-D19 |
| SDA/SCL | PC4/PC5 (A4/A5) | 数字侧第15/16脚 | Uno R3新增的旁路引出 |
这张表看着基础,但画板时每条信号线的走向完全依赖它。我的习惯是在原理图里把像D0/D1这样支持“复用切换”的信号线单独标注,然后在PCB上留两个0欧电阻位或者2.54mm跳线帽,方便在“USB串口模式”和“外接串口设备模式”之间切换。
2.2 电源轨设计:怎么避免Uno Shield一插上就冒烟
Uno R3排针上的电源引脚一共是这六个:IOREF、RESET、3.3V、5V、GND、GND、VIN。兼容板最容易出问题的就是VIN和5V的关系。
- VIN:设计输入范围通常7-12V,直接接到板载降压电路输入端,同时也引到排针上。注意当Shield是一块电机驱动板时,VIN往往是它的VMOT来源,因此走线要能承受2A以上。
- 5V:由USB的5V和VIN降压后的5V共同供电。我的做法是加一个P-MOS做电源路径切换,USB存在时用USB,否则用VIN降压。之前有人为省成本直接两个5V并联,接上外部电源再插USB时,电流倒灌把电脑USB口搞到保护,这种案例我见了不少。
- 3.3V:Uno上的3.3V是从5V经AMS1117-3.3得来的,最大输出电流通常就50-150mA。很多Shield上的逻辑电平转换芯片要喝3.3V,但电流不大。如果你单板上还要挂GPRS、ESP8266这类吃3.3V大户,老老实实在Shield侧单独供电,别指望这路输出。
- IOREF:在Uno R3上这个引脚直接连到5V。我画板时直接拉一根短粗线到5V电源轨,同时加一个0欧电阻位,万一以后想切换成3.3V逻辑,也能人为改。
电源轨最容易被忽略的是GND布线。Uno排针上有两个GND脚,它们必须就近汇入同一个平面,不能左边一个右边一个分隔很远。否则,Shield上的大电流回路会通过GND平面干扰逻辑信号,轻则串口数据乱码,重则电机方向信号翻转。早期版本我就吃过这个亏,后来改成整块板底层全铺地,信号完整性立刻好转。
2.3 USB转串口芯片选型:CH340G还是16U2
官方Uno用的是ATmega16U2做USB转串口,好处是可以在电脑上模拟出标准串口,还能刷成HID设备之类的自定义固件。但代价是成本高,而且需要一颗16MHz晶振,PCB上多占位置。
我在自制单板上用CH340G,原因很实际:
| 芯片 | 成本 | 驱动便利性 | 原厂支持 | 适合场景 |
|---|---|---|---|---|
| ATmega16U2 | 高 | 免驱/系统自带 | 官方方案 | 追求100%兼容、能刷自定义USB固件的场景 |
| CH340G | 低 | Win10及以上系统自带,Win7需装驱动 | 第三方,资料多 | 单板集成、量产、成本敏感的CNC控制板 |
| CP2102 | 中 | 系统自带 | 成熟 | SOP封装方便手工焊接,稳定性好 |
CH340G在Linux下也很省心,内核自带的ch341驱动直接识别,不需要额外操作,这对烧grbl固件后接树莓派上位机的用户来说很友好。唯一需要注意的是CH340G内部是3.3V逻辑,和ATmega328P的5V逻辑通过IO直连,虽然标称电平兼容,但最好串个1kΩ电阻做保护。实际做下来,串不串这个电阻都能工作,但串了以后在热插拔时明显更稳,不容易把CH340G的IO口打坏。
2.4 板上应该留哪些“可改配置”的跳线
我认为单板开发套件和一块纯定制PCB最大的区别,就在“可配置性”。我的板子上留了这几组跳线,每一组都是在实际项目中救过场的设计:
- RX/TX切换跳线:断开后板载CH340G不再占用D0/D1,方便外接蓝牙模块或其他串口设备与grbl通信。
- 5V/VIN选择跳线:用来决定排针上某个引脚是输出5V还是直接输出VIN,兼容需要独立供电的Shield。
- ICSP与排针直连焊盘:如果你想用外部USBasp烧录,可以直接断开板载印线,从ICSP头飞线。
这些跳线让单板在“纯Uno替换”和“专用控制板”两种定位之间来回切换,不算复杂,但非常实用。
3. grbl固件烧录完整实操:从grbl 1.1h.20190825.zip到雕刻机动起来
对于CNC、激光雕刻机这类项目,这块板子最常见的用途就是刷grbl固件。grbl是一个运行在AVR平台上的开源运动控制固件,它做的事情可以概括为:接收G代码、解析指令、通过定时器中断产生步进脉冲,同时控制主轴PWM、冷却液等辅助输出。
3.1 为什么选grbl 1.1h这个版本
grbl的版本号里,1.1其实是多年打磨后的稳定大版本,最后的字母是具体修订。很多人搜到“grbl 1.1h.20190825.zip”这个文件,它是2019年8月25日打包的1.1h版本。这个版本在CNC圈子里用得极广,几乎所有上位机软件(Candle、LaserGRBL、UGS)都按它的串口协议来做适配。
相比更早的0.9版本,1.1h在几个关键点上有实质改进:
- 支持激光模式($32=1),开启后可以让主轴PWM在运动指令中随速度调节,用于激光雕刻机时能明显改善烧蚀效果。
- 软限位和硬限位处理更完善,回原点时的掉电保持逻辑更稳定。
- 参数存储使用EEPROM,烧录后可以通过串口命令动态调整而不需要重新编译。
如果你只是做试验,不想要太多花活,1.1h就是目前最“省心”的选择。新版grbl也分成grbl和grblHAL两个方向,但后者通常跑在STM32等更高级的MCU上,不是ATmega328P的正统玩法。
3.2 编译环境的两种准备方式
给ATmega328P烧grbl,有两条路可以走。
第一条路是Arduino IDE。它最适合新手,因为你只需要把grbl源码作为库安装,然后打开一个示例工程选择板型和端口点上传。缺点是Arduino IDE对于自定义Makefile项目和编译参数的暴露有限,但grbl官方已经做了适配,完全够用。
第二条路是PlatformIO。适合已经用VS Code开发、想在命令行做版本管理、批量编译的朋友。在platformio.ini里指定:
[env:uno] platform = atmelavr board = uno framework = arduino monitor_speed = 115200然后项目目录下放grbl源码,用pio run -t upload就能烧录。PlatformIO好处是编译速度快、日志清晰,出问题时能直接定位到某个源文件。
3.3 Arduino IDE方式:完整步骤
如果你的目标是“赶紧把grbl跑起来”,按下面这套步骤走,基本不会卡壳:
- 解压grbl 1.1h.20190825.zip,你会看到一个名为
grbl的顶层文件夹,里面还有src和examples等子目录。 - 把整个
grbl文件夹复制到Arduino的libraries目录。Windows用户一般在“文档/Arduino/libraries”下,macOS用户是“文稿/Arduino/libraries”。 - 打开Arduino IDE,菜单选择“项目 -> 加载库 -> 添加.ZIP库…”,也可以直接选中刚才那个grbl目录。有部分IDE版本会优先显示
grbl/examples/grblUpload路径。 - 打开示例:文件 -> 示例 -> grbl -> grblUpload。这个示例代码非常短,核心就一句话:
#include <grbl.h>真正干活的其实是grbl库里的初始化代码和main函数替换。这行include只是触发整个库的编译入口。
- 开发板选择:工具 -> 开发板 -> Arduino Uno。如果你的单板用的是ATmega328P但晶振不是16MHz,需要确认Bootloader是否匹配。
- 端口选择:选到CH340G对应的串口号。Windows下如果识别成“USB-SERIAL CH340”就对了,Linux下通常是
/dev/ttyUSB0。 - 点击上传。正常情况会用几十秒完成编译,然后写入。如果你看到类似“avrdude: stk500_recv(): programmer is not responding”的提示,说明Bootloader缺失或串口被占用,后面的排查章节我会细说。
3.4 烧录后必做的验证:串口里那句“Grbl 1.1h”
烧录完成后,把Arduino IDE自带的串口监视器打开,波特率选115200,然后手动复位一下板子。如果你看到一段类似这样的问候语:
Grbl 1.1h ['$' for help] [MSG:'$H'|'$X' to unlock]恭喜,固件已经在跑了。接下来按顺序测试这些命令:
$$:打印全部参数。看到类似$0=10(步进脉冲时间)这样的输出,说明串口通信和EEPROM读写都是好的。$X:解锁告警状态。grbl上电后默认是锁定状态,不执行运动指令。新板子第一次用,这一步不做到后面不管发什么G0都不会动。$H:执行回原点。只有接好限位开关的机器才能完整跑完,如果你的雕刻机还没装限位,可以跳过,不影响普通手动测试。$J=G91X10F300:以300mm/min的进给率,相对移动10mm。这条命令不需要限位开关,是验证步进电机是否转动的快速手段。
我个人建议,在真正用上位机连接之前,先在这个串口监视器里把上面这几条命令跑一遍。如果直接在Candle里发G代码,遇到电机不动时你很难分清是“固件没烧对”还是“上位机参数没设对”。先剥离上位机因素,串口裸命令测通了,后面问题定位会比别人快很多。
3.5 步进电机每毫米脉冲数计算
grbl里$100、$101、$102分别代表X、Y、Z轴每毫米需要多少个步进脉冲。这个值搞错,雕刻出来的尺寸就会成比例偏移。计算公式是:
每毫米脉冲数 = (电机每转步数 × 驱动细分) ÷ 单轴每毫米移动距离举例说明:一个步进电机步距角1.8°,意味着200步转一圈;A4988驱动板设置16细分;丝杆导程5mm,即电机转一圈,滑台移动5mm。那么:
每毫米脉冲数 = (200 × 16) ÷ 5 = 640所以$100、$101、$102都填640。如果是同步带传动,公式略有差别:假如用20齿同步轮配2mm齿距的GT2皮带,电机转一圈移动40mm,同样16细分下就是(200×16)÷40=80步/mm。
你可能注意到,同样的电机,配置差别能导致$100值从80跳到640。这就是为什么烧录固件后一定要先算这一步,千万别抄网上别人的参数——不同机器的传动比完全不一样。
4. 实际运行中,我踩过的几个坑和完整排查链路
烧录grbl成功只是第一步。实际插上CNC Shield、接上电机,各种诡异问题才会真正出现。下面这几个坑我都在项目验证阶段真实遇到,而且都是那种“看似很好排查、实则花了整晚”的级别。
4.1 串口被Shield上的设备占用,导致上位机连不上
现象:Candle或LaserGRBL点击连接后指示灯一直闪,串口偶尔能收到乱码。排查了一圈,发现不是没装驱动、不是波特率不对,而是Shield上插的BLTouch传感器模块把D0/D1引脚占用了。
在标准Uno上,D0/D1是板载USB转串口的RXD/TXD,同时这两个引脚也引到排针。如果Shield上的某个模块也驱动D0/D1,信号就会互相打架。用单板兼容板时也一样,如果不做隔离,这块Shield模块的直通信号会把CH340G的输出顶住。
解决办法:我后来在单板上把D0/D1的排针连接改为通过跳线帽短接。正常使用USB串口时,跳线帽装上去,排针侧的D0/D1和CH340G连通;要用外接串口设备时,拔掉跳线帽,排针直接给外部模块。这样改动之后,再也没碰到过串口冲突。
排查链路建议:先拔掉所有Shield,只留USB线,看串口能否收到grbl欢迎信息。如果OK,再逐步插回Shield模块,每次插回一个都重新连接测试。这样能很快定位是哪块模块“霸占”了D0/D1。
4.2 电机丢步:不是配置问题,是电源和地线的问题
现象:发$J=G91X10F300时电机转得很勉强,声音发闷,有时转着转着突然停住或者反向走一小段。打开串口监视器,grbl并没有报错——这意味着grbl认为脉冲已经发出去,但电机实际没跟上。
根因几乎都在VMOT供电不足或地线压差。A4988的VMOT一般需要8-35V,我习惯用12V 3A电源。如果直接把12V接到板上VIN引脚,再从VIN插针飞到CNC Shield的VMOT,那条细长的杜邦线可能会成为瓶颈:电机启动瞬间电流一冲,VMOT电压跌落到驱动芯片的欠压阈值以下,驱动芯片自动半流或者关断,电机自然就丢了步。
排查步骤:
- 用万用表量VMOT引脚在电机静止和启动瞬间的电压。正常情况下12V电源启动时的跌落不应超过0.5V,如果跌到9V以下,先怀疑线材和连接点。
- 检查Shield的GND和板子GND是不是同一个电位。拿万用表蜂鸣档,测CNC Shield VMOT的GND和USB座外壳间的电阻,理想状态下接近0欧姆。
- 在VMOT和GND之间加一个100-470uF的电解电容,很多人忽略这一步,但A4988数据手册明确建议加。电源线上有感性成分时,这个大电容能吸收瞬时大电流。
修复后实测,同样的电机和配置参数,电机运转声音干净很多,高进给率下也不再停顿。这个坑,说透了就是“逻辑上没问题但电气上没准备好”,最容易让人怀疑固件配置。
4.3 激光模块的PWM接错引脚
现象:做激光雕刻机时,插上激光模块,上位机里开了激光,但激光头不亮,或者一直满功率亮着不受控制。
原因:grbl对引脚的定义和普通Arduino的PWM引脚编号不是一回事。grbl默认把主轴PWM输出放在D11,而不是新手更容易想到的D9。在CNC Shield V3板上,D11这个引脚正好通过一个跳线帽接到激光输出的MOS管控制端,如果跳线帽没插,或者你飞线接到了D9,激光自然没有信号。
另外,激光模式下需要把grbl的$32设置为1,这样主轴PWM才会在激光加工时随着运动速度做对应调节;不设置的话,PWM输出只在M3指令时打开,运动指令期间功率不变化,雕刻效果会很难看。
排查链路建议:先在串口监视器发M3 S1000,用万用表量D11引脚,应该有约50%占空比的方波;再发M5关闭,确认输出变为0。如果D11有信号而激光头不动作,检查Shield上对应跳线帽和MOS管电路;如果D11没信号,查$32配置和grbl编译选项。
4.4 烧录成功但Shield不工作:IOREF和复位时序的光。
还有一个不太容易想到的坑:单板兼容板的复位信号时序和官方Uno不一致。Uno的复位引脚上有个100nF电容到地,USB转串口芯片的DTR信号通过一个电容耦合到复位引脚,从而实现“打开串口时自动复位”。如果单板上这个电容用得太大或太小,或者DTR信号根本没引出,上位机软件连接时会发现Arduino自动复位再握手,最终导致连不上。
至于IOREF,某些Shield通过检测IOREF来判断板子逻辑电平。如果IOREF悬空或者接错,电平转换芯片会认为自己工作在3.3V,而ATmega328P送出的是5V逻辑,转换后的信号高电平阈值错位,表现为“串口能收到数据但指令不响应”。
我在自己板上专门把IOREF用粗线连到5V,并在背后预留一个0欧电阻位。如果你有意改成3.3V逻辑的MCU(比如换成ATmega1284P或STM32),可以通过改这个电阻来切换,Shield能自动适应。
4.5 Bootloader和熔丝位:自画板最容易卡住的一关
如果你是完全自绘的单板,而不是直接用市面上现成的Uno兼容板,那么芯片出厂时往往是空白的,既没有Bootloader,熔丝位也不对。直接通过USB口烧grub是不可能的——因为CH340G只是个串口转USB芯片,芯片里没有引导程序,自然无法响应串口烧录协议。
解决办法是用USBasp或者其他Arduino板做ISP烧录器。把ATmega328P的ICSP引脚接好,然后:
avrdude -c usbasp -p m328p -U flash:w:grbl.hex:i -U lfuse:w:0xFF:m -U hfuse:w:0xDE:m -U efuse:w:0xFD:m这里的熔丝位数值对应16MHz外部晶振、掉电检测开启等配置,和官方Uno是一致的。如果你用的是Arduino板做ISP,也可以在Arduino IDE里通过“烧录Bootloader”功能先把Bootloader烧进去,之后就能用USB口正常串口上传grbl了。
这一关卡住的典型情况是:烧录时USBasp连接失败,或者提示“target is not responding”。优先检查ICSP头的方向,其次检查板子供电和晶振是否焊接良好。我前面说的ICSP方向画反案例,就是在这里炸出来的。
5. 一些实在的使用建议:把这块单板真正用顺
写到这里,硬件设计和固件烧录的主线基本都覆盖了。最后分享几个我在实际项目中摸索出的小习惯,算不上高大上,但能省很多时间。
第一,板上留一个串口调试排针。哪怕平时根本不用,但在出问题时,能把逻辑分析仪或者USB-TTL模块直接怼上去,绕过CH340G看芯片原始输出的情况,会极大加速排查。我见过很多“连不上串口”的案例,最后查出来是CH340G没焊接好或者驱动异常,而不是MCU的问题。
第二,给VIN输入端加一个自恢复保险丝。电机驱动器堵转时电流尖峰很高,自恢复保险丝能避免把板上降压电路和上位机USB口同时带走。成本几毛钱,但能救一板子芯片。
第三,grbl参数记得在确认无误后通过$命令导出保存。用上位机的“设置”界面一次性导入导出,方便随时恢复到稳定状态。
第四,插拔Shield前养成断电习惯。很多A4988和Arduino芯片不是正常工作时坏的,而是带电插拔Shield时,电源脚先接触而信号脚后接触,瞬间过压把引脚打坏。做CNC项目的人,一定要把“断电插拔”刻进肌肉记忆。
这块单板我后来不仅用于grbl,还刷过Marlin做过简单的3D打印机上位实验,也把它当普通Arduino Uno替换板用在几个传感器采集项目里。从实际效果看,只要能守住Uno R3的电气和机械标准,单板带来的稳定性和整洁度提升非常明显。希望这篇文章能帮你少走点路,如果你也在做类似的单板兼容方案,欢迎一起交流移植过程里踩到的细节。
