引言
去年11月份,自己接到的第一个任务就是蓝牙,二维码任务结束后自己又开始做这一个任务,由于还没有定好应用场景,自己先根据自己的理解,介绍一下如何用ESP32实现BLE蓝牙。
开发环境
本工程将ESP32芯片作为从机,使用其他MCU来驱动ESP32,开发的操作系统还是阿里的物联网系统Alios。ESP32可以使用多种方式与主MCU进行通信,例如串口,SPI以及SDIO,但是官方好像说只能同时支持一种通信方式,在本项目中使用SDIO通信作为主MCU与ESP32芯片的通信方式。
开发过程
开发过程其实没什么好说的,在开始的时候我一直认为要写很复杂的程序才能使用蓝牙,其实自己想错了,ESP32提供了一整套较为完整的AT命令,乐鑫公司已经把驱动代码封装到固件中了,开发者只需要使用与BLE蓝牙相关的AT命令,编写业务逻辑就可以了,这里提供3个我自己经常查看的教程。 1、BLE 命令介绍和使用 2、ESP32 常用蓝牙AT指令使用例程 3、ESP32官方AT命令文档
我认为使用ESP32的AT命令开发蓝牙重点在于自己产品的业务逻辑,如蓝牙是做server还是client,获得的数据怎么处理,应用场景等。我自己的项目执行这几个命令就可以了。
AT+BLEINIT=2 //初始化BLE为server AT+BLEGATTSSRVCRE //GATTS 创建服务 AT+BLEGATTSSRVSTART //GATTS 开启服务 AT+BLEADVSTART //开启BLE广播
难点 1、主MCU怎么与ESP32使用SDIO进行通信。(驱动工程师编写) 2、在操作系统中怎么进行逻辑编写,在这个项目中使用了消息队列搭建框架。(自己还是新手,架构是其他大佬搭建的)
开发结果
蓝牙客户端使用iphone,由于iphone会将BLE蓝牙过滤,使用LightBlue软件进行开发。可以看到软件可以搜索到自己打开的ESP32低功耗蓝牙。 进行连接发现可以连接,并且GATT服务以及开启 ESP32打印 到此手机与ESP32的BLE蓝牙成功进行连接,下面的等业务逻辑确定后再进一步编写,
知识总结
AT命令
ESP-AT 是乐鑫开发的可直接用于量产的物联网应用固件,旨在降低客户开发成本,快速形成产品。通过 ESP-AT 指令,您可以快速加入无线网络、连接云平台、实现数据通信以及远程控制等功能,真正的通过无线通讯实现万物互联。 AT 命令以 “AT” 开始,代表 Attention,以新的一行 (CR LF) 为结尾。输入的每条命令都会返回 OK 或 ERROR 的响应,表示当前命令的最终执行结果。注意,所有 AT 命令均为串行执行,每次只能执行一条命令。因此,在使用 AT 命令时,应等待上一条命令执行完毕后,再发送下一条命令。
BLE蓝牙协议栈
推荐听一下这个课「物联网」- 蓝牙4.0 BLE开发入门到精通
GATT服务
GATT服务我看了一些还是感觉有点蒙蒙的,在我的理解里,GATT在BLE协议栈里相当于串口一类通信模块的意思,要想使用BLE蓝牙进行数据传输,就必须打开GATT服务,GATT是通用的,客户端和服务器都遵循这个协议。(欢迎指正)
消息队列
消息队列是一种任务间传递数据的有效方式。消息队列使用环形缓冲池(ring buffer)来管理消息的队列缓冲区,并使用类似信号量的机制进行任务间的同步。任务通过消息队列可以发送消息,也可以通过它接收消息,从而实现数据的同步及通信。任务发送的消息会暂存在消息队列中,当接收任务来读时,将暂存的数据传递给接收任务;若接收任务在接收数据时,消息队列中无可读数据,则任务会阻塞,直到有消息到来解除阻塞而进入就绪状态。 在这个项目,大佬将所有的AT命令执行函数抽象成了一个,将AT推入消息队列。
static int at_exec_command(netm_msg_t *cmd, netm_msg_t *resp)
{
int ret;
csi_kernel_mutex_lock(g_cmd_mutex, -1);
cmd->msg_src = SRC_APP;
if (!cmd->timeout) {
cmd->timeout = DEFAULT_CMD_TIMEOUT;
}
ret = csi_kernel_msgq_put(g_netm_queue, cmd, BACK, NO_WAIT);
if (ret < 0) {
printf("ree %d put g_netm_queue is error\r\n",ret);
csi_kernel_mutex_unlock(g_cmd_mutex);
return ret;
}
ret = at_wait_cmd_done(resp, cmd->cmd);
csi_kernel_mutex_unlock(g_cmd_mutex);
return ret;
}
在执行命令的时候,从消息队列不断向外取就可以了。
static void netm_task(void *arg)
{
netm_msg_t msgbuf;
int ret = 0;
while (1) {
memset(&msgbuf, 0, sizeof(msgbuf));
ret = csi_kernel_msgq_get(g_netm_queue, (void *)&msgbuf, -1);
if (ret < 0) {
LOG_E("recv msg fail,error:%d\n", ret);
continue;
}
switch (msgbuf.msg_src) {
case SRC_APP:
handle_at_response(&msgbuf);
handle_at_cmd(&msgbuf);
break;
case SRC_DRIVER:
handle_at_response(&msgbuf);
break;
default:
LOG_E("error msg type\n");
break;
}
}
}
结尾
在这个任务中学到了BLE蓝牙的知识,困难部分大佬已经做过了,自己在架构上缝缝补补的同时也要不断学习,如果让自己全部写的话自己能不能写出来一个完整且易于拓展的业务框架。整体来说要做蓝牙的话使用乐鑫的ESP32还是可以省事很多,在不要求深度定制的情况下,使用AT命令进行开发以及可以满足大部分要求,同理ESP32也支持wifi,思路是一样的。
在等待蓝牙使用场景的这段时间,自己准备做这3件事情。 1、把自己的C语言和操作系统再精进一下,跟着B站上的视频走一遍,查漏补缺一下,顺便刷一些题,练练手感。(现在读懂是没问题了,要向写的方向上发展,不要眼高手低) 2、把之前买的野火的STM32开发板,跟着视频,再把例子重新自己写一下,把SDIO,I2C,SPI等再好好熟悉一下。(感觉经过之前的任务历练后,这些对我来说应该没那么难了) 3、如果有时间的话,把韦东山的Linux也好好学一学,在Linux上主要学内核的知识,如多线程编程,信号量,事件等知识好好专研一下。(把这3个做完后自己应该就可以完全入行了,之前的任务让我感觉基础太不扎实了)
|