# ESP32WiFiBleControlProject **Repository Path**: exploit/ESP32WiFiBleControlProject ## Basic Information - **Project Name**: ESP32WiFiBleControlProject - **Description**: 项目地址 https://gitee.com/futao314159/ESP32WiFiBleControlProject 微信小程序蓝牙+WiFi控制安信可ESP32-S/C3S模块应用示范 注释:本人使用的是 ESP-C3-32S 我因为是新手!很多不懂的地方并且,我在这里写下自己在使用本示例的一些心得 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: https://gitee.com/futao314159/ESP32WiFiBleControlProject - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-12-10 - **Last Updated**: 2021-12-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 微信小程序蓝牙+WiFi双控制ESP32-C3应用示范

Banner

> ||——分割线———以下是学习使用的笔记——开发板:ESP-C3-32S ———||: 一自建 MQTT 服务 https://www.emqx.com/zh/try?product=broker ![输入图片说明](212213307.png) 安装很简单 官方文档地址 https://docs.emqx.cn/enterprise/v4.3/getting-started/command-line.html 开发板配置: 需要配置WIFI账号密码 sdkconfig 中搜索WIFI 我相信你能找到 gatts_demo.c 在这里设置 mqtt 服务的域名和账号密码就可以了,其他的不需要修改 。 出错问题: 1.下载正常 串口查看器 显示数据有错误。我的原因是固件版本是2M的出厂固件 ,我烧写了 最新版固件后解决了问题。 固件下载地址 https://docs.ai-thinker.com/esp32c3 固件刷入工具 https://www.espressif.com/zh-hans/support/download/other-tools 2.配置 由于和开发者的开发板不同所以LED灯不能正常使用 总是绿灯 而且接到小程序或者 WIFI 的数据时会闪下 然后就没反应了。 小程序 蓝牙正常使用但是切换到网络显示不能连接服务器,大概率是MQTT连接的方法不正确 !可能和自建的mqtt和本例程开发者的不同。 ////////////////////////////////////////////下面是作者的内容///////////////////////////////////////////////////// # 一、前言 目前市场上越来越火的 Combo 方案(**Ble+WiFi**),比如平头哥的TG7100C方案、乐鑫的ESP32等,如何高效使用蓝牙和wifi通讯,已经成为了必然的趋势,于是乎,做了个这样快速入门的demo给各位,奉献于物联网; 本项目适合的模组有: | 模组 | 链接 | | ---------------------- | --------------------- | | 安信可ESP32-S模组 | http://yli08.cn/wjy03 | | 安信可ESP32-SL模组 | http://yli08.cn/IKalA | | 安信可ESP32-C3系列模组 | 联系商务 | 本开源工程用到的技术点有: 1. 乐鑫物联网操作框架 esp-idf 的 freeRtos 实时操作系统熟悉,包括任务创建/消息队列/进程间通讯; 2. 微信小程序开发基础,包括MQTT库/低功耗蓝牙API接口使用,包括搜索/连接/通讯; 3. 使用乐鑫封装 RMT 驱动层单线驱动WS2812B,实现彩虹等效果; 4. 对ESP32/C3芯片的外设开发熟悉,对BLE API接口使用熟悉,包括自定义广播/名字/自定义UUID; # 二、设备核心代码 ## 2.1 蓝牙控制 设置蓝牙广播名字 ```c esp_ble_gap_set_device_name(TEST_DEVICE_NAME); ``` 设置服务UUID ```c gl_profile_tab[0].service_id.is_primary = true; gl_profile_tab[0].service_id.id.inst_id = 0x00; gl_profile_tab[0].service_id.id.uuid.len = ESP_UUID_LEN_16; gl_profile_tab[0].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_A; ``` 主动通知上位机数据发生改动: ```c case ESP_GATTS_READ_EVT: { esp_gatt_rsp_t rsp; memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); rsp.attr_value.handle = param->read.handle; rsp.attr_value.len = 3; rsp.attr_value.value[0] = red; rsp.attr_value.value[1] = green; rsp.attr_value.value[2] = blue; esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, ESP_GATT_OK, &rsp); break; } ``` 上位机主动发送数据到此并做出对应的处理: ```c case ESP_GATTS_WRITE_EVT: { if (!param->write.is_prep) { ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len); esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len); //发送数据到队列 struct __User_data *pTmper; sprintf(user_data.allData, "{\"red\":%d,\"green\":%d,\"blue\":%d}", param->write.value[0], param->write.value[1], param->write.value[2]); pTmper = &user_data; user_data.dataLen = strlen(user_data.allData); xQueueSend(ParseJSONQueueHandler, (void *)&pTmper, portMAX_DELAY); ESP_LOGI(GATTS_TAG, "%02x %02x %02x ", param->write.value[0], param->write.value[1], param->write.value[2]); } example_write_event_env(gatts_if, &a_prepare_write_env, param); break; } ``` ## 2.2 WiFi控制 设置MQTT远程连接的参数 ```c /* * @Description: MQTT参数连接的配置 * @param: * @return: */ void TaskXMqttRecieve(void *p) { //连接的配置参数 esp_mqtt_client_config_t mqtt_cfg = { .host = "www.xuhong.com", //连接的域名 ,请务必修改为您的 .port = 1883, //端口,请务必修改为您的 .username = "admin", //用户名,请务必修改为您的 .password = "xuhong123456", //密码,请务必修改为您的 .client_id = deviceUUID, .event_handle = MqttCloudsCallBack, //设置回调函数 .keepalive = 120, //心跳 .disable_auto_reconnect = false, //开启自动重连 .disable_clean_session = false, //开启 清除会话 }; client = esp_mqtt_client_init(&mqtt_cfg); esp_mqtt_client_start(client); vTaskDelete(NULL); } ``` 服务器下发的处理数据,送往消息队列处理: ``` //服务器下发消息到本地成功接收回调 case MQTT_EVENT_DATA: { printf("TOPIC=%.*s \r\n", event->topic_len, event->topic); printf("DATA=%.*s \r\n\r\n", event->data_len, event->data); //发送数据到队列 struct __User_data *pTmper; sprintf(user_data.allData, "%s", event->data); pTmper = &user_data; user_data.dataLen = event->data_len; xQueueSend(ParseJSONQueueHandler, (void *)&pTmper, portMAX_DELAY); break; } ``` ## 2.3 外设驱动 七彩灯WS2812B的驱动代码初始化: ```c /** * @description: 封装一层设置RGB灯效果 * @param {uint16_t} Red 入参 红色 * @param {uint16_t} Green 入参 绿色 * @param {uint16_t} Blue 入参 蓝色 * @return {*} */ void set_rgb(uint16_t Red, uint16_t Green, uint16_t Blue) { for (int i = 0; i < 24; i++) { strip->set_pixel(strip, i, Red, Green, Blue); } red = Red; green = Green; blue = Blue; strip->refresh(strip, 10); } /** * @description: 初始化LED * @param {*} * @return {*} */ void init_led() { rmt_config_t config = RMT_DEFAULT_CONFIG_TX(4, RMT_TX_CHANNEL); // set counter clock to 40MHz config.clk_div = 2; ESP_ERROR_CHECK(rmt_config(&config)); ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0)); // install ws2812 driver led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(24, (led_strip_dev_t)config.channel); strip = led_strip_new_rmt_ws2812(&strip_config); if (!strip) { ESP_LOGE(TAG, "install WS2812 driver failed"); } // Clear LED strip (turn off all LEDs) ESP_ERROR_CHECK(strip->clear(strip, 100)); set_rgb(0, 254, 0); } ``` 消息队列处理逻辑: ```c /* * @Description: 解析下发数据的队列逻辑处理 * @param: null * @return: */ void Task_ParseJSON(void *pvParameters) { printf("[SY] Task_ParseJSON_Message creat ... \n"); while (1) { struct __User_data *pMqttMsg; printf("Task_ParseJSON_Message xQueueReceive wait [%d] ... \n", esp_get_free_heap_size()); xQueueReceive(ParseJSONQueueHandler, &pMqttMsg, portMAX_DELAY); printf("Task_ParseJSON_Message xQueueReceive get [%s] ... \n", pMqttMsg->allData); ////首先整体判断是否为一个json格式的数据 cJSON *pJsonRoot = cJSON_Parse(pMqttMsg->allData); //如果是否json格式数据 if (pJsonRoot == NULL) { printf("[SY] Task_ParseJSON_Message xQueueReceive not json ... \n"); goto __cJSON_Delete; } cJSON *pJSON_Item_Red = cJSON_GetObjectItem(pJsonRoot, "red"); cJSON *pJSON_Item_Green = cJSON_GetObjectItem(pJsonRoot, "green"); cJSON *pJSON_Item_Blue = cJSON_GetObjectItem(pJsonRoot, "blue"); set_rgb(pJSON_Item_Red->valueint, pJSON_Item_Green->valueint, pJSON_Item_Blue->valueint); __cJSON_Delete: cJSON_Delete(pJsonRoot); } } ``` ## 三、微信小程序核心代码 代码架构,UI主要采用第三方库:有 WeUI、Vant-UI库,其中的MQTT库采用开源的MQTT.JS库。

