基于ESP32-C3与微信小程序通过BLE传输Wi-Fi和TCP信息的示例程序
目录
概述
本示例程序旨在展示如何通过微信小程序与ESP32-C3开发板进行BLE(蓝牙低功耗)通信,实现将Wi-Fi的账号、密码以及TCP的IP和端口号发送给ESP32-C3。ESP32-C3接收到这些信息后,连接指定的Wi-Fi网络,并启动TCP客户端或服务器,进行网络通信。
系统架构
-
ESP32-C3端:
- BLE从机(Peripheral),提供特定的服务和特征,用于接收数据。
- 接收到Wi-Fi和TCP信息后,保存到NVS(非易失性存储),并连接Wi-Fi网络。
- 根据收到的TCP IP和端口号,启动TCP客户端或服务器。
-
微信小程序端:
- 扫描并连接ESP32-C3的BLE服务。
- 提供用户界面,输入Wi-Fi账号、密码和TCP的IP、端口号。
- 将上述信息通过BLE发送给ESP32-C3。
通信协议设计
BLE服务和特征
- 服务UUID:
0000FFFF-0000-1000-8000-00805F9B34FB
(自定义服务) - 特征UUID:
0000FF01-0000-1000-8000-00805F9B34FB
(用于接收数据)- 属性:写入(Write)、通知(Notify)
数据格式
为了简化通信,定义一种简单的数据格式,将所有信息以JSON字符串的形式发送。示例如下:
{
"ssid": "Your_WiFi_SSID",
"password": "Your_WiFi_Password",
"tcp_ip": "192.168.1.100",
"tcp_port": 12345
}
注意:由于BLE每次传输的数据有限制(通常最大20字节),需要对数据进行分包传输。
ESP32-C3端程序实现
4.1 环境准备
- 硬件:
- ESP32-C3开发板
- 软件:
- ESP-IDF(建议使用v4.4或以上版本)
- 串口调试工具(如
minicom
、putty
等)
4.2 主要功能模块
-
初始化BLE服务:
- 创建自定义服务和特征。
- 设置特征的回调函数,处理来自客户端的数据写入。
-
处理接收的数据:
- 接收来自微信小程序的数据。
- 进行数据重组(如果有分包传输)。
- 解析JSON字符串,提取Wi-Fi和TCP信息。
-
连接Wi-Fi网络:
- 使用接收到的SSID和密码,连接指定的Wi-Fi网络。
- 连接成功后,启动TCP通信。
-
启动TCP客户端或服务器:
- 使用接收到的IP和端口号,启动TCP客户端或服务器。
-
数据持久化:
- 将接收到的配置保存到NVS中,以便设备重启后自动连接。
4.3 完整代码
以下是完整的main.c
代码:
// main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "esp_system.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_ble_gatts_api.h"
#include "esp_gatt_common_api.h"
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "esp_gap_ble_api.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#define TAG "MAIN"
// BLE部分定义
#define PROFILE_NUM 1
#define PROFILE_APP_IDX 0
#define ESP_APP_ID 0x55
#define DEVICE_NAME "ESP32-C3-BLE"
#define SVC_INST_ID 0
// 自定义服务和特征UUID
#define GATTS_SERVICE_UUID 0xFFFF
#define GATTS_CHAR_UUID 0xFF01
#define GATTS_DESCR_UUID 0x3333
#define GATTS_NUM_HANDLE 4
static uint8_t adv_config_done = 0;
#define adv_config_flag (1 << 0)
#define scan_rsp_config_flag (1 << 1)
static uint8_t char_value_str[] = {
0x00};
static esp_gatt_char_prop_t a_property = 0;
static uint16_t gatts_service_handle = 0;
static esp_gatt_srvc_id_t service_id;
static uint16_t conn_id = 0xFFFF;
static esp_ble_adv_params_t adv_params = {
.adv_int_min = 0x20,
.adv_int_max = 0x40,
.adv_type = ADV_TYPE_IND,
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
//.peer_addr =
//.peer_addr_type =
.channel_map = ADV_CHNL_ALL,
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
// Wi-Fi连接事件组
static EventGroupHandle_t s_wifi_event_group;
#define WIFI_CONNECTED_BIT BIT0
// 保存接收到的数据
#define MAX_DATA_LEN 512
static char received_data[MAX_DATA_LEN] = {
0};
static int received_len = 0;
// Wi-Fi和TCP信息
static char g_wifi_ssid[32] = {
0};
static char g_wifi_pass[64] = {
0};
static char g_tcp_ip[16] = {
0};
static int g_tcp_port = 0;
// NVS命名空间
#define STORAGE_NAMESPACE "storage"
// 函数声明
void wifi_init_sta(void);
void tcp_start(void);
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
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);
// 配置BLE回调
static esp_gatts_attr_db_t gatt_db[GATTS_NUM_HANDLE] =
{
// 服务声明
[0] = {
{
ESP_GATT_AUTO_RSP},
{
ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ,
sizeof(uint16_t), sizeof(GATTS_SERVICE_UUID), (uint8_t *)&GATTS_SERVICE_UUID}
},
/* 特征声明 */
[1] = {
{
ESP_GATT_AUTO_RSP},
{
ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
sizeof(uint8_t), sizeof(uint8_t), (uint8_t *)&char_prop_write_notify}
},
/* 特征值 */
[2] = {