2、硬件连接:I2C 协议基础,传感器与树莓派/ESP32 的接线方法

好,咱们进入实战环节的第二课。

上一章我们把BMP280的来龙去脉讲清楚了。这一章,咱们得真刀真枪地把它连起来。说白了,就是让传感器和主控芯片“说上话”。

怎么连?靠的就是I2C协议。我个人习惯叫它“I方C”,也有人叫“I二C”,都行,知道是同一个东西就好。

2.1 什么是I2C?用大白话讲清楚

I2C,全称Inter-Integrated Circuit。名字挺唬人,其实原理很简单。

你想想看,如果只有一颗传感器,那直接一根线读数据就行。但气象站里往往有多个传感器:气压、温湿度、光照……每个都单独接线,树莓派那点GPIO口根本不够用。

I2C就是为了解决这个问题而生的。它只用两根线:

  • SDA(数据线):用来传数据,双向的。
  • SCL(时钟线):用来同步节奏,由主控(树莓派/ESP32)控制。

再加上电源和地,总共4根线,就能挂载最多127个设备。是不是很省?

我的经验: 我在一个农业大棚项目里,用一根I2C总线挂了6个BMP280和3个光照传感器。只要地址不冲突,跑得稳稳的。省下的GPIO口全用来控制继电器了。

2.2 I2C的工作流程(极简版)

I2C通信有点像老师点名:

  1. 起始信号:主控把SDA拉低,SCL保持高。相当于老师说“开始点名”。
  2. 发送地址:主控发出7位地址(比如BMP280的地址是0x76或0x77),再加1位读写位(0表示写,1表示读)。
  3. 从机应答:如果地址匹配,传感器会拉低SDA回应一声“到!”。
  4. 数据传输:主控或从机开始传数据,每传一个字节,接收方都要应答。
  5. 停止信号:主控拉高SDA,SCL保持高。点名结束。

嗯,这里要注意:时钟线SCL永远由主控控制。从机只能拉低SDA来应答或等待。

2.3 BMP280的I2C地址

BMP280的I2C地址取决于SDO引脚的电平:

SDO引脚电平 I2C地址(7位) 写地址 读地址
接GND(低电平) 0x76 0xEC 0xED
接VCC(高电平) 0x77 0xEE 0xEF
避坑指南: 我曾经在一个项目里,把两个BMP280的SDO都接了GND,结果地址冲突,一个都读不到。后来把其中一个SDO接VCC,地址改成0x77,问题解决。记住:同一总线上不能有两个相同地址的设备

2.4 硬件接线:树莓派版

树莓派的I2C引脚是固定的。以树莓派3B/4B为例:

  • 3.3V:接BMP280的VCC(注意!BMP280是3.3V器件,接5V会烧)
  • GND:接BMP280的GND
  • SDA(GPIO 2,物理引脚3):接BMP280的SDA
  • SCL(GPIO 3,物理引脚5):接BMP280的SCL
  • SDO:接GND(地址设为0x76)或接3.3V(地址设为0x77)
  • CSB:接3.3V(禁用SPI模式,只使用I2C)

接线图其实很简单,我一般这么记:

树莓派          BMP280
3.3V  -------- VCC
GND   -------- GND
GPIO2 -------- SDA
GPIO3 -------- SCL
GND   -------- SDO  (地址0x76)
3.3V  -------- CSB  (禁用SPI)
小技巧: 我习惯在SDA和SCL上各加一个4.7kΩ的上拉电阻到3.3V。虽然BMP280模块内部通常已经带了,但加一个更保险。尤其是线比较长的时候,上拉电阻能防止信号畸变。

2.5 硬件接线:ESP32版

ESP32的I2C引脚更灵活,可以任意指定。但为了方便,我通常用默认的:

  • 3.3V:接BMP280的VCC
  • GND:接BMP280的GND
  • GPIO 21(SDA):接BMP280的SDA
  • GPIO 22(SCL):接BMP280的SCL
  • SDO:接GND(地址0x76)
  • CSB:接3.3V

接线表:

ESP32            BMP280
3.3V  -------- VCC
GND   -------- GND
GPIO21 -------- SDA
GPIO22 -------- SCL
GND   -------- SDO
3.3V  -------- CSB
注意: ESP32的某些开发板(比如NodeMCU-32S)的3.3V输出能力有限。如果你同时给多个传感器供电,建议用外部稳压模块。我曾经因为供电不足,导致BMP280读数飘忽不定,排查了半天才发现是电压被拉低了。

2.6 验证连接:扫描I2C设备

接好线后,别急着写代码。先确认硬件连接是否正确。

树莓派上:

# 安装工具(如果没装)
sudo apt-get install i2c-tools

# 扫描I2C总线
sudo i2cdetect -y 1

如果看到 0x760x77,说明连接成功。

ESP32上(MicroPython):

from machine import Pin, I2C
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=100000)
devices = i2c.scan()
if devices:
    print("找到设备,地址:", [hex(addr) for addr in devices])
else:
    print("没找到设备,检查接线!")
我的习惯: 每次焊接或插拔后,我都会先跑一遍扫描程序。这能排除90%的硬件问题。如果扫描不到,先检查供电,再检查接线,最后检查地址是否冲突。

2.7 常见问题与排查

  • 扫描不到设备:检查VCC和GND是否接反,SDA/SCL是否接对,上拉电阻是否缺失。
  • 地址显示为0x00或0xFF:通常是SDA或SCL短路,或者上拉电阻没接。
  • 读数不稳定:可能是供电不足,或者线太长(超过20cm建议加屏蔽)。
  • 多个设备冲突:确保每个设备的I2C地址不同。BMP280只有两个可选地址,如果不够用,可以用I2C多路复用器(比如TCA9548A)。

好了,硬件连接就讲到这里。下一章,咱们开始写代码,让树莓派和ESP32真正把数据读出来。到时候你会发现,只要硬件连对了,代码其实就那么几行。