3、ESP32基础:芯片特性、开发板类型、GPIO、ADC、I2C、WiFi、蓝牙等核心资源

在老人看护场景中,ESP32之所以成为首选主控,是因为它在一颗芯片上集成了双核处理器、WiFi、蓝牙、丰富的模拟与数字外设,并且功耗可控、价格低廉。理解ESP32的硬件资源边界,是后续实现久坐检测(依赖ADC与GPIO)、跌倒风险判断(依赖IMU传感器与I2C总线)以及远程提醒(依赖WiFi/蓝牙通信)的基石。本节将系统梳理ESP32的芯片特性、常见开发板选型、GPIO/ADC/I2C等核心外设的使用要点,并结合老人看护项目给出具体的资源分配建议。

ESP32-WROOM-32 双核 Xtensa LX6 @240MHz WiFi 802.11 b/g/n + BLE 4.2 SRAM 520KB / Flash 4MB 数字输入/输出 GPIO 0-39 (34个可编程) PWM / 中断 / 编码器 用于按键、LED、蜂鸣器 模拟输入 ADC1: 8通道 12位 ADC2: 10通道 (WiFi冲突) 用于压力/电池/光敏检测 通信接口 I2C / SPI / UART / CAN 连接IMU/OLED/外部MCU WiFi 通信 STA/AP/混杂模式 MQTT/HTTP/WebSocket 远程提醒与数据上报 蓝牙 BLE 低功耗广播/连接 室内定位/手环联动 本地提醒(无需WiFi) 电源管理 3.3V LDO / 深度睡眠 ULP协处理器 老人看护核心资源映射:GPIO→按键/蜂鸣器,ADC→坐垫压力,I2C→IMU/OLED,WiFi→远程提醒

上图展示了ESP32在老人看护项目中的核心资源分布。左侧为传感器与执行器接口,右侧为通信与电源管理模块,中央为芯片本体。在实际项目中,我们需要根据外设的电气特性和通信协议,合理分配GPIO、ADC和I2C资源,避免冲突(例如ADC2与WiFi不能同时使用)。下面从芯片特性开始逐一展开。

3.1 芯片特性与开发板选型

ESP32系列由乐鑫(Espressif)推出,目前主流型号包括经典ESP32(WROOM-32)、ESP32-S3、ESP32-C3等。对于老人看护场景,ESP32-WROOM-32 是最稳妥的选择,因为它拥有最多的GPIO(34个可编程)、双核240MHz主频、520KB SRAM,且社区资料丰富。ESP32-C3是单核RISC-V架构,功耗更低但GPIO较少,适合极简传感器节点;ESP32-S3增加了AI加速指令,适合需要本地语音识别的场景,但价格略高。

开发板型号核心/主频GPIO数量ADC通道适用场景
ESP32-WROOM-32双核 240MHz3418 (ADC1+ADC2)综合看护节点(推荐)
ESP32-S3-WROOM-1双核 240MHz + AI4520需要语音/图像识别
ESP32-C3-MINI-1单核 160MHz226低功耗简单传感器
ESP32-PICO-D4双核 240MHz3418极小体积穿戴设备

开发板选择上,NodeMCU-32S 和 ESP32-DevKitC 是最常见的两种。NodeMCU-32S自带USB转串口芯片(CP2102或CH340),直接插线即可烧录,适合快速原型验证;DevKitC则更接近官方参考设计,引脚标注清晰,适合教学和调试。无论选择哪款,务必确认板载稳压器输出电流≥500mA,因为WiFi发射瞬间电流可达300-400mA,若供电不足会导致反复重启。

经验提醒:在老人看护项目中,建议优先选用ESP32-WROOM-32 + NodeMCU-32S开发板。原因有三:一是GPIO充足,可同时连接IMU(I2C)、压力传感器(ADC)、OLED屏(I2C)和蜂鸣器(GPIO);二是社区例程多,遇到问题容易搜索到解决方案;三是价格约20-30元,即使损坏更换成本低。

3.2 GPIO:数字输入输出与中断

GPIO(General Purpose Input/Output)是ESP32与外界交互的最基本方式。在老人看护场景中,GPIO主要用于:读取跌倒检测按钮(数字输入)、驱动蜂鸣器报警(数字输出)、控制LED指示灯(PWM输出)、读取门磁传感器(中断触发)。ESP32的GPIO支持多种功能复用,但需要注意以下几点:

  • 输入模式:可配置为浮空输入、上拉输入或下拉输入。对于按键,建议使用上拉输入(内部上拉电阻约45kΩ),按键另一端接地,按下时读到低电平。
  • 输出模式:推挽输出可驱动LED(串联220Ω限流电阻)或蜂鸣器(需三极管或MOS管驱动,因为GPIO最大输出电流约40mA)。
  • 中断触发:支持上升沿、下降沿、低电平、高电平触发。跌倒检测按钮应使用下降沿触发,并配合软件消抖(延时20-50ms再确认)。
  • PWM输出:所有GPIO均可输出PWM信号,用于LED呼吸灯或蜂鸣器音调控制。ESP32的LEDC控制器提供16个通道,频率可调(1Hz-40MHz)。
