资讯动态

Python控制Arduino与树莓派:串口通信、GPIO与实战指南

发布时间:2026/10/16 15:22:37 来源:尧图企业网站定制
1. 为什么选Python来碰硬件先把思路理清楚很多人一看到“用Python控制Arduino或者树莓派”第一反应是Arduino本身不是用C/C吗树莓派不是可以装系统吗这两件事能混在一起说吗我的理解是这句话背后其实包含了两种非常典型的玩法。第一种是用电脑上的Python通过USB串口去指挥Arduino干活。第二种是直接在树莓派上运行Python用GPIO操作硬件。两条路线的硬件平台不同但核心思路高度一致用Python这个“胶水语言”把控制逻辑、数据处理、网络交互串起来让硬件成为系统里真正执行动作的那个末端。我个人尝试过不少方案之后最大的体会是Python的优势不在速度而在开发效率和生态。控制硬件免不了要处理参数解析、日志、告警、定时任务、温度上报、跟数据库或者消息队列对接这些东西用C写会很痛苦但用Python几乎都是现成的库。与此同时硬件端对实时性要求很高的IO操作哪怕Python性能一般也足以应付几十毫秒级别的控制任务。如果你要做的是电机高速闭环、微秒级脉冲这种活那确实该改用C或者直接写成Arduino固件但如果你做的是传感器采集、上位机命令、远程开关、定时控制Python是性价比极高的选择。那到底什么时候选Arduino什么时候选树莓派我常用的判断标准很简单看这个项目是否需要跑复杂的业务逻辑以及成本、功耗、实时性分别卡在哪。Arduino是单片机便宜、启动快、外设定时准确适合做那种通电就运行、一跑几个月甚至几年的设备端。树莓派是一台小型Linux电脑能跑视觉、能连Wi-Fi、能开Web服务适合做控制中枢和计算场景很重的边缘节点但它需要更稳定的供电也会面临SD卡损坏、系统重启这类问题。选型上的误区是把树莓派当成万能板去控制一切其实很多简单任务用Arduino反而稳定得多。所以我的建议是如果你只是想快速做一个能远程开关灯、能读传感器的原型直接用树莓派加Python是最快的如果这个原型要做到低成本量产、或者放到恶劣环境里长期运行那更合理的架构往往是“树莓派作为大脑Arduino作为手臂”两者通过串口联动。这也正是为什么标题里把Arduino和树莓派放在一起讨论因为它们在实际项目里经常会同时出现。下面的内容我会先把两条路线分别讲清楚最后再聊聊把两者组合起来时要注意的稳定性和排查问题的方法。2. Python控制Arduino从串口通信到完整命令流程2.1 Arduino里先烧一个“听命令”的固件要用Python控制Arduino不能指望Arduino出厂就自带一个通用的“Python解释器”。它默认跑的是一段你自己写好的固件上位机Python和Arduino之间的关系本质上是一个主机和一个从机通过某种链路通信。主机发出命令从机执行并返回结果。最简单也最常用的物理通道就是USB转串口在Arduino上表现为串口监视器在电脑上则是一个虚拟串口。所以第一步不是在上位机写Python而是先给Arduino烧一段能够解析串口命令的固件。我用一个非常经典的例子来说明用Arduino Uno的D9引脚控制LEDD9是支持PWM的输出脚既能做数字开关也能调速亮度。固件里要做的三件事一是初始化串口二是读取串口数据三是执行对应操作并回传响应。为了让通信更可靠我习惯把每个命令都设计成换行结尾的文本行这样上位机只要按行读取即可。下面这段固件是我常用的一个模板功能很简单支持“LED:ON”“LED:OFF”以及“PWM:0~255”三组命令。// arduino_command_led.ino const int ledPin 9; void setup() { Serial.begin(115200); pinMode(ledPin, OUTPUT); digitalWrite(ledPin, LOW); Serial.println(READY); } void loop() { if (Serial.available() 0) { String cmd Serial.readStringUntil(\n); cmd.trim(); if (cmd LED:ON) { digitalWrite(ledPin, HIGH); Serial.println(OK:LED_ON); } else if (cmd LED:OFF) { digitalWrite(ledPin, LOW); Serial.println(OK:LED_OFF); } else if (cmd.startsWith(PWM:)) { int value cmd.substring(4).toInt(); value constrain(value, 0, 255); analogWrite(ledPin, value); Serial.println(OK:PWM: String(value)); } else { Serial.println(ERROR:UNKNOWN_CMD); } } }这里有三个细节要提醒。第一波特率要两端一致而且我建议直接选115200原因不是它最快而是它足够快且不容易出乱码传输命令不会有瓶颈。第二readStringUntil(\n)依赖换行符上位机必须发\n结尾的字节如果固件和上位机对换行符的理解不一致你会看到命令执行成功但响应永远读不到。第三Arduino每次重启控制芯片会短暂拉低串口的DTR引脚导致上位机串口被重置这是硬件特性不是bug。上位机连接后稍等片刻再把输入缓冲区清空就能避开这串启动噪声。2.2 上位机Python串口通信三件套上位机侧我用的库很固定就是pyserial。它本质上是把串口封装成了类似文件的对象读写、超时、缓冲区管理都有现成接口比直接用os去读写设备文件省心得多。安装只需要一句pip install pyserial没有任何系统层面的依赖Windows、Linux、macOS都能跑。连接Arduino之前先确定串口号。Windows上一般是COM3、COM4这类名字Linux上常见/dev/ttyUSB0或/dev/ttyACM0macOS上常见/dev/cu.usbmodem*。如果拿不准可以拔掉USB线再插上然后查看端口列表的变化或者用ls /dev/tty*来观察。一个完整的Python端程序长这样import serial import time ser serial.Serial( port/dev/ttyUSB0, baudrate115200, timeout0.5, write_timeout0.5 ) time.sleep(0.3) ser.reset_input_buffer() def send_command(cmd: str) - str: payload cmd \n ser.write(payload.encode(utf-8)) resp ser.readline().decode(utf-8, errorsreplace).strip() return resp print(send_command(LED:ON)) print(send_command(PWM:128)) ser.close()很多人第一次跑会卡在读不到响应、或者读到一堆莫名内容。我踩过坑之后养成了三个习惯。一是连接后必须做一次reset_input_buffer()否则Arduino启动时打印的READY以及板载的启动噪声会残留在缓冲区里。二是timeout不能设成0或者太小0代表不等待直接返回容易拿到空行设成0.5秒比较合适因为串口通信本身不是零延迟给固件留一点点处理时间。三是每次写命令都手动拼\n不要只写命令字符串否则固件里readStringUntil(\n)会一直等不到结束符。2.3 为什么用文本协议而不是二进制协议从上面的代码可以看到我采用的是文本行协议命令是LED:ON这种东西。有人可能会问直接用字节更高效比如0x01代表开灯、0x02代表关灯为什么不选那种方式我的答案是在小项目和原型阶段文本协议的可调试性远大于效率上的那点收益。想象一下这样的场景你写了一个复杂的采集程序现场拿电脑连接上去看日志如果协议是文本的随便一个串口工具就能看出当前发的命令是PWM:128答案一目了然。如果协议是二进制的你得拿协议的字节定义表去对照排查成本高很多。而且对于几十个字节的数据包文本和二进制在串口速率上的差别几乎可以忽略除非你跑到超高波特率或者每秒钟要发送几百上千条指令二进制才值得考虑。不过文本协议也有坑最常见的是数据里包含换行和特殊字符。比如你要让Arduino输出一个带空格的字符串或者让上位机传一个长度不定的浮点数直接拼文本容易把分隔符弄乱。我的折中方案是继续使用文本行但给命令加上简单帧头和校验。命令格式可以设计成$命令;数据*校验值上位机收到后先校验再执行Arduino也回复同样的格式。这样线缆干扰、偶发杂波导致的误码会被直接过滤掉而不是被当成有效命令执行。后面我会专门讲一下这个帧和校验的具体写法。2.4 一个带校验和重试的可靠通信示例如果项目只是自己调试那send_command那种简单实现就够用。但如果你要把它放到一个需要稳定运行几天的环境里我建议至少加上两样东西帧校验和超时重试。校验可以通过所有字符的ASCII码求和来粗略计算虽然不如CRC严谨但在串口短帧场景下已经能挡住绝大多数噪声引起的单字节错误。重试则是为了防止偶发超时比如Arduino正在处理某个耗时操作暂时没来得及回响应上位机如果直接放弃整个控制链就断了。这里给出一段改进过的上位机代码供参考import serial import time def make_frame(cmd: str) - bytes: checksum sum(cmd.encode(utf-8)) 0xFF return f${cmd}*{checksum:02X}\n.encode(utf-8) class ArduinoClient: def __init__(self, port: str, baudrate: int 115200): self.ser serial.Serial(port, baudrate, timeout0.5) time.sleep(0.3) self.ser.reset_input_buffer() def send(self, cmd: str, retries: int 3) - str: frame make_frame(cmd) for attempt in range(retries): try: self.ser.write(frame) resp self.ser.readline().decode(utf-8, errorsreplace).strip() if resp.startswith($) and * in resp: return resp except serial.SerialTimeoutException: pass raise RuntimeError(fcommand failed after {retries} attempts: {cmd}) client ArduinoClient(/dev/ttyUSB0) print(client.send(LED:ON)) client.ser.close()实际使用时校验和命令文本要放在同一个字符串里组成帧固件端解析时先检查*后面的两个十六进制字符是否等于前面内容的累加和相等才执行。这个思路很简单但能让整个系统抗干扰能力上一个台阶。后面如果再配合断线重连基本就能满足大多数“放在角落一直跑”的诉求了。3. 树莓派控制GPIOPython直接驱动外设实例3.1 库的选型RPi.GPIO、gpiozero、pigpio树莓派上跑的是Linux系统设备树里的GPIO是由内核管理的。Python要去操作这些GPIO一般靠三个库RPi.GPIO、gpiozero、pigpio。三个库都不是万能的选型逻辑要分场景。RPi.GPIO是老牌库API很直观GPIO.setmode(GPIO.BCM)、GPIO.setup(pin, GPIO.OUT)、GPIO.output(pin, GPIO.HIGH)。它的优点是稳定很多旧项目都在用它但缺点也很明显它默认需要root权限而且在PWM实现上依赖软件定时器如果你的系统负载很高、或者树莓派本身性能吃紧PWM会抖动。我现在基本只在写一些几十行的小工具时才用RPi.GPIO。gpiozero是我个人最推荐的通用库它的设计哲学是“把硬件变成Python对象”。LED就是LEDButton就是ButtonDistanceSensor就是DistanceSensor你甚至不需要记住某个引脚到底该用OUT还是IN直接创建对象就行。它的文档逻辑很清晰代码可读性也比RPi.GPIO高一个台阶比如你要让一个按钮去切换LEDRPi.GPIO要写回调函数、写状态判断gpiozero里几行就完成了。gpiozero内部虽然也依赖RPi.GPIO但它做了很多细节处理比如抖动、初始状态、事件回调。pigpio则适合对PWM波形、精确时序、甚至远程GPIO有要求的场景。它自带一个后台守护进程可以通过网络控制GPIO也能产生非常稳定的硬件级PWM。代价是需要额外启动一个服务逻辑也相对底层。如果你要用树莓派去控制舵机、电机驱动器或者想通过局域网把另一台设备的GPIO流程一起编排pigpio会是更专业的选择。所以我的经验法则是普通控制用gpiozero底层调试用RPi.GPIO或者查设备树特殊波形或远程控制用pigpio。折腾成本最低且代码最漂亮的永远是gpiozero。3.2 用gpiozero点亮LED并读取按钮先从一个最简单的例子入手让树莓派的GPIO17输出高电平点亮LED再用GPIO2接一个按钮按下时让LED熄灭。这个例子虽然简单但能把gpiozero的核心用法一次性讲清楚。接线时LED阳极通过一个330欧姆电阻连接到GPIO17阴极接到地注意树莓派GPIO是3.3V逻辑不能直接接5V按钮一端接GPIO2另一端接地这样利用内部下拉电阻按下时为高电平松开时为低电平。代码可以这样写from gpiozero import LED, Button from signal import pause led LED(17) button Button(2) button.when_pressed led.off button.when_released led.on pause()代码的核心是事件回调而不是轮询。when_pressed和when_released会在按钮状态变化时自动触发主程序可以一直保持到signal.pause的状态。这个写法的好处是树莓派不会为了读取按钮状态空转CPU后续你要同时控制多路IO也不需要手动写while循环去检查。实际操作中要注意几个问题。第一LED的限流电阻不能省略直接把LED跨接在3.3V和地之间电流可能超过LED额定值时间久了要么LED烧掉要么GPIO保护电路先触发。第二按钮接法要和代码里的引脚设置对应如果按钮接高电平、另一端接GPIO那代码里就要用pull_upTrue否则会读到反逻辑。第三如果按钮的金属引脚有接触不良或者线太长可能出现抖动触发好几次事件解决办法是换用Button(2, bounce_time0.1)让gpiozero自动做软件去抖动。你可能注意到我用了button.when_pressed led.off传递的是函数对象而不是调用结果。这是Python的一个容易踩坑的点如果写成led.off()就会在赋值时立刻执行事件发生时反而什么都不做。类似的错误在RPi.GPIO的回调里也经常出现值得记住。3.3 读取温湿度传感器与超声波模块树莓派直接读传感器是很多业余项目的起点但传感器种类不同接入方式差别很大。温湿度传感器比较适合用DHT11或者DHT22这类数字式单总线传感器。gpiozero已经内置了DHT11和DHT22的驱动使用上非常简单from gpiozero import DHT11 import time sensor DHT11(4) for _ in range(5): temp sensor.temperature humidity sensor.humidity if temp is not None: print(ftemp{temp:.1f}C humidity{humidity:.1f}%) time.sleep(2)注意DHT传感器是慢速传感器两次读取之间必须间隔1秒以上否则它可能不响应。而且它经常在首次上电后读不到有效数据代码里必须做好None值判断。DHT11读到的是整数温度DHT22则是浮点精度更高选型时别只看价格要看你对精度的需求。超声波距离传感器HC-SR04则是另一个完全不同的玩法它靠引脚电平的时序来测距gpiozero也封装好了DistanceSensor代码很短from gpiozero import DistanceSensor sensor DistanceSensor(echo24, trigger23, max_distance2) while True: distance_cm sensor.distance * 100 print(f{distance_cm:.1f} cm) sensor.wait_for_high()接线方面HC-SR04有VCC、Trig、Echo、GND四个脚Echo是5V电平直连树莓派的3.3V GPIO会超压。常规做法是加一个分压电阻把Echo信号降到3.3V以下再进入GPIO。gpiozero库不会替你做电平转换这种接线问题必须靠硬件上解决。不少人在这个模块上烧过GPIO口就是因为图省事直接接了进去。实际体验下来树莓派读取传感器最大的优势是方便但最大的问题也是“什么都得自己负责”。跑Python的进程如果因为系统负载卡顿传感器的读取时序就会抖动。超声波模块对时序比较敏感我建议在测量循环里记录时间戳而不是直接把脉冲触发和回波检测当作绝对精确的操作。3.4 从循环控制升级到Web控制树莓派跑Python还有一个很大的优势是可以很容易地做出Web控制界面。比如你想在手机上开关某个设备或者看传感器数据完全不用先学Web前端直接用Flask写几个路由就行。下面是最小可用的示例打开浏览器访问http://树莓派IP:5000/on就能开灯访问/off就能关灯from flask import Flask, jsonify from gpiozero import LED app Flask(__name__) led LED(17) app.route(/on) def on(): led.on() return jsonify(statuson) app.route(/off) def off(): led.off() return jsonify(statusoff) if __name__ __main__: app.run(host0.0.0.0, port5000)这个例子里藏着三个容易出问题的地方。第一app.run(host0.0.0.0)是必要的不写的话Flask只听本地回环地址手机和电脑都访问不到。第二Flask自带的服务器性能有限如果你需要频繁请求最好后面加一层反向代理或者改用gunicorn这类更专业的服务器。第三Web服务在树莓派上的可靠性要求比本地脚本高得多如果进程异常退出服务就断了。所以真要长期开着我一般会把它放进systemd服务里配置一个restart策略下面会讲。如果你要把控制权限暴露到公网那一定要加认证或者至少限制成局域网访问。我只是演示最简单的开关实际项目里不要裸奔在公网上否则一个普通家用路由器上的设备就可能变成别人随便开关的对象。4. 刚上手最容易踩的坑问题与排查实录4.1 串口打不开、权限不够、设备被占用Arduino场景最常见的问题是Python抛serial.SerialException提示Permission denied或者Device or resource busy。Permission denied多半是当前用户不在串口设备所属的用户组里。Linux下串口设备典型属组是dialout用ls -l /dev/ttyUSB0看一眼就明白解决办法是sudo usermod -aG dialout 你的用户名然后重新登录才能生效。Device or resource busy则是设备被另一个程序占用了。这种情况往往是你开了Arduino IDE的串口监视器或者上一次跑Python脚本的进程没退出就已经占用了打开的设备。排查时用lsof /dev/ttyUSB0看谁占用或者用fuser -k /dev/ttyUSB0强制释放。注意强制释放前要确保没有正在写入的重要数据。Windows上则经常遇到“COM端口被占用”而且Arduino IDE和Python脚本不能同时打开同一个COM口。还有一个Windows特有的坑是拔掉USB线再插上之后端口号可能变了写代码时尽量用动态检测端口或者至少不要把端口号写死在配置里。4.2 乱码、粘包以及Arduino重启带来的幽灵数据串口乱码的来源九成是波特率不匹配。你固件里写的是115200上位机却开成9600收到的必然是乱码。这个最容易排查固定好波特率两端保持一致即可。但有一种隐蔽情况Arduino在USB断开重连或者上位机刚打开串口时会输出一段启动阶段的调试信息或者直接输出READY这些数据和后面的正式响应混在一起会让你的readline()读到不完整的行。我惯用的对策是上位机每次连上后等300毫秒左右然后调用reset_input_buffer()把历史数据清空。如果还是不干净就在协议层面加一个起始标识上位机只接收以$或RESP:开头的行其他内容一律丢弃。另一个常见问题是“粘包”一条命令执行完响应还没读到下一条命令又发出去了结果上位机把两条响应拼接着读出来。解决方法不是让速度变慢而是每次发命令后必须读完一行响应再发下一条也就是做同步的请求-应答而不是纯粹地连续发送。4.3 GPIO引脚编号搞混、电平和抖动问题换到树莓派这边最容易翻车的不是代码逻辑而是物理接线和引脚编号的对不上。树莓派的GPIO有两套常见编号物理引脚编号BOARD和Broadcom芯片编号BCM。同一个物理引脚在BOARD模式下可能对应1号在BCM模式却对应17号。gpiozero默认使用BCM编号所以你在代码里写LED(17)就得确保线确实接在BCM17对应的物理引脚上查引脚图时眼睛要看清楚。电平问题则是另一个大坑。树莓派的GPIO是3.3V逻辑Arduino的逻辑电平是5V。如果你把Arduino的输出直接接到树莓派的GPIO或者把某块5V传感器模块的输出直接接到树莓派轻则GPIO读不到正确状态重则真的会烧掉树莓派的引脚或整个芯片这个损失比代码报错麻烦得多。电平转换器或者分压电路是必须的不要觉得自己只是试验一次就不会出问题。抖动问题则与按钮、机械开关有关。一个按钮按下去物理接触会有几十毫秒的弹跳如果代码直接用原始电平去触发事件一次按下可能会被当成好几次“按下”。gpiozero的Button默认自带一定程度的软件去抖但你可以显式指定bounce_time。RPi.GPIO则需要自己在回调里判断事件触发的时间间隔代码会更啰嗦。4.4 树莓派长期运行的经典故障树莓派长期跑Python控制项目最典型的故障是进程莫名退出其次是SD卡损坏再就是系统时间漂移导致定时任务错乱。进程莫名退出的原因很多可能是内存不足被内核杀掉可能是某个库的异常没被捕获也可能是GPIO引脚被其他进程重置。我常用的方法是脚本里不要写一整套“假设一切正常”的逻辑把所有能想到的异常都捕获写了日志然后交给systemd去重启。SD卡损坏则跟频繁写入有关如果脚本每秒往数据库写一次又没有启用日志压缩或定时清理几个月的运行足够让一块普通SD卡出现坏块。对策是别把树莓派当普通电脑用减少不必要写入把数据写到外部存储或者内存文件系统上同时备份好镜像。树莓派的系统时间在无网络环境下会漂移如果你的定时任务依赖cron它会在错误的时间触发。要么接一个额外的RTC模块要么保证它能随时联网校对时间。树莓派默认用systemd-timesyncd同步断网时间久了问题就会冒出来这属于那种“不跑长周期任务时根本感觉不到”的隐藏问题。5. 从样例工程到长期稳定运行我常用的几个技巧5.1 给通信加上简单校验和心跳先说我个人在Arduino和树莓派联动时最看重的一层通信健壮性。文本协议本身并不抗干扰如果线缆比较长、环境有电磁干扰偶尔会出现一个字节被改写的情况。一个简单的办法是给每个命令帧算一个累加和跟在帧尾发送接收方重新计算一下不一致就直接丢弃。心跳机制也很重要。上位机每隔一段时间发送PING从机收到后回PONG。上位机如果连续几次收不到PONG说明链路断了此时可以选择重连、重启串口甚至向看门狗发信号去复位Arduino。对Arduino这种单片机来说长时间收不到命令而进入未知状态往往比收到错误命令更危险因为设备可能正停留在某个意外的输出状态。心跳的周期我一般设在2到10秒之间。太频繁会增加设备负担太长又会让故障排查变得迟钝。具体选多少取决于你接受多长的“沉默时间”。5.2 把Python服务放进systemd崩溃自动重启树莓派上跑Python控制程序最忌讳的是直接在终端里python3 xxx.py跑完就走。终端一关进程就没了终端不退系统重启后也不会自动拉起。我建议简单起见把控制程序写成systemd服务指定好用户、启动命令和重启策略。一个典型的服务文件长这样[Unit] Descriptionpython IO control service Afternetwork.target [Service] Userpi WorkingDirectory/home/pi/io ExecStart/usr/bin/python3 /home/pi/io/main.py Restartalways RestartSec5 [Install] WantedBymulti-user.target把文件放到/etc/systemd/system/io-service.service然后systemctl daemon-reload、systemctl enable --now io-service服务就能开机自启并在崩溃后自动重启了。我还习惯在Python程序里把所有异常都捕获起来写日志并配合Restartalways这样即使进程崩溃也不需要每次跑到树莓派前面手动拉起。实践中有个细节如果你的程序里有GPIO初始化重启间隔不要太短否则会反复进行插拔。RestartSec5是我觉得比较稳妥的间隔既能快速恢复又不会让系统在故障状态下疯狂重启。5.3 日志、状态记录与断电恢复长期运行的项目离不开日志。别小看这个环节真正出问题时日志往往是唯一的排查线索。最简单的做法是在Python的日志中带时间戳、模块名、消息级别并定期轮转避免单个文件无限膨胀。我一般用标准库logging配合RotatingFileHandler当文件超过1MB就自动分割保留最近的几份。断电恢复是另一个容易被忽视的问题。Arduino断电重上电会重新运行固件树莓派断电重上电则会经历完整的Linux启动流程。如果你的树莓派系统里开着某个GPIO输出断电后再上电GPIO默认回到输入或者低电平状态这通常是安全的。但如果你用继电器控制的是外部电路你需要在程序初始化时明确设置所有输出引脚的安全状态比如继电器断电时处于断开状态然后再去等待上游命令。这个初始化逻辑一定要放在程序最前面因为系统启动到Python程序开始运行之间GPIO状态是不受你控制的。还有一个实用技巧在控制程序里保存一个“最近一次成功状态”的文件程序启动时读取它尽量恢复到断电前的状态。对大多数设备控制项目来说这种“先恢复再说”的策略比一上来就强制清零要友好得多但前提是你得清楚设备在上电时的物理安全要求。5.4 Python控制硬件的下一步扩展当你已经能把Python、Arduino、树莓派串起来以后我觉得最值得扩展的是两件事数据上云和多设备协作。数据上云可以简单到把传感器读数通过HTTP POST到自己的后端也可以复杂到用MQTT协议订阅一个主题然后让多个树莓派、多个Arduino都通过同一个消息通道互相协作。MQTT的发布-订阅模型非常契合“多设备、低带宽、不可靠网络”的场景而且Python端有现成的客户端库Arduino端也有很多方案可以直接用。只要你已经把串口通信或者GPIO控制跑通再加一个MQTT通道其实就是把上一层的命令来源从串口或者本机脚本换成网络消息。多设备协作方面我比较推荐“主从架构”树莓派作为主控负责任务调度、日志、Web服务Arduino作为执行器负责精确时序、继电器、电机这类底层操作。主从之间用串口或MQTT连接既保留了Arduino的稳定性和实时性又利用了树莓派更强的计算能力。这个架构看起来多了一层转发但实际调试时的收益非常大出问题时可以分别看主控日志和执行器响应很快定位到是哪一层出问题。我个人的体会是用Python控制Arduino或树莓派最值得投入精力的不是把某一个Demo跑通而是把通信链路和异常恢复设计扎实。很多项目跑通Demo只需要一个下午但真正能长期稳定运行靠的是心跳、日志、重启策略这些“丑功夫”。如果你现在刚接触这块我的建议很直接先找一块Arduino和一块树莓派从点亮一个LED开始把串口通信的请求-应答流程跑顺再去碰传感器和网络。别一上来就想着把所有功能堆到一起分层跑通了再组合会省掉大量的排错时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