从选题到上手两三天,有个问题我一直避不开:树莓派和 Arduino 到底怎么选。老玩家嘴里那句“一个跑系统、一个跑裸机”,放在十年前确实是教科书级别的答案,但放到今天,这个说法已经不太能帮助你做决策了。更麻烦的是,如果你真的照着这句话去选硬件,大概率会买错板子,或者把项目做得特别别扭。我见过太多在这上面纠结的人,包括我自己早期也走过弯路,所以想好好把这笔账算清楚。
我发现“一个跑系统、一个跑裸机”之所以流行,是因为它把两个平台最显眼的区别浓缩成了一句话。树莓派插电就能进 Linux 桌面,能装软件、跑容器、开网页服务;Arduino 插电直接就从上电复位开始执行程序,没有桌面、没有多任务,只有一段你在 IDE 里写好的程序在反复循环。这种对比通俗直观,早年间用来给新手做科普非常合适,因为那时候树莓派和 Arduino 的定位也确实像两个平行世界。
但近几年的形势已经明显变了:树莓派官方自己也出了不带 Linux 的微控制器板卡,而 Arduino 生态里也在往多核、Wi-Fi、甚至嵌入式 Linux 方向试探。两个阵营中间出现了大片的交叉地带,好多场景里你用哪个都能做,但用错了要付出额外代价。与其背口诀,不如重新认识这些硬件背后真正决定体验的东西。
1. “一个跑系统、一个跑裸机”是怎么来的
1.1 这句话在十年前确实能说明问题
树莓派第一个型号面世时,基本就是一台缩水小电脑。它用的是 ARM 架构的应用处理器,能跑完整的 Linux 系统;内存虽然少得可怜,但也有 256MB,在今天看来啥也干不了,在当时已经能撑起图形界面。它带的那些 GPIO 引脚、HDMI 接口、USB 口,让大家第一次觉得“两百来块的开发板居然能当电脑用”。
Arduino 的核心则是单片机,跟树莓派完全不是一个思路。经典型号用一颗几十 MHz 的处理器,搭配几 KB 内存,没有存储器管理单元,跑不了现代操作系统。你在上面写代码,本质上就是给一颗小芯片安排它每一个时钟周期该干什么。所有任务都在一个主循环里轮转,中断一进来就去处理,处理完再回到原来的位置继续跑。这种工作方式就是大家说的“裸机”。
所以早期两者几乎没有可比性:一个跑 Linux 多任务,一个是循环加中断;一个能用 Python,一个只能写 C/C++;一个几百毫秒才能完成开机启动,一个上电几十毫秒已经在执行指令了。用“一个跑系统、一个跑裸机”来划分,在当时确实简洁而准确。
1.2 现在为什么站不住脚了
变化先从硬件形态开始。树莓派官方后来推出了微控制器板卡 RP2040 系列,也就是 Pico 系列,它们根本不跑 Linux,完全就是单片机裸机玩法。如果你还坚持“树莓派=跑系统”,第一次见到 Pico 时就会有一种错乱感。
另一边,Arduino 也不止当年的八位机了。带有 Wi-Fi 和蓝牙的 Arduino 板卡已经开始接触网络、加密、协议栈,甚至有人在 Arduino 上跑轻量级实时操作系统。更别说大量兼容 Arduino 生态的第三方板卡,基于更强性能的 ARM 内核,有的甚至也具备跑微型 Linux 的能力,只是大家习惯性把它们归在“Arduino”这一类下面。
再往整个行业看,一些原本只在手机或工业设备上使用的应用处理器价格不断下降,很多开发板跑 Linux 的成本和当年 Arduino 已经接近。云南地摊上都能看到的“刷机神器”开发板,其实大多是嵌入式 Linux 设备,要硬套“裸机”思维去看它们,也会发现很多操作对不上。
所以问题不在于这句话说错了,而在于它太粗糙,粗糙到已经无法覆盖现在这个混合生态。拿它当选型依据,就像用“只跑小型车的路一定是窄路”来判断所有道路,路况一变,方向也就跟着偏了。
2. 别被操作系统骗了:真正要对比的是底层能力
2.1 应用处理器和微控制器的本质差异
想搞清楚选型,得先放下“跑不跑系统”这个概念,去看芯片层面怎么会变成今天这样。
树莓派主力型号用的是应用处理器,内部结构接近手机芯片。它有更像样的内存管理单元,能跑完整 Linux、支持进程隔离、虚拟内存,USB、网络、图形这些功能都靠外设控制器实现。操作系统帮忙管理资源,你写程序时不用操心内存在哪里分配、哪个进程占用 CPU,整体开发效率和跑复杂应用的起点高非常多。
Arduino 核心用的是微控制器。微控制器通常把 CPU、内存、存储、各种接口集成到一颗芯片里,成本低、功耗低、启动快,但没有进程概念,也不会动不动跑一个几十 MB 的内核。你要做的是直接在硬件上操作,代码写得越贴近寄存器,行为就越可控。好处是实时性和时序确定性很好,坏处是所有东西都得自己来,复杂应用开发起来慢。
拿延时和中断打个比方。在树莓派上跑 Linux,你很难精确做到“每 10 微秒执行一次任务”,因为操作系统调度、内存页面换入换出都会让执行时间抖动。但微控制器上,只要你写好定时器中断,它就能像节拍器一样稳定触发,抖动通常只有几十纳秒到几微秒级别,这种特性在做波形采集、电机控制、传感器读数时极其重要。
2.2 实时性不是一个操作系统问题
很多人以为只要上了 Linux,实时性就一定差;只要跑裸机,实时性就一定好。这其实是个误区。Linux 内核可以打实时补丁,各种高精度定时器也都能用,只是它要做太多通用性工作,在严苛场景下做不到微控制器那么绝对可控。
反过来,微控制器也不是天然都具有优秀的实时性。高频率的库函数、动态内存分配、频繁开关中断等不良习惯,一样能让裸机程序反应迟钝。我见过有人在 Arduino 上用官方库里带阻塞延时的方式处理按键扫描,结果响应慢得离谱,那并不是硬件不行,而是软件把实时性浪费掉了。
所以,“跑不跑系统”决定的是软件生态和使用方式,而“实时性好不好”取决于芯片设计、中断架构和你的代码写法。这两个维度一旦分开,选择思路就清晰了很多。
2.3 功耗、外设、网络:真正拉开差距的地方
现在很多项目根本不缺算力,反而被电力、外设、联网方式限制了。这是我推荐别人做选型时最先问的三个问题。
功耗方面,树莓派一开机动辄就是几瓦的功耗,加上供电要求高,做电池供电的便携设备非常吃力。Arduino 和同级别的微控制器,睡眠电流可以做到微安级别,一节电池撑好几个月很常见。如果项目要求“挂在野外一个月换一次电”,那树莓派基本被排除。
外设方面,有些项目需要采集大量视频、跑神经网络、处理音频,这些恰恰是应用处理器的强项。微控制器虽然也有摄像头接口,但做本地图像识别非常费劲,算法模型和算力差距是跨不过去的。反之,如果你要接一堆传感器,每个都需要快速采样和多路并行,树莓派那套基于 Linux 的 GPIO 访问反而不太好使,因为驱动和调度带来的开销不小,远不如微控制器直接读寄存器来得爽快。
网络方面,嵌入式 Linux 板卡最容易接入复杂的协议栈,抓包、调试、跑 HTTPS、搭本地服务都很方便。微控制器则更灵活,很多芯片自带 Wi-Fi 模组,做低功耗联网也做得好,但协议栈调试起来繁琐,出错定位也更花时间。
3. 现实的选型,按场景重新拆
3.1 优先选树莓派的场景
我自己最常用的一个经验法则是:凡是需要把数据“变成人看得懂的内容”,树莓派优势就明显。典型场景包括做局域网内的小型监控服务、数据展示面板、音频处理、模型推理。
举个例子,我想做一个家庭服务器,定时抓取一些天气数据,再用图表展示到网页上。树莓派开箱即有 Python 环境,装个轻量的 Web 框架,几行代码就能把数据服务和前端页面搭起来,如果用 Arduino 做这个,光处理网络协议栈、文件系统、网页渲染就能耗掉绝大部分精力,最后得到的效果还差强人意。
另一个强项是容错和升级。树莓派上部署服务,程序挂了系统一般还在,SSH 进去重启服务就行。Arduino 上程序崩溃时,往往只能手动复位,或者依赖看门狗电路做自动恢复,调试一轮下来比写功能还累。所以只要是“长时间运行、需要稳定服务的后台任务”,我会推荐嵌入式 Linux 板卡。
3.2 优先选 Arduino 的场景
反过来,当你需要和真实的物理世界做精确实时交互时,Arduino 这类微控制器的优势就很突出。电机控制、传感器高速采集、PWM 输出、精准触发外部设备,都是它的主场。
我曾经做一个平衡小车项目,最初图省事用树莓派直接控制电机,结果轮子响应速度一直跟不上姿态变化,无论怎么调参数都显得迟滞。后来把控制部分移到 Arduino,树莓派只负责跑算法和传目标值,系统一下子就顺了。原因很简单:电机控制需要微秒级的 PWM 更新和中断响应,Linux 的调度器再怎么优化,也很难赶上这种节奏。
还有一类场景不得不选微控制器:其实你并不想写一堆底层驱动,但你需要设备在通电的瞬间就能干活。民用小家电里的面板控制、智能插座、遥控器,基本全是微控制器。它们上电到开始工作只需几十毫秒,成本还便宜,换电池也能坚持很久,这是大个的嵌入式 Linux 板卡做不了的。
3.3 “中间地带”反而最容易让人翻车
真正让人纠结的,往往是那些“两头都能干”的中间项目。典型代表比如智能家居网关、简单的图像识别门禁、温室环境监控。这类项目既需要一些网络能力和简单的数据处理,又需要采集传感器并做实时控制。
我见过有人用树莓派做温室监控,接了一堆温湿度传感器,结果采集频率稍微一高,数据总是不稳定。原因不是传感器坏了,而是树莓派跑 Linux 时 GPIO 读取受系统负载影响,时序抖动大,采集精度不理想。其实这种场景用 Arduino 读数据、再用串口把数据送给树莓派做存储和展示,结构会舒服得多。
反过来也有人用 Arduino 做智能家居中枢,希望它直接对接 Wi-Fi、跑加密协议、管理多个子设备,结果 Flash 和内存紧张得不行,代码里到处省着用,最后维护噩梦。这种情况不如直接上嵌入式 Linux 板卡,资源充裕,调试工具也更顺手。
中间地带的正确打开方式,通常不是二选一,而是让两者分工各干各擅长的部分。这个思路我在后面会展开细说。
4. 选型判断步骤:从我真实项目里总结出来的方法
4.1 用四个问题快速做初步筛选
我可以把多年的经验简化成四步,基本能覆盖大部分选型需求。
第一步,问自己“设备有没有显示器或人机交互界面需求”。如果有复杂界面、网页、触摸屏,基本可以直接选嵌入式 Linux 板卡;如果只是几个按键加一块数码管或小屏,微控制器就够了。
第二步,问自己“响应时间要求有多严格”。如果要求毫秒级以内的确定性反应,比如电流环、伺服控制、高频采样,微控制器优先。如果反应在几十毫秒以上,或者可以容忍系统延迟,树莓派没问题。
第三步,问“供电方式是什么”。插电使用无所谓;电池供电且要求数月不充电,那微控制器是唯一合理选择。
第四步,问“开发周期和代码复杂度”。这个最容易被忽略。如果项目逻辑复杂,涉及大量协议、数据库、多线程,用树莓派上的 Linux 生态能节约大量时间;如果项目代码短、逻辑直接、核心就是循环加中断,Arduino 更合适。
我把这四步做成一个粗略的判断表,实际用起来挺好上手。
| 判断维度 | 倾向树莓派 | 倾向 Arduino |
|---|---|---|
| 交互界面 | Web界面、桌面、触摸屏 | 数码管、LED、小屏 |
| 响应速度 | 能容忍几十毫秒抖动 | 需要微秒级确定性 |
| 供电约束 | 电源适配器、插电环境 | 电池、低功耗长期运行 |
| 软件开发 | Python、服务、多线程 | C/C++、循环加中断 |
| 联网需求 | 复杂协议、加密、大流量 | 低功耗传感器网络 |
| 成本敏感度 | 稍高但算力强 | 极低,适合量产 |
4.2 再深入一步:把资源抠细
标题门槛过完之后,我习惯再估算一下资源开销,避免后面开发到一半发现平台选窄了。
先从内存看。如果你打算跑一个 Linux 服务,还要装数据库和 Web 框架,那至少需要 512MB 内存才舒服,树莓派的入门型号通常可以胜任;如果你想在微控制器上做类似事情,先想想它的内存可能只有几百 KB,连一张普通网页的字符串都放不下。
再算算存储。树莓派的 SD 卡或硬盘动辄几十 GB,存视频、日志都很宽裕;微控制器的 Flash 可能只有几 MB,一段复杂的语音识别代码可能就塞满。比如做本地语音词条识别,你用树莓派可以用开源模型直接跑,效果还不差;在 Arduino 上做同样的功能,往往只能做非常有限的关键词匹配,还要仔细裁剪模型。
然后看外设接口。树莓派虽然有 GPIO,但它的 I2C/SPI 接口在 Linux 驱动下有一定延迟,做高频通信时不如微控制器顺手。Arduino 直接操作寄存器,可以做到很高频率的时序输出,甚至可以软件模拟各种协议。不过 Arduino 没有原生 USB host 能力,想接 U 盘、键盘、摄像头,会绕很多弯路,树莓派在这些场景里又是完胜。
算完这些资源,选型基本能确定。再纠结就把原型分别跑一遍,用真实数据说话。
5. 高级玩法:不要只选一个,让它们组队
5.1 树莓派和 Arduino 之间怎么通信
很多项目做到最后会发现,最合理的结构不是二选一,而是树莓派当大脑、Arduino 当手脚。我自己的好多项目都是这个模式,通信方式也成了关键。
最常用的连接方式是 USB 串口。把 Arduino 用 USB 线接到树莓派上,树莓派里会出现一个串口设备,直接读写串口就能互通。这个方法最简单,而且 USB 天然带了供电隔离和稳定的驱动,适合大多数场景。
如果两个板子靠得近,还可以直接接 UART 引脚、I2C、SPI,通信速度更高,延迟更低。我对时序有要求时一般用 SPI,它的速率高且双向通信方便;普通传感器数据交换用 I2C 就够,接线还少。
这里有个容易踩的坑:两个板子如果各自独立供电,就要处理好共地。树莓派和 Arduino 之间信号线必须有一个共同的地线,否则电平参考点不一致,数据乱码、偶尔死机都是这么来的。我用 USB 连接时没这问题,因为 USB 线本身就带了地线;用引脚直连时一定记得把两边 GND 接在一起。
5.2 一个可靠的分工模式
我比较常用的一套职责切分是:树莓派负责与用户打交道、联网取数据、做复杂计算;Arduino 负责实时采集数据、控制执行器、处理高频中断。树莓派上层的决策指令,通过串口发给 Arduino,Arduino 执行完再把状态和采集结果回传。
做一个网络安防巡检的小机器人时,我就是这么做的。树莓派跑视觉识别,通过摄像头判断目标和路径,同时把速度和转向指令通过串口发给下方的 Arduino;Arduino 读取编码器、控制电机、管理避障用的超声波传感器,再把里程计和障碍信息回传。这样树莓派不必去面对微秒级的电机控制,Arduino 也不用手忙脚乱地处理图像数据,两边压力都不大。
通信协议一定要设计得简单可靠。我习惯用固定长度的帧,帧头、长度、指令类型、数据区、校验位一应俱全。别嫌校验多余,现场有电机、继电器这类强干扰源时,串口线上偶尔会有毛刺,没有校验你就会收到莫名其妙的数据。我遇到过好几次,加了简单的和校验和 CRC 之后,系统立刻稳定很多。
这个组合模式下,还有个好处是开发节奏会快很多。树莓派上的算法随便改,不用重新烧录;Arduino 上的控制代码写好一次就是一次,这部分逻辑本来就变动少。两边各改各的,连调起来省心不少。
6. 我踩过的坑和几条实在建议
6.1 翻车现场:被过时口诀坑掉的真实经历
我开始做嵌入式那阵子,坚信“跑系统就不适合实时控制”,于是一个语音控制小车项目里,我坚持用 Arduino 做全部逻辑,包括语音识别前端的音频采集。结果内存根本不够用,模型放不下,只能退而求其次用一个非常简陋的关键词检测,识别率低得让人崩溃。
后来换了一种做法,把语音识别放在树莓派上用现成的开源库跑,识别的结果通过串口发给 Arduino,Arduino 只负责驱动机器人动作。同样的硬件,体验直接从“能响但识别不了”升级到“说一句动一下”。这让我彻底明白,实时控制不需要整台设备都实时,只需要实时的那部分由实时子系统承担就够了。
反过来我也见过另一位开发者把电机启停控制全放在树莓派上用 GPIO 切换,程序里各种线程一多,电机的换向动作总是慢半拍。明明换个单片机控制电机就能解决的问题,他硬是调了整整一周的 Linux 调度参数,最后还是换方案了。
6.2 别被观念锁死,学会按阶段选硬件
现在我选型时会多问一句:这个项目是做一个原型验证,还是要长期稳定运行?如果是快速验证想法,我会优先树莓派,因为开发环境舒服、库多、出活快,哪怕 I/O 时序不佳,先跑通逻辑最重要;等逻辑确定、准备部署成小批量样品时,再考虑把实时控制部分移植到微控制器,能在性能和成本上都优化不少。
有人会担心这样重复劳动,其实完全不会。验证阶段用树莓派玩逻辑,真正部署时把逻辑里和硬件强相关的部分剥离给 MCU,是嵌入式圈子里很常见的迭代方式。我有个习惯是把数据处理和控制决策尽量分模块写,后面就能在平台之间平滑迁移,省掉很多重写的时间。
最后说一句很多教程不会讲的事:所谓“一个跑系统一个跑裸机”,在今天的意义更多是帮助你理解工作方式,而不是直接告诉你选哪个。Arduino 项目里可以出现网络服务和复杂状态机,树莓派项目里也可以有裸机式的底层操作。真正决定选型的,永远是你项目的需求、你的开发效率和目标场景的约束条件。把这句话从“标准答案”改成“背景知识”,手里的板子会用得更顺。
我个人目前的做法是桌上常备一套树莓派加一套 Arduino,两边的工程环境都留着。遇到新项目,先想清楚要经过哪些硬件,再决定是让树莓派出场、Arduino 出场,还是两个一起上。这样思考之后,基本不会再纠结“怎么选”这种问题了。