58. ESP32的蓝牙功能
一、ESP32简介
ESP32 是乐鑫公司(ESPRESSIF)继 ESP8266 芯片后推出的又一款集成集成了 Wi-Fi 和蓝牙功能的低成本、低功耗的微控制器。它是一个集成天线和射频巴伦、功率放大器、低噪声放大器、滤波器和电源管理模块。整个解决方案占用的印刷电路板面积最少。该板采用台积电 40nm 低功耗技术的 2.4GHz 双模 Wi-Fi 和蓝牙芯片,功率和射频性能最佳,安全可靠,可扩展到各种应用。 ESP32 指的是 ESP32 裸芯片。但是,“ESP32” 一词通常指 ESP32 系列芯片及开发板。
参考文档链接如下:https://docs.ai-thinker.com/bt。
ESP32 模块的蓝牙功能非常强大,它支持蓝牙 5.0 标准,包括 低功耗蓝牙(Bluetooth Low Energy,BLE)和 经典蓝牙(Bluetooth Classic)两种模式。
- 双模蓝牙 :ESP32 模块支持蓝牙 5.0,这意味着它可以同时作为经典蓝牙和低功耗蓝牙设备工作。经典蓝牙主要用于与传统蓝牙设备(如手机、电脑)进行通信,而低功耗蓝牙则适合于物联网(IoT)设备,因为它具有更低的功耗和更长的电池寿命。
- Wi-Fi共存 :ESP32 模块可以同时使用 Wi-Fi 和蓝牙功能,这对于需要同时连接到 Wi-Fi 和蓝牙网络的设备来说非常有用。
- 音频支持 :ESP32 模块支持蓝牙音频,可以用于无线耳机、扬声器和其他音频设备。
- 蓝牙 Mesh :ESP32 模块支持蓝牙 Mesh 网络,这是一种用于构建大规模网络的蓝牙技术,非常适合智能照明、家庭自动化和其他物联网应用。
二、AT指令简介
ESP32 可以通过 AT 指令进行配置和控制,与其它蓝牙模块进行交互,以便在设备之间建立连接、交换数据或进行其他配置操作。AT 指令以 "AT" 作为起始符,后面跟随特定的指令代码和参数,以新的一行(CRLF)为结尾。输入的每条命名都会返回 OK 或者 ERROR 的响应。
AT 指令可以细分为四种类型,如下表所示:

具体的 AT 指令,我们可以在官网提供的文档中查看:https://docs.espressif.com/projects/esp-at/zh_CN/latest/esp32/AT_Command_Set/index.html。



三、蓝牙功能初始化
/**
* @brief ESP32的蓝牙功能初始化函数
*
*/
void ESP32_BLE_Init(void)
{
// 初始化蓝牙角色 1: client; 2: server
if (ESP32_SendAtCmd("AT+BLEINIT=2", "OK", 3000)) // 低功耗蓝牙初始化
{
printf("低功耗蓝牙初始化成功\r\n");
}
if (ESP32_SendAtCmd("AT+BLEGATTSSRVCRE", "OK", 3000)) // 创建GSTT服务
{
printf("创建GSTT服务成功\r\n");
}
if (ESP32_SendAtCmd("AT+BLEGATTSSRVSTART","OK", 500)) // 开启GSTT服务
{
printf("开启GSTT服务成功\r\n");
}
// AT+BLEADVPARAM=<最小广播间隔>,<最大广播间隔>,<adv_type>,<Bluetooth LE 地址类型>,<广播信道>[,<广播过滤器规则>][,<对方 Bluetooth LE 地址类型>,<对方 Bluetooth LE 地址>]
if (ESP32_SendAtCmd("AT+BLEADVPARAM=50,50,0,0,7,0", "OK", 500)) // 设置蓝牙广播参数
{
printf("设置蓝牙广播参数成功\r\n");
}
// AT+BLEADVDATAEX=<设备名称>,<uuid>,<制造商数据>,<是包含TX功率>
if (ESP32_SendAtCmd("AT+BLEADVDATAEX=\"ESP32\",\"A111\",\"1122334455\",1", "OK", 500)) // 自动设置广播参数
{
printf("自动设置广播参数成功\r\n");
}
if (ESP32_SendAtCmd("AT+BLEADVSTART", "OK", 500)) // 开启蓝牙广播
{
printf("开启蓝牙广播成功\r\n");
}
if (ESP32_SendAtCmd("AT+SYSMSG=4", "OK", 500)) // 设置系统提示信息
{
printf("设置系统提示信息成功\r\n");
}
// 开启透传要在连接之后
if (ESP32_SendAtCmd("AT+BLESPPCFG=1,1,7,1,5", "OK", 300)) // 设置蓝牙透传参数
{
printf("设置蓝牙透传参数成功\r\n");
}
}
四、蓝牙接收数据
我们可以从手机的软件商店中下载 BLE 蓝牙调试助手来向 ESP32 发送数据。这里,串口接收的数据格式如下:

