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指令分类

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

基础AT命令集

蓝牙AT指令

低功耗蓝牙AT指令

三、蓝牙功能初始化

/**
 * @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;
}

演示视频

posted @ 2025-04-02 20:01  星光映梦  阅读(1660)  评论(0)    收藏  举报