一、单片机端

        串口是一条城乡之间的窄道(连接单片机和外设),一次只能并排走八个人(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()
05-02 17:50