基于ESP32-C3的蓝牙主从一体示例程序
本文将介绍如何在ESP32-C3上编写一个蓝牙主从一体(Dual Role)的示例程序,使其一方面可以与微信小程序通信,另一方面又能连接到另一个蓝牙设备。
开发环境准备
- 硬件:ESP32-C3开发板
- 软件:
- ESP-IDF(ESP32的官方开发框架)
- 安装了ESP-IDF插件的Visual Studio Code或其他IDE
功能概述
- Peripheral(从设备)角色:ESP32-C3作为蓝牙外设,与微信小程序进行通信。
- Central(主设备)角色:ESP32-C3作为蓝牙主机,连接并通信另一个蓝牙设备。
实现步骤
1. 初始化BLE环境
首先,初始化蓝牙BLE的环境,包括NVS闪存和蓝牙控制器。
#include "nvs_flash.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
void app_main(void)
{
// 初始化NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
// 初始化蓝牙控制器
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
ret = esp_bt_controller_init(&bt_cfg);
ESP_ERROR_CHECK(ret);
// 使能BLE模式
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
ESP_ERROR_CHECK(ret);
// 初始化蓝牙栈
ret = esp_bluedroid_init();
ESP_ERROR_CHECK(ret);
ret = esp_bluedroid_enable();
ESP_ERROR_CHECK(ret);
// 后续代码...
}
2. 配置为Peripheral(从设备)角色
设置GATT服务和特征,使ESP32-C3可以作为蓝牙外设被微信小程序连接。
// 定义服务UUID和特征UUID
#define GATTS_SERVICE_UUID_WECHAT 0x00FF
#define GATTS_CHAR_UUID_WECHAT_TX 0xFF01
#define GATTS_CHAR_UUID_WECHAT_RX 0xFF02
// 定义属性句柄
static uint16_t wechat_service_handle = 0;
static esp_gatt_char_prop_t wechat_property = 0;
// GATT服务和特征的回调函数
static void gatts_profile_event_handler(/* 参数列表 */)
{
// 处理GATT事件,例如READ、WRITE、CONNECT、DISCONNECT等
}
// 注册GATT服务
void wechat_gatts_init(void)
{
esp_err_t ret;
// 注册GATT回调
ret = esp_ble_gatts_register_callback(gatts_profile_event_handler);
ESP_ERROR_CHECK(ret);
// 创建GATT服务
ret = esp_ble_gatts_create_service(/* 参数列表 */);
ESP_ERROR_CHECK(ret);
// 启动服务
ret = esp_ble_gatts_start_service(wechat_service_handle);
ESP_ERROR_CHECK(ret);
}
3. 配置为Central(主设备)角色
使ESP32-C3作为蓝牙主机,扫描并连接其他蓝牙设备。
// 定义扫描参数
static esp_ble_scan_params_t ble_scan_params = {
.scan_type = BLE_SCAN_TYPE_ACTIVE,
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
.scan_interval = 0x50,
.scan_window = 0x30,
.scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE
};
// 扫描回调函数
static void gap_event_handler(/* 参数列表 */)
{
// 处理扫描结果,连接目标设备
}
// 初始化GAP并开始扫描
void ble_central_init(void)
{
esp_err_t ret;
// 注册GAP回调
ret = esp_ble_gap_register_callback(gap_event_handler);
ESP_ERROR_CHECK(ret);
// 设置扫描参数
ret = esp_ble_gap_set_scan_params(&ble_scan_params);
ESP_ERROR_CHECK(ret);
}
4. 集成主从角色功能
在app_main
函数中,调用以上初始化函数,实现主从一体的功能。
void app_main(void)
{
// 前面的初始化代码...
// 初始化GATT服务(Peripheral角色)
wechat_gatts_init();
// 初始化GAP并开始扫描(Central角色)
ble_central_init();
}
5. 与微信小程序通信
在GATT服务的回调函数中,处理微信小程序发送的数据,并进行相应的回应。
static void gatts_profile_event_handler(esp_gatts_cb_event_t event,
esp_gatt_if_t gatts_if,
esp_ble_gatts_cb_param_t *param)
{
switch (event)
{
case ESP_GATTS_WRITE_EVT:
// 处理微信小程序发送的数据
break;
case ESP_GATTS_READ_EVT:
// 处理微信小程序的读请求
break;
// 其他事件处理...
default:
break;
}
}
6. 与另一个蓝牙设备通信
在GAP回调函数中,扫描并连接目标设备,建立GATT连接后,进行数据通信。
static void gap_event_handler(esp_gap_ble_cb_event_t event,
esp_ble_gap_cb_param_t *param)
{
switch (event)
{
case ESP_GAP_BLE_SCAN_RESULT_EVT:
// 处理扫描结果,判断是否是目标设备
break;
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
// 开始扫描
esp_ble_gap_start_scanning(0);
break;
// 其他事件处理...
default:
break;
}
}
注意事项
- 资源限制:ESP32-C3的资源有限,同时运行主从角色可能会导致内存紧张,需要精简代码和优化内存使用。
- 微信蓝牙协议:与微信小程序通信需要遵循微信的蓝牙接入协议,可能需要申请相关权限和认证。
- 设备兼容性:确保另一个蓝牙设备支持BLE通信,并且可以被ESP32-C3识别和连接。
完整代码示例
由于篇幅限制,无法提供完整的代码。您可以参考以下官方示例,根据需求进行修改:
结语
通过以上步骤,我们实现了在ESP32-C3上同时运行BLE主设备和从设备的功能。一方面可以与微信小程序通信,实现手机与设备的数据交互;另一方面又能连接其他蓝牙设备,扩展了设备的功能和应用场景。
希望本文对您有所帮助,如有疑问,欢迎交流讨论。