一、单片机端
串口是一条城乡之间的窄道(连接单片机和外设),一次只能并排走八个人(8位),但大部分城市(单片机)里的人(ADC数据)喜欢12个人并排走,所以只能分开传高八位、第八位。此处以ESP32的函数为例,假设有四个通道(其它单片机只要换一个串口发送函数即可):
ptr_head = 0xAA; // 帧头
ptr_end = 0xBB; // 帧尾
for(i = 0; i < Sample_Num; i++)
{
ptr1_H = (Voltage1[i] >> 8) & 0xFF; // 获取高八位
ptr1_L = Voltage1[i] & 0xFF; // 获取低八位
ptr2_H = (Voltage2[i] >> 8) & 0xFF;
ptr2_L = Voltage2[i] & 0xFF;
ptr3_H = (Voltage3[i] >> 8) & 0xFF;
ptr3_L = Voltage3[i] & 0xFF;
ptr4_H = (Voltage4[i] >> 8) & 0xFF;
ptr4_L = Voltage4[i] & 0xFF;
sprintf(ptr,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",ptr_head,ptr1_H,ptr1_L,ptr2_H,ptr2_L,ptr3_H,ptr3_L,ptr4_H,ptr4_L,ptr_end);
Serial2.print(ptr);
}
二、Python端
import serial
import pandas as pd
import matplotlib.pyplot as plt
# 配置串口
com_port = 'COM11' # 根据实际情况修改
baud = '57600' # 根据实际情况修改
ser = serial.Serial(com_port, baud, timeout=1) # 打开串口
print(f"{com_port}打开成功") # 打印串口打开成功信息
Sample_Num = 512 # 采集的样本点数
count = 0
# 初始化变量
voltage1 = []
voltage2 = []
voltage3 = []
voltage4 = []
try:
while len(voltage1) < Sample_Num:
# 一次读一位
if ser.in_waiting > 0:
data = ser.read()
# 检测帧头
if data == b'\xAA':
bytes_received = ser.read(9) # 读取剩余的数据
if bytes_received[-1] == 0xBB:
# 解析数据
ptr1_H, ptr1_L, ptr2_H, ptr2_L, ptr3_H, ptr3_L, ptr4_H, ptr4_L = bytes_received[:8]
# 组装数据
voltage1.append((ptr1_H << 8) | ptr1_L)
voltage2.append((ptr2_H << 8) | ptr2_L)
voltage3.append((ptr3_H << 8) | ptr3_L)
voltage4.append((ptr4_H << 8) | ptr4_L)
count = count + 1
print(f"接收到{count}组数据")
except KeyboardInterrupt:
print("程序被用户中断")
finally:
ser.close() # 关闭串口
# 绘制图像,每个通道一个子图
fig, axs = plt.subplots(4, 1, figsize=(10, 8)) # 创建4个竖排的子图
# 绘制每个通道
axs[0].plot(voltage1, label='Channel 1', color='blue')
axs[1].plot(voltage2, label='Channel 2', color='red')
axs[2].plot(voltage3, label='Channel 3', color='green')
axs[3].plot(voltage4, label='Channel 4', color='purple')
# 设置每个子图的标签和标题
axs[0].set_title('Channel 1')
axs[1].set_title('Channel 2')
axs[2].set_title('Channel 3')
axs[3].set_title('Channel 4')
# 设置x轴的标签
for ax in axs:
ax.set_xlabel('Sample Number')
# 设置y轴的标签
axs[0].set_ylabel('Voltage')
axs[1].set_ylabel('Voltage')
axs[2].set_ylabel('Voltage')
axs[3].set_ylabel('Voltage')
# 显示图例
axs[0].legend()
axs[1].legend()
axs[2].legend()
axs[3].legend()
# 调整子图间的间距
plt.tight_layout()
plt.show()