☰
树莓派跑系统Arduino跑裸机已过时?2025年硬件选型实战指南
2026/10/13 4:03:47 网站建设 项目流程

1. 那句流传十年的“跑系统与跑裸机”到底在说什么

“树莓派跑系统,Arduino跑裸机”——这句话在创客圈子里流传了差不多十年,几乎每个刚接触硬件的新人都会在论坛、视频评论区或者某篇入门文章里看到它。它的逻辑听起来很干净:树莓派是一台完整的微型计算机,上面跑着Linux,有文件系统、有进程调度、有网络协议栈;Arduino是一颗单片机,你写的代码直接编译成机器指令,烧进去之后从头到尾就你一个程序在跑,没有操作系统在中间插一脚。于是结论就来了:要复杂计算、要联网、要接屏幕,选树莓派;要实时控制、要低功耗、要稳定响应,选Arduino。

这个二分法在2015年前后基本是对的。那时候树莓派最新型号是Pi 2,主频900MHz,单核性能勉强够用,GPIO的实时性一塌糊涂——你在Python里写个GPIO.output(),从调用到引脚真正翻转,中间可能隔了几十微秒甚至几百微秒,因为Linux调度器随时可能把你的进程踢出去干别的事。而Arduino Uno用的是ATmega328P,16MHz,8位,资源少得可怜,但正因为它简单,一个数字写操作从代码到引脚翻转只需要几百纳秒,确定性极强。所以那时候的选型逻辑很清晰:谁干实时谁用Arduino,谁干逻辑谁用树莓派。

但问题是,这句话被当成了永恒真理,一直传到今天。而今天的硬件早就不是那个样子了。树莓派5用的是四核Cortex-A76,主频2.4GHz,内存最高8GB,PCIe接口都给你了;Arduino这边,Uno R4用的是32位Cortex-M4,带FPU,主频48MHz,还有ESP32这种怪物——双核240MHz,自带WiFi和蓝牙,价格比Uno还便宜。更关键的是,树莓派上现在可以跑实时内核补丁,Arduino这边也能跑FreeRTOS做多任务调度。“跑系统”和“跑裸机”的界限已经模糊到不能再模糊了。

我写这篇东西的目的很简单:把那句过期的话拆开,告诉你今天到底该怎么选。不是给你一个“A好还是B好”的结论,而是给你一套判断框架——你的项目到底需要什么,哪个平台在今天的硬件条件下能更好地满足它,以及那些“两个一起用”的方案到底值不值得。如果你正在纠结第一个硬件平台选哪个,或者手头有个项目不知道该往哪个方向走,这篇应该能帮你省下不少试错的时间。

2. 实时性这件事,树莓派早就不是当年的树莓派了

2.1 从GPIO翻转速度看“实时”的真实含义

很多人说“Arduino实时性好”,但如果你追问一句“多好”,大部分人答不上来。我们先把这个东西量化一下。所谓实时性,在嵌入式语境里通常指两件事:一是响应延迟,从事件发生到你代码里感知到它花了多久;二是抖动,这个延迟的波动范围有多大。抖动比延迟更致命——如果每次都是固定延迟10微秒,你可以补偿;如果延迟在1微秒到1毫秒之间随机跳,那你的控制环路就没法稳定工作。

在Arduino Uno上,一个digitalWrite()的执行时间大约是3.4微秒,而且这个数字非常稳定,因为没有任何东西会打断你的代码。在树莓派4上,用Python的RPi.GPIO库做同样的操作,平均延迟大概在50到100微秒,但抖动可以大到几毫秒——因为Linux内核随时可能去处理网络中断、文件系统写入或者内存回收。这就是“跑系统”带来的代价。

