蓝牙Mesh开发六 ESP32蓝牙Mesh Wifi共存(浅析)

本文介绍如何使用ESP32实现BLE Mesh网关,包括配置PSRAM、使能蓝牙与Wi-Fi共存等功能。此外,还展示了如何通过MQTT协议将数据上传至云端。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

上一章节用到了低功耗的Ble蓝牙来开发mesh低功耗的应用,但是需要接入网络还需要一个网关。ESP32已经支持了蓝牙Mesh和WIFI协议栈,但是其硬件基础上仅单天线,并且受限其有限的资源;而令人叫喜的是,IDF4.2版本已经很好的支持共存,虽然目前仅只有Wi-Fi STA模式下支持共存,但是通过增加PSRAM可有效提高了BLE WIFI共存模式的数据吞吐率(1Mbps),作为BLE MESH的网关就在好不过
如有异议,欢迎留言指正

功能设计

网关发现未配网设备广播后,网关使能配网器功能将其配置到mesh网络中,并建立友谊连接,通过mqtt协议与云端进行交互
在这里插入图片描述

工程实例

共存的工程实例可以参考esp-idf\examples\bluetooth\esp_ble_mesh\ble_mesh_wifi_coexist

配置器配置
使能PSRAM

需要通过idf.py menuconfig配置器配置PSRAM(主要是提高吞吐率),可以参考上一篇博文
允许LWIP的内存在PSRAM中分配(给应用释放资源)
在这里插入图片描述

使能WIFI蓝牙共存

在这里插入图片描述

BLE扫描全窗

在这里插入图片描述

BLE使用动态内存

在这里插入图片描述

使能友谊功能

可以配置友谊功能节点的接收窗口、队列、支持的节点等相关参数
在这里插入图片描述

初始化BLE Mesh
配网功能

移植配网器的例程 examples\bluetooth\esp_ble_mesh\ble_mesh_provisioner,针对匹配的UUID未配网设备进行配网
这里也可以直接使用普通节点功能代码,后续通过代理来进行配网

uint8_t match[2] = {0xdd, 0xdd}; //uuid
.... //省略
err = esp_ble_mesh_provisioner_set_dev_uuid_match(match, sizeof(match), 0x0, false);//匹配uuid
if (err != ESP_OK) {
	ESP_LOGE(TAG, "Failed to set matching device uuid (err %d)", err);
	return err;
}
配置元素与模型

参考vendor_model例程,添加服务模型;(也可以使用客户端模型例程 )

static esp_ble_mesh_model_t root_models[] = {//根模型即配置模型
    ESP_BLE_MESH_MODEL_CFG_SRV(&config_server),
};
static esp_ble_mesh_model_op_t vnd_op[] = { //opcode 命令码
    ESP_BLE_MESH_MODEL_OP(ESP_BLE_MESH_VND_MODEL_OP_SEND, 2),
    ESP_BLE_MESH_MODEL_OP_END,
};
static esp_ble_mesh_model_t vnd_models[] = {//厂家模型(02E5 0001)
    ESP_BLE_MESH_VENDOR_MODEL(CID_ESP, ESP_BLE_MESH_VND_MODEL_ID_SERVER,
    vnd_op, NULL, NULL),
};
static esp_ble_mesh_elem_t elements[] = { //元素【根模型 + 厂家模型】
    ESP_BLE_MESH_ELEMENT(0, root_models, vnd_models),//仅一个主元素
};
static esp_ble_mesh_comp_t composition = { //填充数据
    .cid = CID_ESP,
    .elements = elements,
    .element_count = ARRAY_SIZE(elements),
};

乐鑫从SIG申请的厂家ID为0x02E5

#define CID_ESP             0x02E5
mesh通信数据

接收消息回调,需要在mesh初始化时注册回调