// GPIO按键输入 + 中断示例(Arduino框架)
const int buttonPin = 4;  // GPIO4 连接跌倒按钮
volatile bool fallDetected = false;

void IRAM_ATTR isr() {
  fallDetected = true;  // 中断服务函数中只置标志位
}

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPin), isr, FALLING);
}

void loop() {
  if (fallDetected) {
    delay(50);  // 软件消抖
    if (digitalRead(buttonPin) == LOW) {
      // 确认跌倒,触发报警流程
      activateAlarm();
    }
    fallDetected = false;
  }
}
风险提示:GPIO 6-11在大多数ESP32模块上连接到外部Flash,不能作为普通IO使用。GPIO 34-39只能作为输入,不能输出。在分配引脚时,务必避开这些特殊引脚,否则会导致程序无法烧录或运行异常。

3.3 ADC:模拟信号采集与压力检测

ADC(模数转换器)用于将模拟电压转换为数字值。在老人看护中,ADC最典型的应用是坐垫压力检测——通过薄膜压力传感器(FSR)感知老人是否长时间坐在椅子上。ESP32内置两个ADC:ADC1(8通道,GPIO32-39)和ADC2(10通道,GPIO0-27)。关键限制:ADC2与WiFi不能同时使用,因为WiFi模块会占用ADC2的采样时钟。因此,所有模拟传感器必须连接到ADC1通道。

ADC的精度为12位(0-4095),默认测量范围0-3.3V。但实际使用时,建议将测量范围限制在0-2.5V,因为ESP32的ADC在接近满量程时线性度会下降。若需测量更高电压,需外接分压电阻。对于压力传感器,典型接法为:FSR一端接3.3V,另一端串联10kΩ下拉电阻到GND,中间节点接ADC引脚。当压力增大时,FSR阻值减小,ADC电压升高。

ADC通道GPIO引脚推荐用途注意事项
ADC1_CH0GPIO36坐垫压力传感器只能输入
ADC1_CH3GPIO39电池电压监测需分压电阻
ADC1_CH4GPIO32环境光传感器用于夜间模式
ADC1_CH5GPIO33备用/扩展避免与I2C冲突
// ADC读取压力传感器示例
#define PRESSURE_PIN 36  // ADC1_CH0

void setup() {
  Serial.begin(115200);
  analogReadResolution(12);  // 设置12位精度
  analogSetPinAttenuation(PRESSURE_PIN, ADC_11db);  // 衰减11dB,量程约3.3V
}

void loop() {
  int raw = analogRead(PRESSURE_PIN);
  float voltage = raw * (3.3f / 4095.0f);
  // 根据电压值估算压力等级
  if (voltage > 2.0f) {
    // 有人坐在椅子上
    Serial.println("Occupied");
  } else {
    Serial.println("Empty");
  }
  delay(1000);
}
核心原理:ADC的采样值受供电电压波动影响。当WiFi发射时,系统电流增大,3.3V电压可能跌落0.1-0.2V,导致ADC读数漂移。解决方案:在软件中对ADC读数做滑动平均滤波(取10次采样平均值),并在关键阈值判断时加入滞回区间(例如压力阈值设为1.8V-2.2V之间),避免临界抖动。

3.4 I2C:连接IMU与外部传感器

I2C(Inter-Integrated Circuit)是一种两线制同步串行总线,使用SDA(数据线)和SCL(时钟线)连接多个设备。在老人看护场景中,I2C主要用于连接IMU惯性测量单元(如MPU6050/MPU9250)来检测跌倒姿态,以及连接OLED显示屏(如SSD1306)显示状态信息。ESP32的I2C接口通过软件配置,可使用任意GPIO作为SDA/SCL,但推荐使用默认引脚:SDA=GPIO21,SCL=GPIO22。

I2C通信速率支持100kHz(标准模式)和400kHz(快速模式)。对于IMU数据读取,建议使用400kHz以降低延迟。每个I2C设备有7位地址,MPU6050的地址为0x68(AD0接地)或0x69(AD0接VCC)。在连接多个设备时,需确保地址不冲突,且总线上拉电阻(通常4.7kΩ到3.3V)已正确安装。

// I2C扫描设备地址示例
#include <Wire.h>

void setup() {
  Wire.begin(21, 22);  // SDA=GPIO21, SCL=GPIO22
  Serial.begin(115200);
  Serial.println("Scanning I2C bus...");
  for (byte addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    if (Wire.endTransmission() == 0) {
      Serial.print("Found device at 0x");
      Serial.println(addr, HEX);
    }
  }
}

void loop() { }

在跌倒检测应用中,IMU通过I2C以100Hz频率输出加速度和角速度数据。ESP32作为I2C主机,需要配置时钟速率为400kHz,并在每次读取时先发送设备地址和寄存器地址,再读取6字节数据(加速度X/Y/Z各2字节)。由于I2C是半双工通信,读取过程中CPU会阻塞等待,因此建议使用DMA或任务调度来避免阻塞主循环。