但树莓派5加上实时内核补丁之后,情况变了。PREEMPT_RT补丁把Linux内核中绝大部分不可抢占的区域都改成了可抢占的,中断处理线程化,自旋锁变成了可睡眠的互斥锁。实测下来,在树莓派5上跑PREEMPT_RT内核,用C语言直接操作GPIO寄存器,GPIO翻转的抖动可以压到50微秒以内,平均延迟在10微秒左右。这个数字已经能覆盖大部分“软实时”场景了——比如电机控制、传感器轮询、LED矩阵刷新,甚至一些低速的PID环路。

2.2 什么时候你仍然需要一颗真正的单片机

但“软实时”和“硬实时”之间有一条硬线。硬实时的定义是:错过截止时间就等于系统失败。比如你做一个无刷电机的换向控制,电角度每60度要换一次相,转速一万转的时候这个间隔只有几十微秒,抖动超过几微秒电机就会抖甚至失步。这种场景下,Linux再打补丁也救不了你——因为Linux的调度器本质上还是“尽力而为”,它不提供数学上的最坏情况延迟保证。

这时候Arduino或者任何一颗裸机单片机仍然是唯一选择。但注意,我说的是“裸机单片机”,不是“Arduino”这个品牌。你可以用Arduino IDE写ESP32,也可以用PlatformIO写STM32,甚至可以在树莓派的RP2040芯片上跑裸机代码——RP2040就是树莓派基金会自己出的单片机,双核Cortex-M0+,133MHz,带可编程IO(PIO),价格只要几块钱。所以“跑裸机”这件事跟“用不用Arduino”已经没有必然关系了。

我自己的经验是:如果你的控制环路频率在1kHz以下,树莓派加实时补丁基本够用;1kHz到10kHz之间,看你的抖动容忍度,可能需要一颗单片机做协处理;10kHz以上,别犹豫,直接上裸机单片机。这个分界线不是绝对的,但可以作为一个起点。

2.3 树莓派RP2040带来的新变量

RP2040这颗芯片值得单独说几句,因为它直接模糊了“树莓派”和“Arduino”的边界。它是一颗单片机,但它是树莓派基金会设计的;它可以用Arduino IDE开发,也可以用MicroPython,还可以用C SDK裸机编程。它的PIO(可编程IO)模块允许你自定义引脚行为,比如实现精确的WS2812时序、做高速SPI从机、甚至模拟VGA信号——这些在传统单片机上要么做不了,要么需要极精细的汇编调优。

我拿RP2040做过一个多路舵机控制器,8路PWM输出,每路独立控制,刷新率400Hz。用Arduino Uno做同样的事情,定时器资源根本不够,得用软件模拟,抖动大得没法看。用RP2040的PIO,每路舵机就是一个状态机,硬件自动生成波形,CPU几乎不参与。这个例子说明什么?说明“单片机做实时控制”这件事本身也在进化,不是只有Arduino那种“简单粗暴”的路子。

所以当你听到“树莓派跑系统、Arduino跑裸机”的时候,脑子里应该自动翻译成:“Linux平台适合非硬实时的复杂逻辑,裸机平台适合硬实时的确定性控制。”至于具体用哪块板子,那是另一个维度的问题。

3. 算力与生态:选型时真正该算的那笔账

3.1 树莓派的算力优势在什么场景下才成立

树莓派5的BCM2712是一颗四核Cortex-A76,跑在2.4GHz,单核性能大概是Arduino Uno的ATmega328P的几千倍。这个差距在跑分上很震撼,但在实际项目里,大部分时候你根本用不到。一个温度传感器每秒钟读一次,一个继电器每天开关几次,这种场景下树莓派的算力99.9%都在闲置。

树莓派的算力真正有价值的场景是这几类:图像处理(OpenCV跑人脸检测、颜色识别、二维码解析)、网络服务(跑MQTT broker、Web服务器、数据库)、复杂算法(机器学习推理、路径规划、FFT分析)、多任务并行(同时处理摄像头、网络、存储和用户界面)。如果你要做的东西需要接一个USB摄像头做实时分析,或者需要把数据存到数据库里再通过网页展示,那树莓派是天然的选择——这些事在Arduino上要么做不了,要么得外挂一堆模块,复杂度反而更高。