typedef enum ESP32_BLE_Status_t
{
WIFI_CHANGE, // WIFI状态变化
BLE_ERROR, // 错误
BLE_CONN, // 蓝牙连接
BLE_DISCONN, // 蓝牙断开
BLE_UT, // 蓝牙透传模式
BLE_DATA, // 蓝牙数据模式
BLE_OTHER, // 其它
} ESP32_BLE_Status_t;
/**
* @brief ESP32蓝牙连接状态改变的处理函数
*
* @return ESP32_BLE_Status ESP32连接状态枚举值
*/
ESP32_BLE_Status_t ESP32_BLE_HandlerConnectChange(void)
{
// 如果还没有接收完,直接结束方法
if (!pg_uart_esp32_frameData->finsh)
{
return BLE_ERROR;
}
if (strstr((const char *)pg_uart_esp32_frameData->data, "WIFI"))
{
printf("WIFI连接状态改变\r\n");
UART_ClearFrameData(pg_uart_esp32_frameData);
return WIFI_CHANGE;
}
else if (strstr((const char *)pg_uart_esp32_frameData->data, "+BLECONN:"))
{
printf("蓝牙连接成功,准备开启透传模式\r\n");
if (ESP32_SendAtCmd("AT+BLESPP", "OK", 500))
{
printf("开启透传模式成功\r\n");
}
UART_ClearFrameData(pg_uart_esp32_frameData);
return BLE_UT;
}
else if (strstr((const char *)pg_uart_esp32_frameData->data, "+BLEDISCONN"))
{
printf("蓝牙已断开连接,准备退出透传模式\r\n");
UART_ClearFrameData(pg_uart_esp32_frameData);
ESP32_ExitUnvarnished(); // 退出透传模式
printf("重新开始广播\r\n");
if (ESP32_SendAtCmd("AT+BLEADVSTART", "OK", 500)) // 开启蓝牙广播
{
printf("重新开启蓝牙广播成功\r\n");
}
UART_ClearFrameData(pg_uart_esp32_frameData);
return BLE_DISCONN;
}
else if (strstr((const char *)pg_uart_esp32_frameData->data, "+BLECONNPARAM"))
{
UART_ClearFrameData(pg_uart_esp32_frameData);
return BLE_OTHER;
}
return BLE_DATA;
}
/**
/**
* @brief ESP32读取蓝牙接收的数据
*
* @param data 用于保存接收到的数据
* @param length 记录接收数据的长度
*/
void ESP32_BLE_ReadData(char *data, uint16_t *length)
{
memset(data, 0, strlen(data));
*length = 0;
// 如果还没有接收完,直接结束方法
if (!pg_uart_esp32_frameData->finsh)
{
return;
}
if (ESP32_BLE_HandlerConnectChange() == BLE_DATA)
{
strcpy(data, (const char *)pg_uart_esp32_frameData->data);
*length = pg_uart_esp32_frameData->length;
}
UART_ClearFrameData(pg_uart_esp32_frameData);
}
五、蓝牙发送数据
/**
* @brief ESP32通过蓝牙发送的数据
*
* @param data 指向要发送数据的指针
* @param length 要发送数据的长度
*/
void ESP32_BLE_SendData(char *data, uint16_t length)
{
if (length == 0)
{
return;
}
HAL_UART_Transmit(pg_uart_esp32_handler, (uint8_t *)data, length, 100);
}
六、main()函数
int main(void)
{
char data[100] = {0};
uint16_t length = 0;
HAL_Init();
System_Clock_Init(8, 336, 2, 7);
Delay_Init();
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
UART_Init(&g_usart1_handle, USART1, 115200);
UART_Init(&g_usart2_handle, USART3, 115200);
ESP32_Init(&g_usart2_handle, &g_usart2_frame_data);
ESP32_BLE_Init();
while (1)
{
memset(data, 0, sizeof(data));
length = 0;
ESP32_BLE_ReadData(data, &length);
if (length)
{
ESP32_BLE_SendData(data, length);
}
}
return 0;
}


浙公网安备 33010602011771号