一、主从蓝牙配置

1.进入AT模式

蓝牙接USB-TTL模块:蓝牙的RXD接USB-TTL的TXD, 蓝牙的TXD接USB-TTL的RXD, GND互相接好,但是先不把USB-TTL的5V接蓝牙的VCC。

打开串口调试助手,选择波特率为38400,按住蓝牙模块上的按键的同时,把USB-TTL的5V接蓝牙的VCC,此时蓝牙的指示灯闪烁频率会变慢,串口调试助手发送AT+换行,如果回复了OK,则成功进入AT模式。

单片机基础1:串口与蓝牙和Python相连_串口

2.配置参数

(1)改名字

查名字:AT+NAME? 换行

改名字:AT+NAME=ESP32_sEMG_Send 换行

单片机基础1:串口与蓝牙和Python相连_单片机_02

确认是否改成功了:AT+NAME?换行   或者最后蓝牙退出AT模式后,用手机或电脑搜索看是否能搜到该名字的蓝牙(只能验证从模式的蓝牙,主模式的搜不到)

单片机基础1:串口与蓝牙和Python相连_单片机_03

(2)改角色

查角色:AT+ROLE?换行

从模式:0(信号发送端)

主模式:1(信号接收端)

单片机基础1:串口与蓝牙和Python相连_单片机_04

单片机基础1:串口与蓝牙和Python相连_串口_05

(3)波特率设为一致

查波特率:AT+UART?换行

改波特率:AT+UART=115200,0,0换行   (后面两个0代表停止位1位,无校验位)

单片机基础1:串口与蓝牙和Python相连_单片机_06

(4)配对码设为一致

查配对码:AT+PSWD?换行

改配对码:AT+PSWD="1024"

单片机基础1:串口与蓝牙和Python相连_单片机_07

(5)相互连接地址

先查询地址:AT+ADDR?

得到的结果是:

单片机基础1:串口与蓝牙和Python相连_单片机_08

得到:“+ADDR:98D3:71:F6F548”

另一块蓝牙进AT后,配置AT+BIND=98D3,71,F6F548  把":"改为“,”

注意:两块蓝牙必须互相配置地址才行

3.验证

同时打开两个串口调试助手,互相发一下消息,验证一下它俩能够接收到彼此就行

 

单片机基础1:串口与蓝牙和Python相连_单片机_09

单片机基础1:串口与蓝牙和Python相连_串口_10

二、与Python数据传输

 串口是一条城乡之间的窄道(连接单片机和外设),一次只能并排走八个人(8位),但大部分城市(单片机)里的人(ADC数据)喜欢12个人并排走,所以只能分开传高八位、第八位。此处以ESP32的函数为例,假设有四个通道(其它单片机只要换一个串口发送函数即可)

1.单片机端

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);
     }

2.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()

可以再将其优化一下成为一个上位机:

单片机基础1:串口与蓝牙和Python相连_单片机_11