但这里有个常见的误区:很多人觉得“树莓派算力强,所以做控制也比Arduino好”。这是把算力和实时性混为一谈了。算力强意味着你能在同样时间内做更多计算,但不意味着你能在确定的时间内完成计算。一个跑在Linux上的Python脚本,即使CPU占用率只有1%,它的GPIO响应延迟也可能比一颗满载的Arduino大两个数量级。所以如果你的项目核心是“精确控制”,算力再强也帮不上忙。

3.2 Arduino生态的护城河正在被侵蚀

Arduino最大的资产不是硬件,是那个庞大的库生态和社区。你想接一个DHT11温湿度传感器,Arduino有现成的库,三行代码搞定;你想驱动一个步进电机,AccelStepper库直接拿来用;你想接一个OLED屏幕,U8g2库支持几十种型号。这种“即插即用”的体验是Arduino十年积累的结果,也是它至今仍然是很多人的首选入门平台的原因。

但这个护城河正在被两边夹击。一边是树莓派这边的Python生态——Python的库数量比Arduino多几个数量级,而且很多硬件厂商现在同时提供Arduino库和Python库。另一边是ESP32的崛起——ESP32可以用Arduino框架开发,意味着它直接继承了Arduino的库生态,同时还自带WiFi和蓝牙,价格还更便宜。我最近做的一个项目用ESP32-S3,在Arduino IDE里开发,接了一个ILI9341屏幕、一个SD卡模块、一个DHT22,所有库都是现成的,编译烧录一气呵成。同样的项目如果用树莓派做,光配置SPI和GPIO就得折腾半天。

所以现在的局面是:如果你要的是“快速把东西做出来”,Arduino框架(不管跑在什么硬件上)仍然是效率最高的路径之一。但如果你要的是“把东西做稳定、做可维护”,那可能得考虑更专业的工具链,比如PlatformIO加ESP-IDF,或者树莓派上的C++直接操作寄存器。

3.3 功耗与成本:被低估的决策因素

功耗这件事在插电项目里不重要,但在电池供电项目里是决定性的。Arduino Uno在5V下跑16MHz,电流大概20mA;树莓派5在空闲状态下也要3W左右,满载能到12W。如果你要用电池跑一个月,树莓派基本不可能——你得配一块巨大的电池,然后大部分电量都浪费在维持Linux运行上。Arduino或者ESP32的深度睡眠模式可以把电流压到微安级别,一颗18650电池能撑几个月。

成本方面,Arduino Uno R3正品大概一百多块,兼容板几十块;树莓派5 4GB版本大概四百多,加上电源、SD卡、散热片,一套下来六七百。ESP32开发板大概二三十块,RP2040大概二十块。如果你的项目只需要控制几个继电器、读几个传感器,用树莓派就是杀鸡用牛刀,多出来的钱和功耗都是浪费。但反过来,如果你需要接摄像头做图像识别,那树莓派反而是性价比最高的方案——因为你需要的那颗能跑OpenCV的芯片本身就比树莓派贵。

我一般会建议新手这样想:先列出你的项目必须完成的三件事,然后问自己“哪块板子能用最低的成本和最简单的代码完成这三件事”。答案往往不是树莓派也不是Arduino,而是ESP32或者RP2040这类“中间态”的板子。

4. 那些“两个一起用”的方案,到底值不值得

4.1 树莓派加Arduino的经典组合

在创客圈子里有一个很常见的架构:树莓派做上位机,负责网络通信、用户界面、数据存储;Arduino做下位机,负责实时控制、传感器读取、执行器驱动。两者通过串口或者I2C通信。这个架构的好处是各取所长——树莓派干它擅长的复杂逻辑,Arduino干它擅长的确定性控制。

