从Arduino数据读取到树莓派:手把手教你用PySerial搞定串口通信(附完整代码示例)

发布时间:2026/6/21 16:37:44

从Arduino数据读取到树莓派:手把手教你用PySerial搞定串口通信(附完整代码示例) 从Arduino数据读取到树莓派手把手教你用PySerial搞定串口通信附完整代码示例1. 串口通信硬件与软件的桥梁想象一下这样的场景你的Arduino正在实时采集温湿度数据而你需要将这些数据传输到树莓派上进行进一步处理或可视化。这就是串口通信的典型应用场景——在硬件设备与计算机之间建立可靠的数据通道。串口通信Serial Communication是一种古老但依然广泛使用的数据传输方式。它通过发送和接收单个比特流来实现设备间的数据交换。在现代创客项目中串口常用于Arduino与PC之间的调试信息传输传感器数据采集系统嵌入式设备与上位机的通信工业控制设备的监控Python的PySerial模块为我们提供了一套简洁而强大的API让我们能够轻松实现这些功能。与直接操作底层串口相比PySerial抽象了不同操作系统间的差异让开发者可以专注于业务逻辑而非兼容性问题。2. 环境准备与PySerial安装2.1 安装PySerialPySerial的安装非常简单无论你使用什么操作系统基本都可以通过pip一键安装pip install pyserial对于Linux用户如果遇到权限问题可以尝试sudo pip install pyserial或者使用虚拟环境python -m venv serial_env source serial_env/bin/activate # Linux/Mac # 或 serial_env\Scripts\activate # Windows pip install pyserial提示建议使用Python 3.6及以上版本以获得最佳的兼容性和性能。2.2 验证安装安装完成后可以通过以下命令验证PySerial是否安装成功python -c import serial; print(serial.__version__)如果看到版本号输出如3.5说明安装成功。3. 硬件连接与串口识别3.1 硬件准备在开始编码前我们需要确保硬件连接正确。典型的Arduino与PC连接方式如下使用USB线连接Arduino和计算机Arduino会自动安装驱动程序首次连接可能需要等待确认Arduino板上的电源指示灯亮起3.2 查找串口号连接设备后我们需要确定系统分配给它的串口号。不同操作系统的查找方法略有不同Windows系统打开设备管理器展开端口(COM和LPT)项查找类似USB Serial Port (COM3)的条目Linux/Mac系统在终端运行ls /dev/tty*查找类似/dev/ttyUSB0或/dev/ttyACM0的设备。注意每次重新插拔USB设备串口号可能会变化特别是Windows上的COM号。3.3 常用串口参数配置串口时需要了解几个关键参数参数典型值说明波特率9600, 115200数据传输速率bps数据位8每个字节的数据位数奇偶校验None错误检测方式停止位1数据包结束标志超时1读取操作的等待时间秒Arduino默认通常使用9600波特率但在高速传输场景下可以提高到115200。4. PySerial基础通信实践4.1 最简单的串口通信让我们从一个最基本的例子开始 - 发送和接收单个字符import serial # 配置串口参数 ser serial.Serial( portCOM3, # 替换为你的串口号 baudrate9600, # 波特率 timeout1 # 超时时间(秒) ) # 发送数据 ser.write(bHello Arduino!) # 读取数据 response ser.readline() print(Received:, response.decode(utf-8)) # 关闭串口 ser.close()对应的Arduino代码void setup() { Serial.begin(9600); } void loop() { if (Serial.available()) { String message Serial.readStringUntil(\n); Serial.print(Arduino received: ); Serial.println(message); } }4.2 实时数据采集示例更实用的场景是实时采集传感器数据。假设我们有一个连接了DHT11温湿度传感器的Arduinoimport serial import time ser serial.Serial(COM3, 9600, timeout1) try: while True: # 请求数据 ser.write(bGET_DATA\n) # 读取响应 data ser.readline().decode(utf-8).strip() if data: temperature, humidity map(float, data.split(,)) print(f温度: {temperature}°C, 湿度: {humidity}%) time.sleep(2) # 每2秒采集一次 except KeyboardInterrupt: print(程序终止) finally: ser.close()对应的Arduino代码#include DHT.h #define DHTPIN 2 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); dht.begin(); } void loop() { if (Serial.available()) { String cmd Serial.readStringUntil(\n); if (cmd GET_DATA) { float h dht.readHumidity(); float t dht.readTemperature(); if (!isnan(h) !isnan(t)) { Serial.print(t); Serial.print(,); Serial.println(h); } } } }5. 常见问题与高级技巧5.1 解决乱码问题串口通信中最常见的问题就是接收到的数据出现乱码。这通常由以下原因导致波特率不匹配确保两端使用相同的波特率编码问题明确指定编码方式如UTF-8数据格式不一致约定好数据结束标志如换行符调试技巧先发送简单的ASCII字符测试使用十六进制模式查看原始数据print(Raw data:, ser.read(10).hex())5.2 提高通信可靠性对于关键应用可以增加以下机制校验和在数据包中加入校验字段重试机制对重要数据实现自动重发心跳包定期检测连接状态改进后的数据格式示例$DATA,25.5,60.3*4F\n其中*4F是校验和。5.3 多线程串口通信对于需要同时处理用户输入和串口数据的应用可以使用多线程import serial import threading class SerialManager: def __init__(self, port): self.ser serial.Serial(port, 9600, timeout1) self.running True def read_serial(self): while self.running: if self.ser.in_waiting: data self.ser.readline().decode(utf-8) print(Received:, data.strip()) def start(self): self.thread threading.Thread(targetself.read_serial) self.thread.start() def send(self, message): self.ser.write(message.encode(utf-8)) def stop(self): self.running False self.thread.join() self.ser.close() # 使用示例 manager SerialManager(COM3) manager.start() try: while True: cmd input(Enter command: ) manager.send(cmd \n) except KeyboardInterrupt: manager.stop()6. 树莓派上的串口应用将Arduino数据传送到树莓派后我们可以构建更强大的应用。例如创建一个简单的Web服务来展示传感器数据from flask import Flask, render_template import serial import threading app Flask(__name__) current_data {temperature: 0, humidity: 0} def read_sensor(): ser serial.Serial(/dev/ttyACM0, 9600, timeout1) while True: ser.write(bGET_DATA\n) data ser.readline().decode(utf-8).strip() if data: t, h map(float, data.split(,)) current_data.update({temperature: t, humidity: h}) app.route(/) def index(): return render_template(sensor.html, **current_data) if __name__ __main__: thread threading.Thread(targetread_sensor) thread.daemon True thread.start() app.run(host0.0.0.0, port8080)对应的HTML模板templates/sensor.html!DOCTYPE html html head title环境监测/title meta http-equivrefresh content5 /head body h1当前环境数据/h1 p温度: {{ temperature }}°C/p p湿度: {{ humidity }}%/p /body /html这个简单的应用每5秒自动刷新页面展示最新的传感器数据。你可以进一步扩展它比如添加数据记录、图表展示或报警功能。

相关新闻