1. 课程导入

各位同学,欢迎来到《ESP32 I2C传感器驱动与数据采集开发实战》的第一章。

做嵌入式开发这些年,我越来越觉得I2C是个好东西。它只需要两根线,就能挂一堆传感器。你想想看,一个ESP32,接上温湿度、气压、加速度计,总共才用两个IO口。这性价比,没谁了。

这一章,我们先打好基础。把开发板、协议、传感器选型、接线、环境搭建这些事儿捋清楚。后面写驱动的时候,你才不会手忙脚乱。

1.1 ESP32开发板:为什么选它?

ESP32是乐鑫科技推出的双核MCU,带Wi-Fi和蓝牙。我最早用ESP8266做项目,后来换成ESP32,感觉就像从自行车换成了摩托车。性能翻倍,外设接口也多了不少。

具体到I2C这块,ESP32有两个硬件I2C控制器。你可以同时跑两路I2C总线,一路接高速传感器,一路接低速传感器。互不干扰。

参数 ESP32 备注
CPU 双核 Xtensa LX6,最高240MHz 够用
I2C控制器 2个 可同时使用
I2C速率 标准模式100kHz / 快速模式400kHz 大部分传感器够用
GPIO 任意引脚可映射为SCL/SDA 布线灵活
工作电压 3.3V 注意传感器电平匹配
我的习惯: 做原型阶段,我一般用ESP32-DevKitC或者NodeMCU-32S。便宜、好买、资料多。量产时再根据需求换模组。

1.2 I2C协议基础:两根线的艺术

I2C,全称Inter-Integrated Circuit。说白了,就是飞利浦当年搞出来让芯片之间聊天的协议。

它只有两根线:

  • SCL(串行时钟线) — 由主机控制,产生时钟脉冲
  • SDA(串行数据线) — 双向数据线,主机和从机都能拉

这两根线都是开漏输出,所以必须接上拉电阻。我见过不少新手,焊好板子发现通信不了,查了半天,结果是忘了加上拉电阻。

我曾经踩过的坑: 有一次用ESP32接BMP280,死活读不到数据。示波器一看,SCL波形像条毛毛虫。最后发现是上拉电阻用了10kΩ,线又长了点,上升沿太慢。换成4.7kΩ,问题解决。记住:线越长、速率越高,上拉电阻就要越小。

I2C的通信流程,其实就这几步:

  1. 主机发送起始条件(SCL高电平时,SDA从高变低)
  2. 主机发送7位从机地址 + 1位读写位
  3. 从机应答(拉低SDA)
  4. 数据传输(每字节后跟一个应答位)
  5. 主机发送停止条件(SCL高电平时,SDA从低变高)

嗯,流程不复杂。但有个细节要注意:地址是7位的,但很多数据手册会把地址写成8位(左移一位后的值)。你写代码时一定要看清楚。

I2C 单次通信完整时序流程 起始条件 地址+读写位 从机应答 数据字节 停止条件 注意:每次通信都以起始条件开始,以停止条件结束。 从机应答是拉低SDA,如果从机没拉低,说明地址不对或设备没准备好。 SCL与SDA波形示意 SCL SDA 起始 地址(7位) R/W 数据(8位) 停止

1.3 常用I2C传感器选型

市面上I2C传感器多得让人眼花。我挑几个课程里会用到的,也是我项目里用得最多的:

传感器 测量内容 I2C地址 工作电压 精度
SHT30 温湿度 0x44 / 0x45 2.4V - 5.5V ±0.3°C / ±2%RH
BMP280 气压、温度 0x76 / 0x77 1.8V - 3.6V ±1hPa
MPU6050 加速度、陀螺仪 0x68 2.4V - 3.6V 16位ADC
选型建议: 新手入门,我强烈建议从SHT30开始。它简单、稳定、资料多。等你把SHT30的驱动调通了,再搞BMP280和MPU6050,会顺手很多。

