蓝牙无线传数据?Quecpython 平台 SPP 模式玩法大揭秘!
嘿,各位蓝牙玩家、开发大神们~ 今天来聊个超实用的技能:在 Quecpython 平台上用 SPP 模式玩转蓝牙!不管你是想做无线串口通信,还是搞设备间数据互传,这篇指南都能让你秒变 “蓝牙达人”,小白也能轻松上手~
先搞懂:蓝牙 SPP 到底是个啥?
其实呀,SPP(Serial Port Profile,串口协议)就是经典蓝牙(Bluetooth BR/EDR)里的 “无线串口”!它能让两个设备像接了根无形的数据线一样,通过蓝牙模拟传统的 RS232 串口通信。简单说:有线串口能做的,它用蓝牙无线也能做,是不是很神奇?
SPP 能玩出哪些花样?
这可太多了!日常开发和生活中到处都能见到它的身影:
👉 蓝牙串口模块:比如咱们熟悉的 HC-05、HC-06、JDY-08,插上单片机就能用 SPP 无线传数据,告别杂乱的电线~
👉 车载诊断:汽车 OBD2 读码器就是靠 SPP 和手机连接,实时读取车速、油耗这些数据,修车师傅的好帮手!
👉 蓝牙打印机:超市小票、快递标签打印机,用 SPP 无线接收打印指令,摆在哪里都方便~
👉 工业设备:工厂里的 PLC、单片机,不用布线就能通过 SPP 传数据,维护起来超省心!
👉 日常小场景:比如蓝牙耳机(音频数据传输)、设备间传图片 / 文件,甚至自定义设备界面的 logo,都能靠它实现~
而且哦,SPP 支持最高 3M 速率传输,速度杠杠的!
哪些模组能玩 SPP?
Quecpython 平台下,这些 4G 模组都支持蓝牙 SPP,手里有的小伙伴可以直接开工:
EC200U、EC600U、EG912U、EG915ULA_AB、EG915UEU_AB
(没有的也别慌,先马住攻略,以后说不定就用上啦~)
划重点:Quecpython 开发 SPP 有多简单?
最爽的是,在 Quecpython 平台上玩蓝牙 SPP,根本不用啃复杂的底层协议栈!就像搭积木一样,调用几个简单的接口,分分钟搞定连接、传数据~ 是不是超省心?
手把手教你:蓝牙 SPP 初始化 + 通信全流程
下面咱们一步步来,从初始化到收发数据,跟着做就能搞定~
第一步:准备工作 —— 初始化蓝牙
首先得让蓝牙 “醒过来”,还得给它配个 “消息通知员”(回调函数),蓝牙有啥动静(比如连上了、收到数据了)都会通过它告诉你~
核心接口:bt.init(user_cb)
● 作用:初始化蓝牙,注册回调函数
● 回调函数(user_cb):蓝牙事件的 “消息中心”,比如 “蓝牙启动了”“收到数据了” 都会在这里通知你~
第二步:认识蓝牙的 “小动作”——
事件 ID
蓝牙工作时会有各种 “状态通知”,咱们得知道这些通知代表啥,比如:
● BT_START_STATUS_IND(0):蓝牙启动了
● BT_SPP_CONNECT_IND(61):SPP 连接成功啦
● BT_SPP_RECV_DATA_IND(14):收到数据啦
● BT_SPP_DISCONNECT_IND(62):连接断开了
这些就像蓝牙的 “表情”,看懂了就能知道它在干嘛~
第三步:代码示例 —— 从启动到传数据全流程
咱们直接上代码,每一步都给你标清楚,小白也能看懂~
# 导入蓝牙模块,用于蓝牙相关操作
import bt
# 导入时间模块,用于延时等时间操作
import utime
# 导入多线程模块,用于创建事件处理线程
import _thread
# 从队列模块导入Queue,用于存储蓝牙事件消息
from queue import Queue
# 定义蓝牙设备名称,其他设备可通过该名称搜索到本设备
BT_NAME = 'QuecPython-SPP'
# 定义蓝牙事件字典,键为事件描述,值为事件ID,用于识别不同蓝牙事件
BT_EVENT = {
'BT_START_STATUS_IND': 0, # 蓝牙/ble启动状态通知
'BT_STOP_STATUS_IND': 1, # 蓝牙/ble停止状态通知
'BT_SPP_INQUIRY_IND': 6, # 蓝牙SPP查询到设备通知
'BT_SPP_INQUIRY_END_IND': 7, # 蓝牙SPP查询结束通知
'BT_SPP_RECV_DATA_IND': 14, # 蓝牙SPP接收数据通知
'BT_SPP_CONNECT_IND': 61, # 蓝牙SPP连接状态通知
'BT_SPP_DISCONNECT_IND': 62, # 蓝牙SPP断开连接通知
}
# 目标设备信息字典,存储要连接的设备名称和蓝牙地址
DST_DEVICE_INFO = {
'dev_name':'iQOO Neo7 SE',# 要连接的目标设备蓝牙名称
'bt_addr': None # 目标设备蓝牙地址,初始为None,搜索到后赋值
}
# 蓝牙运行状态标记:0-未运行,1-运行中
BT_IS_RUN = 0
# 创建消息队列,最大容量30,用于缓存蓝牙回调函数传来的事件消息
msg_queue = Queue(30)
# 蓝牙回调函数:当蓝牙有事件发生时,系统会调用该函数
# 参数args:事件相关参数,包含事件ID、状态等信息
def bt_callback(args):
global msg_queue
# 将事件参数放入消息队列,供事件处理线程处理
msg_queue.put(args)
# 打开/usr/test.txt文件,模式为a+(追加+可读),用于存储接收的蓝牙数据
f=open('usr/test.txt','a+')
# 蓝牙事件处理线程函数:循环从消息队列获取事件并处理
def bt_event_proc_task():
# 声明使用全局变量
global msg_queue
global BT_IS_RUN
global DST_DEVICE_INFO
while True:
print('wait msg...')
# 从消息队列获取消息,若无消息则阻塞等待
msg = msg_queue.get()
# 解析事件ID(第一个参数为事件ID)
event_id = msg[0]
# 解析状态(第二个参数为状态:0-成功,非0-失败)
status = msg[1]
# 处理蓝牙启动状态通知事件
if event_id == BT_EVENT['BT_START_STATUS_IND']:
print('event: BT_START_STATUS_IND')
# 若启动成功
if status == 0:
print('BT start successfully.')
# 更新蓝牙运行状态为运行中
BT_IS_RUN = 1
print('Set BT name to {}'.format(BT_NAME))
# 设置蓝牙设备名称
retval = bt.setLocalName(0, BT_NAME)
if retval != -1:
print('BT name set successfully.')
else:
print('BT name set failed.')
# 若设置名称失败,停止蓝牙
bt.stop()
continue
# 设置蓝牙可见模式(3表示可见)
retval = bt.setVisibleMode(3)
if retval == 0:
# 获取当前可见模式并验证
mode = bt.getVisibleMode()
if mode == 3:
print('BT visible mode set successfully.')
else:
print('BT visible mode set failed.')
bt.stop()
continue
else:
print('BT visible mode set failed.')
bt.stop()
continue
# 以下为查询设备相关代码(默认注释,取消注释可启用)
# retval = bt.startInquiry(15)
# if retval != 0:
# print('Inquiry error.')
# bt.stop()
# continue
# 若启动失败
else:
print('BT start failed.')
bt.stop()
continue
# 处理蓝牙停止状态通知事件
elif event_id == BT_EVENT['BT_STOP_STATUS_IND']:
print('event: BT_STOP_STATUS_IND')
if status == 0:
# 更新蓝牙运行状态为未运行
BT_IS_RUN = 0
print('BT stop successfully.')
else:
print('BT stop failed.')
# 以下为释放SPP和蓝牙资源的代码(默认注释)
# retval = bt.sppRelease()
# if retval == 0:
# print('SPP release successfully.')
# else:
# print('SPP release failed.')
# retval = bt.release()
# if retval == 0:
# print('BT release successfully.')
# else:
# print('BT release failed.')
# break
# 延时5秒后重新启动蓝牙
utime.sleep(5)
bt.start()
bt.setVisibleMode(3)
# 处理SPP查询到设备通知事件
elif event_id == BT_EVENT['BT_SPP_INQUIRY_IND']:
print('event: BT_SPP_INQUIRY_IND')
if status == 0:
# 解析信号强度(第三个参数为rssi)
rssi = msg[2]
# 解析设备名称(第五个参数为设备名称)
name = msg[4]
# 解析设备地址(第六个参数为设备地址)
addr = msg[5]
# 格式化MAC地址(转换为xx:xx:xx:xx:xx:xx格式)
mac = '{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}'.format(addr[5], addr[4], addr[3], addr[2], addr[1], addr[0])
print('name: {}, addr: {}, rssi: {}'.format(name, mac, rssi))
# 若查询到目标设备
if name == DST_DEVICE_INFO['dev_name']:
print('The target device is found, device name {}'.format(name))
# 记录目标设备地址
DST_DEVICE_INFO['bt_addr'] = addr
# 取消查询(已找到目标设备)
retval = bt.cancelInquiry()
if retval != 0:
print('cancel inquiry failed.')
continue
else:
print('BT inquiry failed.')
bt.stop()
continue
# 处理SPP接收数据通知事件
elif event_id == BT_EVENT['BT_SPP_RECV_DATA_IND']:
# print('event: BT_SPP_RECV_DATA_IND')
# 若接收数据成功
if status == 0:
# 解析接收的数据(第四个参数为数据)
data = msg[3]
# 将数据写入文件
f.write(data)
print('recvbytes data: {}'.format(data))
# 以下为发送响应数据的代码(默认注释,取消注释可启用)
# send_data = 'I have received the data you sent.'
# print('send data: {}'.format(send_data))
# retval = bt.sppSend(send_data)
if retval != 0:
print('send data faied.')
else:
print('Recv data failed.')
bt.stop()
continue
# 处理SPP连接通知事件
elif event_id == BT_EVENT['BT_SPP_CONNECT_IND']:
print('event: BT_SPP_CONNECT_IND')
# 若连接成功
if status == 0:
# 解析连接状态(第三个参数为连接状态)
conn_sta = msg[2]
# 解析设备地址(第四个参数为设备地址)
addr = msg[3]
# 格式化MAC地址
mac = '{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}'.format(addr[5], addr[4], addr[3], addr[2], addr[1], addr[0])
print('SPP connect successful, conn_sta = {}, addr {}'.format(conn_sta, mac))
else:
print('Connect failed.')
bt.stop()
continue
# 处理SPP断开连接通知事件
elif event_id == BT_EVENT['BT_SPP_DISCONNECT_IND']:
print('event: BT_SPP_DISCONNECT_IND')
# 解析连接状态(第三个参数为连接状态)
conn_sta = msg[2]
# 解析设备地址(第四个参数为设备地址)
addr = msg[3]
# 格式化MAC地址
mac = '{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}'.format(addr[5], addr[4], addr[3], addr[2], addr[1], addr[0])
print('SPP disconnect successful, conn_sta = {}, addr {}'.format(conn_sta, mac))
# 关闭文件
f.close()
bt.stop()
continue
# 主函数:初始化并启动蓝牙SPP
def main():
global BT_IS_RUN
# 启动蓝牙事件处理线程
_thread.start_new_thread(bt_event_proc_task, ())
# 初始化蓝牙(注册回调函数)
retval = bt.init(bt_callback)
if retval == 0:
print('BT init successful.')
else:
print('BT init failed.')
return -1
# 初始化SPP
retval = bt.sppInit()
if retval == 0:
print('SPP init successful.')
else:
print('SPP init failed.')
return -1
# 启动蓝牙
retval = bt.start()
if retval == 0:
print('BT start successful.')
else:
print('BT start failed.')
# 若启动失败,释放SPP资源
retval = bt.sppRelease()
if retval == 0:
print('SPP release successful.')
else:
print('SPP release failed.')
return -1
# 循环监测蓝牙运行状态
count = 0
while True:
utime.sleep(1)
count += 1
# 获取当前时间
cur_time = utime.localtime()
# 格式化时间戳(时:分:秒)
timestamp = "{:02d}:{:02d}:{:02d}".format(cur_time[3], cur_time[4], cur_time[5])
# 每5秒打印一次运行状态
if count % 5 == 0:
if BT_IS_RUN == 1:
print('[{}] BT SPP is running, count = {}......'.format(timestamp, count))
print('')
else:
print('BT SPP has stopped running, ready to exit.')
break
# 若脚本作为主程序运行,则执行main函数
if __name__ == '__main__':
main()
第四步:手机配合测试 —— 秒变
“蓝牙数据中转站”
代码跑起来后,咱们用手机配合测试一下:
1、手机下载 “blue-spp” 软件(专门玩 SPP 的工具)
2、打开手机蓝牙,搜索到咱们设置的蓝牙名(比如 “QuecPython-SPP”)
3、连接成功后,在手机上输入点文字,模组就能收到啦~反过来模组也能发数据给手机
亲测有效,数据嗖嗖传,比插线方便多了!



总结一下:SPP 模式超实用,上手超简单!
今天的蓝牙 SPP 小课堂就到这里~ 简单说:
● SPP 是经典蓝牙的 “无线串口”,能模拟有线通信,传数据超方便
● 支持 EC200U、EC600U 等多款模组,手头有的赶紧试
● Quecpython 平台调用接口就行,不用啃底层,小白也能玩
更多推荐

所有评论(0)