1. ESP32 与 Arduino 开发环境

ESP32 集成了双核 Tensilica LX6 处理器(主频可达 240MHz)、WiFi 802.11 b/g/n、双模蓝牙(经典 + BLE)以及丰富的外设接口。使用 Arduino 框架可以大幅降低开发门槛,但底层仍是 FreeRTOS 实时的多线程调度。

Arduino Core 安装步骤

  • 打开 Arduino IDE,进入“文件 -> 首选项”,在“附加开发板管理器网址”中添加:https://espressif.github.io/arduino-esp32/package_esp32_index.json
  • 打开“工具 -> 开发板 -> 开发板管理器”,搜索“esp32”,安装最新版(建议 2.x 以上)。
  • 选择开发板型号(如 ESP32 Dev Module),确认 USB 驱动(CP2102/CH340)已安装。

2. WiFi 功能详解

ESP32 的 WiFi 支持三种模式:STA(站)、AP(热点)、AP+STA 共存。所有功能基于 WiFi.h 库,核心初始化流程为:

#include <WiFi.h>

const char* ssid = "YourSSID";
const char* password = "YourPassword";

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnected! IP: " + WiFi.localIP().toString());
}

void loop() {
  // 周期检查连接状态,若断开则重连
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.reconnect();
  }
  delay(10000);
}

扫描与热点创建

  • 扫描:WiFi.scanNetworks() 返回可见 AP 数量,之后用 WiFi.SSID(i)WiFi.RSSI(i) 获取信息。
  • 开启热点:
WiFi.mode(WIFI_AP);
WiFi.softAP("ESP32_AP", "12345678", 1, 0);  // 1为通道号,0为隐藏
Serial.println(WiFi.softAPIP());

注意:ESP32 的 WiFi 仅支持 2.4GHz,且天线增益有限,长距离传输需外置功放或采用 ESP32-PICO 系列。

3. 蓝牙功能详解

ESP32 同时支持经典蓝牙(BR/EDR)和低功耗蓝牙(BLE)。经典蓝牙适合串口透传,而 BLE 适合低功耗传感器/手机交互。

3.1 经典蓝牙串口透传

使用 BluetoothSerial 库即可快速将 UART 数据转换为蓝牙无线串口:

#include "BluetoothSerial.h"

BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP32_Bluetooth"); // 设备名称
  Serial.println("Bluetooth started, pair with your phone!");
}

void loop() {
  if (SerialBT.available()) {
    char c = SerialBT.read();
    Serial.write(c);  // 转发到硬件串口
  }
  if (Serial.available()) {
    SerialBT.write(Serial.read());
  }
  delay(1);
}

3.2 BLE 服务与特征值

使用 BLEDevice 库,核心概念:GATT Server 中包含 Service,Service 中包含 Characteristic。创建一个可读可写的 BLE 服务:

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;

class MyServerCallbacks : public BLEServerCallbacks {
  void onConnect(BLEServer* server) { deviceConnected = true; };
  void onDisconnect(BLEServer* server) { deviceConnected = false; };
};

class MyCharCallbacks : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pChar) {
    std::string value = pChar->getValue();
    if (value.length() > 0) {
      Serial.print("Received: ");
      Serial.println(value.c_str());
    }
  }
};

void setupBLE(const char* deviceName) {
  BLEDevice::init(deviceName);
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  
  BLEService *pService = pServer->createService("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
  pCharacteristic = pService->createCharacteristic(
    "beb5483e-36e1-4688-b7f5-ea07361b26a8",
    BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE
  );
  pCharacteristic->setCallbacks(new MyCharCallbacks());
  pCharacteristic->setValue("Hello from ESP32");
  pService->start();
  
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(pService->getUUID());
  BLEDevice::startAdvertising();
}

4. 综合示例:WiFi + BLE 共存

由于 WiFi 与蓝牙共享同一个射频前端,双模同时运行时需注意:

  • 硬件上可共存,但蓝牙速率会下降,尤其是 BLE 广播间隔需增大。
  • setup() 中先初始化 WiFi,再初始化 BLE,避免射频初始化冲突。
void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin("MySSID", "Password");
  while (WiFi.status() != WL_CONNECTED) delay(100);

  setupBLE("ESP32_BLE");
  Serial.println("WiFi + BLE 运行中");
}

5. 注意事项与常见坑

  • 电源电流:ESP32 开启 WiFi 时峰值电流可达 500mA,务必使用 3.3V LDO(如 AMS1117)或 5V 供电,并加 10~100uF 去耦电容。
  • GPIO 限制:GPIO 0、2、12、15 有上拉/下拉或 JTAG 功能,避免用于高速信号;GPIO 36~39 仅输入。
  • Flash 分区:若 OTA 或存储需求大,使用 tools/partitions 中的自定义 CSV 分区表。
  • FreeRTOS:Arduino 的 loop() 运行在 core 0 的 low-priority task 中,耗时的 WiFi/BLE 操作不要阻塞过长,建议使用 xTaskCreatePinnedToCore() 分配任务。
  • 频段合规:不同国家/地区的 WiFi 信道和蓝牙功率有法规限制,量产需进行认证(如 FCC/CE)。

ESP32 强大的无线能力配合 Arduino 的易用性,能让你快速将创意原型落地。深入理解透 WiFi 协议栈和 BLE 的 GATT 结构,是实现复杂物联网应用的关键。