我做过一个温室监控项目,用的就是这个架构。树莓派跑一个Python程序,每秒钟通过串口向Arduino发送一次目标温度和湿度,Arduino负责读取DHT22、控制加热器和加湿器、驱动风扇,同时每100毫秒把当前状态回传给树莓派。树莓派把这些数据存到SQLite数据库,同时跑一个Flask网页服务,可以在手机上查看历史曲线和手动调整目标值。这个项目里,Arduino的实时性保证了温湿度控制的稳定性,树莓派的算力保证了数据存储和网络服务的流畅。

但这个架构的代价是复杂度。你得写两套代码,定义一套通信协议,处理串口断连、数据校验、错误恢复。如果通信出了问题,你得同时调试两个平台。我踩过的一个坑是:树莓派在重启的时候串口电平会跳变,导致Arduino收到一堆乱码,有时候会误触发执行器。后来加了一个简单的握手协议和超时保护才解决。所以这个方案适合有一定经验、项目复杂度确实需要两个平台分工的场景。如果你只是控制一个LED灯,别这么干。

4.2 用ESP32替代Arduino做下位机

现在更流行的做法是用ESP32替代Arduino做下位机。原因很简单:ESP32自带WiFi和蓝牙,可以直接和树莓派通过网络通信,不需要物理串口线;ESP32的算力比Arduino Uno强几十倍,可以同时处理多个传感器和执行器;ESP32的价格比Arduino Uno还便宜。我现在的默认方案就是树莓派做网关和数据处理,ESP32做边缘节点,两者通过MQTT通信。

这个架构的灵活性高很多。ESP32可以放在离传感器最近的地方,通过WiFi把数据发到树莓派上的MQTT broker,树莓派再把数据转发到数据库或者云端。如果WiFi断了,ESP32可以本地缓存数据,等网络恢复再补发。树莓派重启不影响ESP32的本地控制逻辑,ESP32死机了树莓派也能通过心跳检测发现并报警。这种松耦合的设计比串口直连健壮得多。

但要注意,MQTT通信本身有延迟,通常几毫秒到几十毫秒,取决于网络质量。如果你的控制环路需要亚毫秒级响应,那还是得用串口或者SPI直连,或者干脆把控制逻辑全部放在ESP32本地,树莓派只做监控和参数下发。

4.3 什么时候该放弃“两个一起用”

我见过不少项目,本来一颗ESP32就能搞定的事情,非要加一个树莓派,结果复杂度翻倍,故障点翻倍,成本翻倍。判断标准很简单:如果你的项目不需要本地图像处理、不需要跑数据库、不需要做复杂的网络服务,那大概率不需要树莓派。一颗ESP32可以接屏幕、可以跑Web服务器、可以连MQTT、可以做简单的数据记录,功耗还低得多。

反过来,如果你的项目需要跑TensorFlow Lite做图像分类,或者需要同时处理多个摄像头流,或者需要跑一个完整的LAMP栈,那树莓派是必须的,这时候再考虑要不要加一颗单片机做实时协处理。不要为了“架构好看”而增加组件,每增加一个组件就多一个故障点、多一份功耗、多一套代码要维护。

5. 从项目需求反推平台:一套可操作的决策流程

5.1 先问三个问题,砍掉一半选项

我一般会先问三个问题,这三个问题能砍掉大部分不合适的选项。

第一个问题:你的项目需要硬实时吗?如果需要,直接排除树莓派跑Linux的方案,不管它打没打实时补丁。硬实时的定义前面说过——错过截止时间等于失败。典型的硬实时场景包括:无刷电机换向、高速PWM调光、精确脉冲计数、高速ADC采样。如果你不确定自己的项目是不是硬实时,那大概率不是。

第二个问题:你的项目需要跑操作系统吗?如果需要跑数据库、Web服务器、图像处理流水线、多用户并发任务,那树莓派是自然选择。如果你只是读传感器、控执行器、做简单逻辑,那操作系统是负担不是帮助。