Banner

## 3.1 蓝牙搜索 ``` wx.onBluetoothDeviceFound(function (devices) { var isnotexist = true if (devices.deviceId) { if (devices.advertisData) { devices.advertisData = app.buf2hex(devices.advertisData) } else { devices.advertisData = '' } for (var i = 0; i < that.data.devicesList.length; i++) { if (devices.deviceId == that.data.devicesList[i].deviceId) { isnotexist = false } } if (isnotexist && devices[0].name === that.data.filterName ) { that.data.devicesList.push(devices[0]) } } that.setData({ devicesList: that.data.devicesList }) }) } ``` ## 3.2 蓝牙服务发现 发现服务列表:```wx.getBLEDeviceServices()``` 发现特征值列表:```wx.getBLEDeviceCharacteristics()``` 发送设备,判断是否为蓝牙控制或wifi控制: ```javascript SendTap: function (red, green, blue) { var that = this if (!this.data.isCheckOutControl) { if (this.data.connected) { var buffer = new ArrayBuffer(that.data.inputText.length) var dataView = new Uint8Array(buffer) dataView[0] = red; dataView[1] = green; dataView[2] = blue; wx.writeBLECharacteristicValue({ deviceId: that.data.connectedDeviceId, serviceId: that.data.serviceId, characteristicId: "0000FF01-0000-1000-8000-00805F9B34FB", value: buffer, success: function (res) { console.log('发送成功') }, fail() { wx.showModal({ title: '提示', content: '蓝牙已断开', showCancel: false, success: function (res) { } }) } }) } else { wx.showModal({ title: '提示', content: '蓝牙已断开', showCancel: false, success: function (res) { that.setData({ searching: false }) } }) } } else { //MQTT通讯发送 if (this.data.client && this.data.client.connected) { this.data.client.publish('/esp32-c3/7cdfa1322e68/devSub', JSON.stringify({red,green,blue})); } else { wx.showToast({ title: '请先连接服务器', icon: 'none', duration: 2000 }) } } }, ``` # 四、感谢 为此,还开源了以下的代码仓库,共勉!! | 开源项目 | 地址 | 开源时间 | | --------------------------------------------------------- | ----------------------------------------------------------- | -------- | | 微信小程序连接mqtt服务器,控制esp8266智能硬件 | https://github.com/xuhongv/WeChatMiniEsp8266 | 2018.11 | | 微信公众号airkiss配网以及近场发现在esp8266 rtos3.1 的实现 | https://github.com/xuhongv/xLibEsp8266Rtos3.1AirKiss | 2019.3 | | 微信公众号airkiss配网以及近场发现在esp32 esp-idf 的实现 | https://github.com/xuhongv/xLibEsp32IdfAirKiss | 2019.9 | | 微信小程序控制esp8266实现七彩效果项目源码 | https://github.com/xuhongv/WCMiniColorSetForEsp8266 | 2019.9 | | 微信小程序蓝牙配网blufi实现在esp32源码 | https://github.com/xuhongv/BlufiEsp32WeChat | 2019.11 | | 微信小程序蓝牙ble控制esp32七彩灯效果 | https://blog.csdn.net/xh870189248/article/details/101849759 | 2019.10 | | 可商用的事件分发的微信小程序mqtt断线重连框架 | https://blog.csdn.net/xh870189248/article/details/88718302 | 2019.2 | | 微信小程序以 websocket 连接阿里云IOT物联网平台mqtt服务器 | https://blog.csdn.net/xh870189248/article/details/91490697 | 2019.6 | | 微信公众号网页实现连接mqtt服务器 | https://blog.csdn.net/xh870189248/article/details/100738444 | 2019.9 | | 自主开发微信小程序接入腾讯物联开发平台,实现一键配网+控制 | https://github.com/xuhongv/AiThinkerIoTMini | 2020.9 | | 云云对接方案天猫精灵小爱同学服务器+嵌入式Code开源 | https://github.com/xuhongv/xClouds-php | 2020.7 | 另外,感谢: - 乐鑫物联网操作系统:https://github.com/espressif/esp-idf - 腾讯WeUI框架:https://github.com/Tencent/weui-wxss - 有赞Vant框架:https://vant-contrib.gitee.io/vant-weapp