从WiFi到BLE:ESP32全模块代码片段实战指南
引言:解决ESP32开发的痛点
你是否还在为ESP32开发中的WiFi连接、BLE通信、I2C设备交互等基础功能编写重复代码?是否希望有一个一站式资源库,能够快速找到经过验证的代码片段?ESP32-Snippets项目正是为解决这些问题而生。本文将详细介绍这个项目的结构、核心功能模块,并通过丰富的代码示例和实战教程,帮助你轻松掌握ESP32开发的关键技术点。
读完本文,你将能够:
- 快速理解ESP32-Snippets项目的组织结构
- 掌握WiFi、BLE、I2C等核心模块的使用方法
- 直接应用项目中的代码片段到自己的项目中
- 解决常见的ESP32开发难题
项目概述
ESP32-Snippets是一个包含各种ESP32代码片段和示例的开源项目,旨在为开发者提供可直接复用的代码模块。项目涵盖了从基础外设交互到高级网络通信的多个方面,是ESP32开发的宝贵资源。
项目结构
项目获取
git clone https://gitcode.com/gh_mirrors/es/esp32-snippets.git
cd esp32-snippets
核心功能模块详解
1. WiFi模块
WiFi模块提供了简单易用的ESP32无线网络连接功能,支持STA模式(连接到AP)和AP模式(作为接入点)。
主要功能
- 快速连接到WiFi网络
- 配置静态IP地址
- 扫描可用WiFi网络
- 创建WiFi接入点
连接WiFi示例
#include <WiFi.h>
void connectToWiFi() {
WiFi wifi;
// 连接到指定的SSID和密码
uint8_t connectionStatus = wifi.connectAP("你的SSID", "你的密码");
if (connectionStatus == ESP_OK) {
ESP_LOGI("WiFi", "连接成功");
ESP_LOGI("WiFi", "IP地址: %s", wifi.getStaIp().c_str());
ESP_LOGI("WiFi", "子网掩码: %s", wifi.getStaNetmask().c_str());
ESP_LOGI("WiFi", "网关: %s", wifi.getStaGateway().c_str());
} else {
ESP_LOGE("WiFi", "连接失败,错误代码: %d", connectionStatus);
}
}
WiFi连接流程
2. BLE模块
蓝牙低功耗(BLE)模块提供了完整的BLE协议栈实现,支持作为BLE服务器和客户端,可用于设备间近距离通信。
主要功能
- 创建BLE服务器,提供服务和特征
- 作为BLE客户端,连接其他BLE设备
- 支持BLE广播和扫描
- 实现安全连接和数据加密
BLE服务器示例
#include "BLEDevice.h"
#include "BLEServer.h"
#include "BLEUtils.h"
#include "BLE2902.h"
void createBLEServer() {
// 初始化BLE设备
BLEDevice::init("ESP32-BLE-Server");
// 创建BLE服务器
BLEServer* pServer = BLEDevice::createServer();
// 创建BLE服务
BLEService* pService = pServer->createService("91bad492-b950-4226-aa2b-4ede9fa42f59");
// 创建BLE特征
BLECharacteristic* pCharacteristic = pService->createCharacteristic(
"0d563a58-196a-48ce-ace2-dfec78acc814",
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY
);
// 设置特征初始值
pCharacteristic->setValue("Hello BLE World!");
// 添加描述符
pCharacteristic->addDescriptor(new BLE2902());
// 启动服务
pService->start();
// 开始广播
BLEAdvertising* pAdvertising = pServer->getAdvertising();
pAdvertising->addServiceUUID(pService->getUUID());
pAdvertising->start();
ESP_LOGI("BLE", "BLE服务器已启动");
}
BLE客户端示例
#include "BLEDevice.h"
#include "BLEClient.h"
#include "BLEScan.h"
// 目标服务和特征UUID
static BLEUUID serviceUUID("91bad492-b950-4226-aa2b-4ede9fa42f59");
static BLEUUID charUUID("0d563a58-196a-48ce-ace2-dfec78acc814");
void connectToBLEServer() {
BLEDevice::init("");
// 创建扫描对象
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setActiveScan(true);
// 扫描10秒
BLEScanResults foundDevices = pBLEScan->start(10);
// 遍历扫描结果
for (int i = 0; i < foundDevices.getCount(); i++) {
BLEAdvertisedDevice device = foundDevices.getDevice(i);
// 检查是否包含目标服务
if (device.haveServiceUUID() && device.isAdvertisingService(serviceUUID)) {
// 创建客户端并连接
BLEClient* pClient = BLEDevice::createClient();
if (pClient->connect(&device)) {
ESP_LOGI("BLE", "连接成功");
// 获取服务和特征
BLERemoteService* pService = pClient->getService(serviceUUID);
if (pService) {
BLERemoteCharacteristic* pCharacteristic = pService->getCharacteristic(charUUID);
if (pCharacteristic) {
// 读取特征值
std::string value = pCharacteristic->readValue();
ESP_LOGI("BLE", "读取到的值: %s", value.c_str());
// 写入新值
pCharacteristic->writeValue("Hello from client");
}
}
// 断开连接
pClient->disconnect();
}
break;
}
}
}
BLE通信流程
3. I2C模块
I2C(Inter-Integrated Circuit)模块提供了与I2C设备通信的接口,可用于连接各种传感器、显示器等外设。
主要功能
- 初始化I2C总线
- 扫描总线上的设备
- 读写I2C设备寄存器
- 支持多设备通信
I2C扫描器示例
#include <I2C.h>
void scanI2CDevices() {
I2C i2c;
// 初始化I2C,使用默认引脚(SDA=25, SCL=26)
i2c.init(0, GPIO_NUM_25, GPIO_NUM_26);
ESP_LOGI("I2C", "开始扫描I2C设备...");
ESP_LOGI("I2C", "SDA引脚: %d, SCL引脚: %d", 25, 26);
ESP_LOGI("I2C", " 0 1 2 3 4 5 6 7 8 9 a b c d e f");
// 扫描地址范围0x03到0x77
for (uint8_t address = 0x03; address < 0x78; address++) {
if (address % 16 == 0) {
ESP_LOGI("I2C", "\n%.2x:", address);
}
// 检查设备是否存在
if (i2c.slavePresent(address)) {
ESP_LOGI("I2C", " %.2x", address);
} else {
ESP_LOGI("I2C", " --");
}
}
ESP_LOGI("I2C", "\n扫描完成");
}
I2C设备通信示例
#include <I2C.h>
// 假设连接了一个地址为0x48的ADC设备
#define ADC_ADDR 0x48
uint16_t readADC() {
I2C i2c;
i2c.init(ADC_ADDR, GPIO_NUM_25, GPIO_NUM_26);
// 开始I2C事务
i2c.beginTransaction();
// 发送读取命令
uint8_t cmd = 0x00; // 假设0x00是读取命令
i2c.write(&cmd, 1);
// 读取2字节数据
uint8_t data[2];
i2c.read(data, 2);
// 结束事务
i2c.endTransaction();
// 处理数据
return (data[0] << 8) | data[1];
}
常用外设接口
1. 传感器
ESP32-Snippets提供了多种传感器的接口代码,包括温度传感器、加速度传感器等。
MPU6050加速度传感器示例
#include <MPU6050.h>
void readMPU6050() {
MPU6050 mpu;
// 初始化传感器
if (!mpu.init()) {
ESP_LOGE("MPU6050", "初始化失败");
return;
}
// 读取数据
float ax, ay, az;
float gx, gy, gz;
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
ESP_LOGI("MPU6050", "加速度: %.2f, %.2f, %.2f g", ax, ay, az);
ESP_LOGI("MPU6050", "角速度: %.2f, %.2f, %.2f °/s", gx, gy, gz);
}
2. 显示器
项目中包含多种显示器的驱动代码,如OLED、LCD等。
SSD1306 OLED示例
#include <U8G2.h>
// 创建显示器对象,使用I2C接口
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
void initOLED() {
u8g2.begin();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0, 10, "Hello ESP32!");
u8g2.drawStr(0, 30, "OLED Display");
u8g2.drawStr(0, 50, "128x64 pixels");
u8g2.sendBuffer();
}
网络通信
1. HTTP客户端
RESTClient提供了简单的HTTP请求功能,可用于与Web服务交互。
#include <RESTClient.h>
void httpRequestExample() {
RESTClient client;
// 设置请求URL
client.setURL("http://httpbin.org/get");
// 发送GET请求
client.get();
// 获取响应
ESP_LOGI("HTTP", "状态码: %d", client.getResponseCode());
ESP_LOGI("HTTP", "响应内容: %s", client.getResponse().c_str());
}
2. MQTT客户端
PubSubClient模块实现了MQTT协议,可用于连接MQTT服务器。
#include <PubSubClient.h>
#include <WiFi.h>
WiFi wifi;
PubSubClient mqttClient;
void onMqttMessage(char* topic, byte* payload, unsigned int length) {
ESP_LOGI("MQTT", "收到消息: %s", topic);
ESP_LOGI("MQTT", "内容: %.*s", length, payload);
}
void connectMQTT() {
// 连接WiFi
wifi.connectAP("SSID", "PASSWORD");
// 设置MQTT服务器和回调函数
mqttClient.setServer("mqtt.example.com", 1883);
mqttClient.setCallback(onMqttMessage);
// 连接MQTT服务器
if (mqttClient.connect("ESP32-Client")) {
ESP_LOGI("MQTT", "连接成功");
mqttClient.subscribe("esp32/test");
mqttClient.publish("esp32/status", "online");
} else {
ESP_LOGE("MQTT", "连接失败, error code: %d", mqttClient.state());
}
}
void loop() {
if (!mqttClient.connected()) {
connectMQTT();
}
mqttClient.loop();
}
项目实战案例
智能家居控制节点
以下是一个综合应用示例,结合WiFi、BLE和I2C功能,实现一个智能家居控制节点。
#include <WiFi.h>
#include <BLEDevice.h>
#include <I2C.h>
#include <PubSubClient.h>
#include <MPU6050.h>
// WiFi配置
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
// MQTT配置
const char* mqtt_server = "mqtt.example.com";
// 全局对象
WiFi wifi;
PubSubClient mqttClient;
I2C i2c;
MPU6050 mpu;
// BLE服务器配置
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
void setup() {
// 初始化I2C
i2c.init(0, GPIO_NUM_25, GPIO_NUM_26);
// 初始化MPU6050
mpu.init();
// 连接WiFi
wifi.connectAP(ssid, password);
// 初始化MQTT
mqttClient.setServer(mqtt_server, 1883);
mqttClient.setCallback(callback);
// 初始化BLE
BLEDevice::init("ESP32-Smart-Home");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setValue("ESP32 Smart Home Node");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
// 检查MQTT连接
if (!mqttClient.connected()) {
reconnect();
}
mqttClient.loop();
// 读取传感器数据
float ax, ay, az;
mpu.getAcceleration(&ax, &ay, &az);
// 发送数据到MQTT
char msg[50];
sprintf(msg, "{\"ax\":%.2f,\"ay\":%.2f,\"az\":%.2f}", ax, ay, az);
mqttClient.publish("esp32/sensor/mpu6050", msg);
// 延时
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
void callback(char* topic, byte* payload, unsigned int length) {
// 处理收到的MQTT消息
ESP_LOGI("MQTT", "收到消息: %s", topic);
// 解析 payload 并执行相应操作
// ...
}
void reconnect() {
// 重连MQTT
while (!mqttClient.connected()) {
String clientId = "ESP32-";
clientId += String(random(0xffff), HEX);
if (mqttClient.connect(clientId.c_str())) {
ESP_LOGI("MQTT", "连接成功");
mqttClient.subscribe("esp32/command");
} else {
ESP_LOGE("MQTT", "连接失败, rc=%d, 重试中...", mqttClient.state());
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
}
}
项目结构与扩展
项目目录结构
esp32-snippets/
├── BLE/ # BLE相关代码
├── cpp_utils/ # C++工具类
│ ├── BLEDevice.h # BLE设备类
│ ├── WiFi.h # WiFi类
│ ├── I2C.h # I2C类
│ └── ...
├── hardware/ # 硬件相关代码
│ ├── sensors/ # 传感器驱动
│ ├── displays/ # 显示器驱动
│ └── ...
├── networking/ # 网络相关代码
│ ├── MQTT/ # MQTT客户端
│ ├── HTTP/ # HTTP客户端
│ └── ...
└── tests/ # 测试代码
├── BLETests/ # BLE测试
├── I2CTests/ # I2C测试
└── ...
如何扩展项目
- 添加新模块:在cpp_utils目录下创建新的类文件
- 添加硬件驱动:在hardware目录下添加相应的驱动代码
- 编写测试用例:在tests目录下添加测试代码
- 更新文档:完善README和相关注释
总结与展望
ESP32-Snippets项目为ESP32开发者提供了丰富的代码片段和工具类,涵盖了从基础外设到高级网络通信的各个方面。通过本文的介绍,你应该能够快速上手并应用这些代码片段到自己的项目中,提高开发效率。
未来,该项目可以进一步扩展:
- 添加更多传感器和外设的支持
- 优化现有代码,提高性能和稳定性
- 增加对最新ESP-IDF版本的支持
- 提供更丰富的示例项目
资源与互动
如果觉得本文对你有帮助,请点赞、收藏并关注作者获取更多ESP32开发资源。如有任何问题或建议,欢迎在评论区留言讨论。
下期预告:ESP32低功耗项目实战指南——电池供电设备的优化技巧。
项目地址:https://gitcode.com/gh_mirrors/es/esp32-snippets
贡献指南:欢迎提交PR和Issue,一起完善这个ESP32开发资源库。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



