1. 那句流传十年的“跑系统与跑裸机”到底在说什么“树莓派跑系统Arduino跑裸机”——这句话在创客圈子里流传了差不多十年几乎每个刚接触硬件的新人都会在论坛、视频评论区或者某篇入门文章里看到它。它的逻辑听起来很干净树莓派是一台完整的微型计算机上面跑着Linux有文件系统、有进程调度、有网络协议栈Arduino是一颗单片机你写的代码直接编译成机器指令烧进去之后从头到尾就你一个程序在跑没有操作系统在中间插一脚。于是结论就来了要复杂计算、要联网、要接屏幕选树莓派要实时控制、要低功耗、要稳定响应选Arduino。这个二分法在2015年前后基本是对的。那时候树莓派最新型号是Pi 2主频900MHz单核性能勉强够用GPIO的实时性一塌糊涂——你在Python里写个GPIO.output()从调用到引脚真正翻转中间可能隔了几十微秒甚至几百微秒因为Linux调度器随时可能把你的进程踢出去干别的事。而Arduino Uno用的是ATmega328P16MHz8位资源少得可怜但正因为它简单一个数字写操作从代码到引脚翻转只需要几百纳秒确定性极强。所以那时候的选型逻辑很清晰谁干实时谁用Arduino谁干逻辑谁用树莓派。但问题是这句话被当成了永恒真理一直传到今天。而今天的硬件早就不是那个样子了。树莓派5用的是四核Cortex-A76主频2.4GHz内存最高8GBPCIe接口都给你了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-M0133MHz带可编程IOPIO价格只要几块钱。所以“跑裸机”这件事跟“用不用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中档控制、带DACESP32-S3双核Cortex-M7240MHz硬实时中40mAWiFi开物联网节点、带AI加速RP2040双核Cortex-M0133MHz硬实时中低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 SRAMRP2040有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连在一起。没有哪个更好只有哪个更适合当前这个任务。那句“一个跑系统一个跑裸机”的话现在对我来说已经变成了“一个跑服务一个跑控制”——这才是今天选型时真正该问的问题。
阅读完成 · 觉得有帮助?