说个我自己的经历。有一次做环境监测节点,选了SHT30和BMP280。两个传感器挂同一条I2C总线上,地址不冲突。代码写起来很顺,数据也稳定。后来客户要加姿态检测,我又加了MPU6050。三个传感器,两根线,搞定。

1.4 硬件接线

接线其实很简单。但越简单的事,越容易出错。

标准接法:

  • ESP32的GPIO21 → SCL(所有传感器的SCL并在一起)
  • ESP32的GPIO22 → SDA(所有传感器的SDA并在一起)
  • VCC → 3.3V(注意传感器的工作电压范围)
  • GND → GND(共地!共地!共地!)
  • SCL和SDA各接一个4.7kΩ上拉电阻到3.3V
重要提醒: 有些传感器模块自带上拉电阻,比如GY-521(MPU6050模块)。如果你再外加一个,相当于两个电阻并联,阻值会变小。我建议你先查一下模块原理图,再决定要不要外加。

ESP32的I2C引脚是可以任意映射的。你不一定非要用GPIO21和22。比如我有个项目,GPIO21和22被其他外设占了,我就把I2C映射到了GPIO16和17。代码里改一下引脚号就行。

1.5 开发环境搭建

课程里我会用两种环境:Arduino IDE和ESP-IDF。你选一个就行。

1.5.1 Arduino IDE(推荐新手)

Arduino IDE上手快,库多。我最早接触ESP32就是用Arduino IDE。

步骤:

  1. 下载安装Arduino IDE(官网直接下)
  2. 打开IDE,进入 文件 → 首选项 → 附加开发板管理器网址
  3. 填入:https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  4. 工具 → 开发板 → 开发板管理器,搜索ESP32,安装
  5. 选择开发板:工具 → 开发板 → ESP32 Arduino → ESP32 Dev Module

装好后,写个简单的I2C扫描程序测试一下:

#include <Wire.h>

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);  // SDA=21, SCL=22
  Serial.println("I2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices = 0;
  
  for(address = 1; address < 127; address++ ) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) {
      Serial.print("Found at 0x");
      if (address < 16) Serial.print("0");
      Serial.println(address, HEX);
      nDevices++;
    }
  }
  if (nDevices == 0) Serial.println("No devices found");
  delay(5000);
}
我的习惯: 每次焊好新板子,第一件事就是跑这个扫描程序。确认所有传感器的I2C地址都能读到,再开始写驱动。这能帮你快速排除接线问题。

1.5.2 ESP-IDF(进阶选择)

如果你要做产品,我建议用ESP-IDF。它更底层,控制力更强,资源占用也更小。

安装步骤:

  1. 去乐鑫官网下载ESP-IDF安装器(Windows)或使用命令行(Linux/Mac)
  2. 运行安装脚本,选择目标版本(建议用最新的稳定版)
  3. 设置环境变量:export IDF_PATH=~/esp/esp-idf
  4. 创建工程:cp -r $IDF_PATH/examples/peripherals/i2c/i2c_simple .
  5. 配置:idf.py menuconfig → 设置I2C引脚和速率
  6. 编译烧录:idf.py build flash monitor

ESP-IDF的I2C驱动API比Arduino复杂一些,但功能更全。比如支持DMA传输、支持多主机模式。这些高级功能,我们后面章节会讲到。

我的建议: 如果你刚开始学,先用Arduino IDE。把I2C通信的逻辑搞明白。等你觉得Arduino IDE限制你了,再切到ESP-IDF。不要一上来就啃IDF,容易劝退。

1.6 本章小结

这一章我们聊了:

  • ESP32为什么适合做I2C传感器采集
  • I2C协议的核心流程:起始、地址、应答、数据、停止
  • 三款常用传感器的选型对比
  • 硬件接线要点和上拉电阻的选择
  • Arduino IDE和ESP-IDF两种开发环境的搭建

嗯,内容不少。但这些都是基本功。后面每一章都会用到这些知识。

我建议你花点时间,把开发环境搭好,把传感器接好,跑通那个I2C扫描程序。当你看到串口输出"Found at 0x44"的时候,你就知道,硬件没问题了。