第三个问题:你的项目是电池供电吗?如果是,优先考虑单片机和深度睡眠方案。树莓派的功耗在电池场景下基本不可接受,除非你配一块很大的电池并且接受频繁充电。

这三个问题回答完,剩下的选项通常只有两三个。然后你再根据算力需求、外设接口、开发效率、成本预算做最终选择。

5.2 一张表看清主流平台的真实定位

平台核心架构典型主频实时性算力功耗(典型)适合场景
Arduino Uno R3ATmega328P 8位16MHz硬实时极低20mA简单控制、教学入门
Arduino Uno R4Cortex-M4 32位48MHz硬实时低30mA中档控制、带DAC
ESP32-S3双核Cortex-M7240MHz硬实时中40mA(WiFi开)物联网节点、带AI加速
RP2040双核Cortex-M0+133MHz硬实时中低20mA精确IO、PIO应用
树莓派5四核Cortex-A762.4GHz软实时高3W-12W图像处理、网络服务
树莓派Zero 2W四核Cortex-A531GHz软实时中1W-3W轻量网关、便携设备

这张表里的“实时性”一栏,硬实时意味着抖动在微秒级且可预测,软实时意味着抖动在几十微秒到毫秒级且受系统负载影响。注意树莓派5的“软实时”是在打了PREEMPT_RT补丁并且用C语言直接操作寄存器的情况下的表现,如果你用Python的GPIO库,抖动会大一个数量级。

5.3 一个真实项目的选型复盘

去年我帮一个朋友做了一套“智能鱼缸”系统,需求是:自动喂食、水温控制、灯光定时、手机远程查看、异常报警。我一开始想用树莓派5做,因为要跑Web服务和摄像头。但算了一下功耗,树莓派5常年开着,一年电费虽然不多,但加上散热风扇的噪音在卧室里很烦人。后来改成ESP32-S3做主控,接温度传感器、继电器、舵机喂食器,跑一个轻量Web服务器,通过MQTT连到家里的服务器做数据存储和远程访问。ESP32的深度睡眠模式让它在不工作时电流降到几十微安,整体功耗不到1W。摄像头功能砍掉了,因为朋友说其实不需要看鱼,只要知道喂食器有没有正常工作就行。

这个案例的教训是:不要因为“以后可能要用”而选择更复杂的平台。树莓派能做的事很多,但你的项目可能只需要其中一小部分。ESP32能做的事也很多,而且它做不了的那些事,很多时候你并不需要。

6. 那些年我踩过的选型坑

6.1 用树莓派做PWM调光的翻车经历

早期我用树莓派3B做一个LED灯带调光项目,用Python的RPi.GPIO库生成PWM。代码写起来很简单,GPIO.PWM(pin, 1000),然后start(50)就是50%占空比。但实际跑起来发现灯带有明显的闪烁,尤其是当系统负载变化的时候——比如你同时开着一个Web服务器,闪烁就更严重。用示波器看波形,占空比在45%到55%之间随机跳,频率也不稳定。

原因就是前面说的:Linux调度器随时可能打断你的Python进程,导致PWM波形不连续。后来换成用C语言直接操作树莓派的硬件PWM外设,情况好了一些,但硬件PWM只有两个通道,而且和音频输出冲突。最后解决方案是加了一颗RP2040做PWM协处理器,树莓派通过I2C发送目标亮度值,RP2040用PIO生成稳定的PWM波形。这个方案很稳,但复杂度上去了。

如果一开始就选ESP32,它自带16路LED PWM控制器,硬件生成波形,CPU完全不参与,根本不会有这个问题。这个坑让我明白:树莓派的GPIO适合做“状态控制”,不适合做“波形生成”。状态控制就是开和关、高和低,偶尔翻转一下没问题;波形生成需要精确的时序,那是单片机的活。

6.2 Arduino的内存陷阱

