从WiFi到BLE:ESP32全模块代码片段实战指南

从WiFi到BLE:ESP32全模块代码片段实战指南

引言:解决ESP32开发的痛点

你是否还在为ESP32开发中的WiFi连接、BLE通信、I2C设备交互等基础功能编写重复代码?是否希望有一个一站式资源库,能够快速找到经过验证的代码片段?ESP32-Snippets项目正是为解决这些问题而生。本文将详细介绍这个项目的结构、核心功能模块,并通过丰富的代码示例和实战教程,帮助你轻松掌握ESP32开发的关键技术点。

读完本文,你将能够:

  • 快速理解ESP32-Snippets项目的组织结构
  • 掌握WiFi、BLE、I2C等核心模块的使用方法
  • 直接应用项目中的代码片段到自己的项目中
  • 解决常见的ESP32开发难题

项目概述

ESP32-Snippets是一个包含各种ESP32代码片段和示例的开源项目,旨在为开发者提供可直接复用的代码模块。项目涵盖了从基础外设交互到高级网络通信的多个方面,是ESP32开发的宝贵资源。

项目结构

mermaid

项目获取

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连接流程

mermaid

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通信流程

mermaid

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测试
    └── ...

如何扩展项目

  1. 添加新模块:在cpp_utils目录下创建新的类文件
  2. 添加硬件驱动:在hardware目录下添加相应的驱动代码
  3. 编写测试用例:在tests目录下添加测试代码
  4. 更新文档:完善README和相关注释

总结与展望

ESP32-Snippets项目为ESP32开发者提供了丰富的代码片段和工具类,涵盖了从基础外设到高级网络通信的各个方面。通过本文的介绍,你应该能够快速上手并应用这些代码片段到自己的项目中,提高开发效率。

未来,该项目可以进一步扩展:

  • 添加更多传感器和外设的支持
  • 优化现有代码,提高性能和稳定性
  • 增加对最新ESP-IDF版本的支持
  • 提供更丰富的示例项目

资源与互动

如果觉得本文对你有帮助,请点赞、收藏并关注作者获取更多ESP32开发资源。如有任何问题或建议,欢迎在评论区留言讨论。

下期预告:ESP32低功耗项目实战指南——电池供电设备的优化技巧。


项目地址:https://gitcode.com/gh_mirrors/es/esp32-snippets
贡献指南:欢迎提交PR和Issue,一起完善这个ESP32开发资源库。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值