static void example_ble_mesh_custom_model_cb(esp_ble_mesh_model_cb_event_t event,
                                             esp_ble_mesh_model_cb_param_t *param)
{
    switch (event) {
    case ESP_BLE_MESH_MODEL_OPERATION_EVT: //收到节点消息事件
        if (param->model_operation.opcode == ESP_BLE_MESH_VND_MODEL_OP_SEND) {//匹配命令码
            //uint16_t tid = *(uint16_t *)param->model_operation.msg;         
			
           nodeBuf[param->model_operation.length] = '\0';           
			memcpy(nodeBuf, param->model_operation.msg, param->model_operation.length);//备份数据
           ESP_LOGI(TAG, "recv = %s \n",nodeBuf);//打印消息
/*			
            esp_err_t err = esp_ble_mesh_server_model_send_msg(&vnd_models[0],
                    param->model_operation.ctx, ESP_BLE_MESH_VND_MODEL_OP_STATUS,
                    sizeof(tid), (uint8_t *)&tid);//返回消息
            if (err) {
                ESP_LOGE(TAG, "Failed to send message 0x%06x", ESP_BLE_MESH_VND_MODEL_OP_STATUS);
            }
*/
        }
        break;
    case ESP_BLE_MESH_MODEL_SEND_COMP_EVT://发送完成事件
        if (param->model_send_comp.err_code) {
            ESP_LOGE(TAG, "Failed to send message 0x%06x", param->model_send_comp.opcode);
            break;
        }
        ESP_LOGI(TAG, "Send 0x%06x", param->model_send_comp.opcode);
        break;
    default:
        break;
    }
}
wifi配置

使用共存例程里面的wifi station配置

void config_wifi_station(void)
{
    wifi_config_t wifi_config =
    {
        .sta = {
            .ssid = EXAMPLE_ESP_WIFI_SSID,//
            .password = EXAMPLE_ESP_WIFI_PASS,//
            .pmf_cfg = {
                .capable = true,
                .required = false
            },
        },
    };
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL));
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_ps(WIFI_PS_MIN_MODEM) ); //必须配置 must call this;
    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
    ESP_ERROR_CHECK( esp_wifi_connect() );
}
云端上传

移植的mqtt的例程

msg_id = esp_mqtt_client_publish(client, "/gwedYwAc0FA/meshDevice001/user/temp_value", nodeBuf, 0, 1, 0);
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
总结
  1. 测试中两个低功耗节点每定时发送一次环境温度的消息到网关,再由网关在上报到某里云上,测试数据量不大,未有数据丢失的情况
    在这里插入图片描述

  2. ESP32使用代理配网时,如果此时在进行wifi数据通信,配网时间相对时间会变长

### 关于 iOS 平台 ESP32 蓝牙 Mesh 开发 #### 使用 ESP32 进行蓝牙 Mesh 网络开发的基础概念 ESP-IDF 提供了丰富的 API 来支持 Bluetooth Mesh 协议栈,允许设备之间形成复杂的网络拓扑结构[^1]。然而,在 iOS 设备上控制或参与这样的网络涉及到不同层次的技术集成。 #### 设置环境准备 为了在 iOS 应用程序中与基于 ESP32蓝牙 Mesh 设备交互,需先安装必要的工具链: - 安装最新版本的 Xcode 和 CocoaPods。 - 配置 ESP-IDF 工具链用于编译固件并烧录至 ESP32 模组。 #### 创建简单的蓝牙 Mesh 示例项目 对于 ESP32 侧而言,可以从 `examples/bluetooth` 文件夹下的现有例子出发,调整配置使其适应特定需求。这里假设已经熟悉基本的 ESP-IDF 编程模型以及如何上传代码到硬件平台。 ```c #include "esp_bt.h" #include "nvs_flash.h" void app_main(void){ esp_err_t ret; // 初始化 NVS ret = nvs_flash_init(); // 启动蓝牙子系统... } ``` 此部分主要关注初始化过程;实际应用时还需加入更多细节来构建完整的节点行为逻辑。 针对 iOS 方面,则可以利用 Apple 提供的 CoreBluetooth 框架来进行通信操作。下面是一个简化版的应用入口点示意: ```swift import UIKit import CoreBluetooth class ViewController: UIViewController { var centralManager:CBCentralManager! override func viewDidLoad() { super.viewDidLoad() self.centralManager = CBCentralManager(delegate:self,options:nil); } } extension ViewController : CBCentralManagerDelegate{ func centralManagerDidUpdateState(_ central: CBCentralManager) { switch(central.state){ case .poweredOn: print("BLE powered on.") default: break; } } } ``` 上述 Swift 片段展示了怎样启动扫描流程去发现周围可用的服务端点——即运行着相应固件程序的 ESP32 设备们。 值得注意的是,由于苹果公司对第三方协议的支持有限制,因此直接通过官方API实现完全兼容的蓝牙 mesh 功能可能具有挑战性。通常情况下,会采用桥接的方式让 iPhone 成为网关的一部分,或是借助云端服务间接管理整个mesh网络的状态变化。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值