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通信有点像老师点名:
- 起始信号:主控把SDA拉低,SCL保持高。相当于老师说“开始点名”。
- 发送地址:主控发出7位地址(比如BMP280的地址是0x76或0x77),再加1位读写位(0表示写,1表示读)。
- 从机应答:如果地址匹配,传感器会拉低SDA回应一声“到!”。
- 数据传输:主控或从机开始传数据,每传一个字节,接收方都要应答。
- 停止信号:主控拉高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
如果看到 0x76 或 0x77,说明连接成功。
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真正把数据读出来。到时候你会发现,只要硬件连对了,代码其实就那么几行。