工程实践:当I2C总线上同时挂载IMU和OLED时,建议在初始化时先扫描总线确认设备地址,再分别初始化。若OLED显示异常,优先检查SDA/SCL是否接反、上拉电阻是否缺失。另外,I2C线长超过20cm时,应降低速率至100kHz并增加上拉电阻至2.2kΩ。

3.5 WiFi与蓝牙:远程提醒的通信基础

WiFi和蓝牙是ESP32区别于普通单片机的核心优势。在老人看护系统中,WiFi用于将报警信息发送到云端或家属手机,蓝牙则用于近距离设备联动(如连接蓝牙手环)。ESP32的WiFi支持802.11 b/g/n,工作频率2.4GHz,最大发射功率20dBm(100mW)。在室内环境下,WiFi覆盖范围约30-50米,穿墙后信号衰减明显。

WiFi工作模式有三种:Station(STA)——连接路由器;Access Point(AP)——自身作为热点;混杂模式——同时作为STA和AP。在老人看护场景中,推荐使用STA模式连接家庭路由器,通过MQTT协议上报数据。若家庭网络不稳定,可启用AP模式作为备用,让家属手机直接连接ESP32查看状态。

蓝牙方面,ESP32支持经典蓝牙(BR/EDR)和低功耗蓝牙(BLE 4.2)。BLE功耗更低,适合周期性广播状态信息。例如,ESP32每5秒广播一次“老人当前状态”(坐姿/站立/跌倒),家属手机上的APP通过扫描广播包即可获取信息,无需建立连接,功耗极低。

通信方式功耗延迟适用场景注意事项
WiFi STA + MQTT高(平均80mA)1-3秒远程报警、数据上报需路由器,断网需重连
WiFi AP高(平均100mA)即时现场调试、应急直连手机需切换WiFi网络
BLE 广播低(平均20mA)1-5秒近距离状态同步单向通信,无法接收指令
BLE 连接中(平均40mA)10-50ms手环联动、参数配置需配对,连接稳定
// WiFi连接 + MQTT上报示例(使用PubSubClient库)
#include <WiFi.h>
#include <PubSubClient.h>

const char* ssid = "Home_WiFi";
const char* password = "password123";
const char* mqttServer = "192.168.1.100";
const int mqttPort = 1883;

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
  client.setServer(mqttServer, mqttPort);
  client.connect("ESP32_Care_Node");
}

void loop() {
  if (!client.connected()) {
    client.connect("ESP32_Care_Node");
  }
  client.loop();
  // 检测到跌倒时发布消息
  if (fallDetected) {
    client.publish("care/alert", "FALL_DETECTED");
  }
}
风险提示:WiFi连接失败或断线是老人看护系统最常见的故障点。务必在代码中实现自动重连机制,并设置看门狗定时器(WDT)防止死机。同时,MQTT服务器应支持遗嘱消息(LWT),当ESP32异常离线时,服务器能自动发布“设备离线”告警。

3.6 资源分配与常见误区

在综合老人看护项目中,合理的引脚分配能避免后期调试的诸多麻烦。以下是一个经过验证的资源分配方案:

  • GPIO4:跌倒检测按钮(输入+中断)
  • GPIO5:蜂鸣器驱动(PWM输出)
  • GPIO21/22:I2C总线(IMU + OLED)
  • GPIO36:坐垫压力传感器(ADC1_CH0)
  • GPIO39:电池电压监测(ADC1_CH3)
  • GPIO2:板载LED(状态指示)
  • GPIO15:预留(可接门磁传感器)

常见误区包括:

  1. 误用ADC2通道:当WiFi开启时,ADC2读数会随机跳变。所有模拟信号必须接ADC1。
  2. 忽略GPIO上电状态:某些GPIO(如GPIO0、GPIO2、GPIO15)在启动时有特殊功能(下载模式、Flash电压选择等),若外部电路影响这些引脚的电平,可能导致无法正常启动。
  3. I2C地址冲突:多个相同型号的传感器(如两个MPU6050)需要修改AD0引脚地址,否则无法同时工作。
  4. 供电不足:使用USB供电时,若同时开启WiFi和驱动蜂鸣器,可能导致电压跌落至3.0V以下,系统重启。建议使用5V/2A电源适配器或锂电池+稳压模块。
总结复盘:ESP32的资源丰富但并非无限,在老人看护项目中应遵循“先规划、后接线、再编程”的原则。建议在硬件设计阶段就绘制一张引脚分配表,标注每个GPIO的功能、方向、电气特性。在软件层面,使用条件编译区分调试模式和正式模式,方便现场排查。最后,务必在原型阶段进行72小时连续运行测试,重点观察WiFi稳定性、ADC漂移和I2C通信可靠性,确保系统在真实环境中长期稳定运行。