另一个方向的坑是低估了Arduino的内存限制。Arduino Uno只有2KB SRAM,你写代码的时候稍微不注意就用完了。我做过一个项目,用Arduino Uno接了一个LCD屏幕、一个SD卡模块、一个GPS模块,代码编译通过,但运行几分钟就死机。查了半天发现是字符串拼接的时候把SRAM耗尽了——Arduino的String类在堆上分配内存,频繁拼接会产生碎片,最终导致内存耗尽。

这个坑的教训是:在Arduino上写代码,要像在针尖上跳舞。能用char数组就别用String,能用PROGMEM把常量放到Flash里就别放在SRAM里,能静态分配就别动态分配。如果你觉得这些限制太痛苦,那说明你需要换一个内存更大的平台——ESP32有512KB SRAM,RP2040有264KB,都比Arduino Uno宽裕得多。

6.3 通信协议设计不当导致的玄学故障

前面提到的树莓派加Arduino串口通信的项目,我还遇到过一个更隐蔽的问题:Arduino在收到树莓派指令后,如果指令不完整或者校验失败,它会执行上一次的指令。这个行为在正常情况下没问题,但如果树莓派发送指令的过程中被重启打断,Arduino就会一直执行旧指令,导致温室加热器一直开着。后来我加了一个“心跳超时”机制——如果Arduino超过5秒没收到有效指令,就自动进入安全状态(关闭所有执行器)。这个机制救了好几次。

这个经验适用于任何上下位机架构:永远不要假设通信是可靠的,永远要设计失效安全(fail-safe)行为。单片机这边要能检测到通信中断并进入安全状态,上位机这边要能检测到下位机无响应并报警。这些逻辑不复杂,但很多人会忽略,直到出了事故才补上。

7. 给不同阶段的人几句实在话

如果你是完全的新手,想学硬件编程,我的建议是从ESP32或者RP2040开始。它们比Arduino Uno贵不了多少,但性能强得多,能做的事情多得多,而且同样可以用Arduino IDE开发,学习曲线几乎一样。Arduino Uno唯一的优势是“简单到极致”,但这个优势在ESP32面前已经不太成立了——你完全可以在ESP32上写和Arduino Uno一样简单的代码,需要的时候再用它的高级功能。

如果你已经有一堆Arduino的库和代码,不想重写,那继续用Arduino框架没问题,但可以考虑把硬件换成ESP32或者RP2040,代码大部分可以兼容。Arduino框架现在已经支持很多32位平台,你不需要为了用某个库而把自己锁在8位单片机上。

如果你在做商业项目或者需要长期维护的项目,选型的时候要把“可维护性”和“供应链稳定性”考虑进去。树莓派的供货在疫情期间出过问题,Arduino的某些型号也经常缺货。ESP32和RP2040的供货相对稳定,而且有多家厂商生产,不容易被单一供应商卡脖子。另外,商业项目要考虑代码的可移植性——如果你用Arduino框架写,换硬件平台的时候代码改动量会小很多;如果你直接操作某个芯片的寄存器,换平台就得重写。

最后说一句关于“学习”的事。很多人纠结“先学树莓派还是先学Arduino”,我觉得这个问题问错了。你应该问“我想做什么项目”,然后根据项目选平台。如果你想做网络摄像头、智能家居网关、媒体中心,那直接学树莓派上的Linux和Python;如果你想做机器人、无人机、灯光控制,那直接学单片机和C语言。两个方向都有前途,但混着学容易两头不靠。选定一个方向,做出三个能跑的项目,然后再看另一个方向,那时候你已经有足够的背景知识去理解两者的差异了。

我自己是两边都用的。树莓派跑Home Assistant做智能家居中枢,ESP32做各个房间的传感器节点,RP2040做工作台上的灯光和风扇控制。它们各干各的活,通过MQTT连在一起。没有哪个更好,只有哪个更适合当前这个任务。那句“一个跑系统一个跑裸机”的话,现在对我来说已经变成了“一个跑服务一个跑控制”——这才是今天选型时真正该问的问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询