在本教程中,您将学习如何使用 TCA9458A 1 至 8 I2C 多路复用器扩展 I2C 总线端口(ESP32、ESP8266、Arduino)。如果要控制具有相同 I2C 地址的多个 I2C 设备,则此硬件非常有用。例如,多个OLED显示器,或多个传感器,如BME280。
![TCA9548A I2C 多路复用器教程:ESP32、ESP8266、Arduino](https://static.qutaojiao.com/wp-content/uploads/2023/12/Guide-TCA9548A-I2C-Multiplexer-ESP32-EP8266-Arduino.jpg)
本教程兼容 ESP32、ESP8266 和 Arduino 开发板。我们将使用 Arduino IDE 对电路板进行编程。
目录
在本教程中,我们将介绍以下主题:
- 介绍TCA9548A I2C多路复用器
- TCA9548A 多路复用器特性
- TCA9548A 多路复用器 I2C 地址
- TCA9548A引脚排列
- TCA9548A 多路复用器选择 I2C 总线
- 示例 1:连接多个 OLED 显示器
- 示例 2:连接多个 I2C 传感器 (BME280)
目录
介绍 TCA9548A 1 至 8 I2C 多路复用器
![TCA9548A I2C 多路复用器教程:ESP32、ESP8266、Arduino](https://static.qutaojiao.com/wp-content/uploads/2023/12/TCA9548A-I2C-Multiplexer-Sensor-Module.jpg)
I2C 通信协议允许您在同一 I2C 总线上与多个 I2C 设备进行通信,只要所有设备都具有唯一的 I2C 地址。但是,如果要连接具有相同地址的多个 I2C 设备,它将不起作用。
TCA9548A I2C 多路复用器允许您使用相同的 I2C 总线与多达 8 个 I2C 设备进行通信。多路复用器使用 I2C 通信协议与微控制器通信。然后,您可以在多路复用器上选择要寻址的 I2C 总线。
要寻址特定端口,只需向多路复用器发送一个具有所需输出端口号的字节。
![TCA9548A I2C 多路复用器教程:ESP32、ESP8266、Arduino](https://static.qutaojiao.com/wp-content/uploads/2023/12/TCA9548A-How-it-Works.png)
TCA9548A 多路复用器特性
以下是其主要功能的摘要:
- 1 至 8 个双向平移开关
- /RESET输入
- 3 个地址引脚 — 同一 I2C 总线上最多 8 个TCA9548A器件
- 通过 I2C 总线选择通道
- 工作电源电压范围:1.65V至5.5V
- 5V 容限引脚
有关更详细的说明,请参阅数据表。
TCA9548A 多路复用器 I2C 地址
TCA9548A多路复用器使用 I2C 通信协议与微控制器通信。因此,它需要一个 I2C 地址。多路复用器的地址是可配置的。您可以通过调整 A0、A1 和 A2 引脚的值从 0x70 到 0x77 中选择一个值,如下表所示。
A0 | A1 | A2 | I2C 地址 |
LOW | LOW | LOW | 0x70 |
HIGH | LOW | LOW | 0x71 |
LOW | HIGH | LOW | 0x72 |
HIGH | HIGH | LOW | 0x73 |
LOW | LOW | HIGH | 0x74 |
HIGH | LOW | HIGH | 0x75 |
LOW | HIGH | HIGH | 0x76 |
HIGH | HIGH | HIGH | 0x77 |
因此,您最多可以将 8 个TCA9548A多路复用器连接到同一 I2C 总线,这将允许您仅使用微控制器的一个 I2C 总线连接具有相同地址的 64 个设备。
例如,如果将 A0、A1 和 A2 连接到 GND,则会为多路复用器设置地址0x70。
TCA9548A引脚排列
下表介绍了TCA9584A引脚排列。
Pin | 描述 |
VIN | 为多路复用器供电 |
GND | 连接到 GND |
SDA | 连接到主微控制器 SDA 引脚 |
SCL | 连接到主微控制器 SCL 引脚 |
RST | 低电平有效RST引脚—可用于复位多路复用器 |
A0 | 选择多路复用器 I2C 地址 — 连接到 GND 或 VCC |
A1 | 选择多路复用器 I2C 地址 — 连接到 GND 或 VCC |
A2 | 选择多路复用器 I2C 地址 — 连接到 GND 或 VCC |
SD0 | 通道 0 的 SDA |
SC0 | 通道 0 的 SCL |
SD1 | 通道 1 的 SDA |
SC1 | 通道 1 的 SCL |
SD2 | 通道 2 的 SDA |
SC2 | 通道 2 的 SCL |
SD3 | 通道 3 的 SDA |
SC3 | 通道 3 的 SCL |
SD4 | 通道 4 的 SDA |
SC4 | 通道 4 的 SCL |
SD5 | 通道 5 的 SDA |
SC5 | 通道 5 的 SCL |
SD6 | 通道 6 的 SDA |
SC6 | 通道 6 的 SCL |
SD7 | 通道 7 的 SDA |
SC7 | 通道 7 的 SCL |
TCA9548A I2C 多路复用器 选择 I2C 总线
如前所述,要选择特定的 I2C 总线来读/写数据,只需向多路复用器发送一个具有所需输出端口号(0 到 7)的字节。
为此,您可以简单地使用以下用户定义的函数:
void TCA9548A(uint8_t bus){
Wire.beginTransmission(0x70); // TCA9548A address is 0x70
Wire.write(1 << bus); // send byte to select bus
Wire.endTransmission();
Serial.print(bus);
}
然后,您只需要调用该函数,并在发送 I2C 命令之前将要控制的端口总线号作为参数传递。例如,要控制连接到总线编号 3 的设备,您需要在调用其他 I2C 命令之前调用以下行(请注意,它从 0 开始):
TCA9548A(2);
您将在以下各节中通过实际示例了解其工作原理。
控制多个OLED显示器—TCA9548A I2C多路复用器
在本节中,我们将向您展示如何控制多个OLED显示器。例如,我们将控制四个 OLED 显示器,但您最多可以连接 8 个显示器。
所需零件
下面是此示例所需的部件列表:
- 微控制器(ESP32、ESP8266、Arduino 或其他);
- TCA9548A I2C 多路复用器
- 多个OLED显示屏(最多8个)
- 面包板
- 跳线
带有I2C多路复用器电路的多个OLED显示器
连接四个OLED显示器,如下图所示。我们使用的是 2、3、4 和 5 路公交车。您可以选择任何其他端口号。
我们还将 A0、A1 和 A2 连接到 GND。这将选择多路复用器的地址0x70。
![TCA9548A I2C 多路复用器教程:ESP32、ESP8266、Arduino](https://static.qutaojiao.com/wp-content/uploads/2023/12/multiple-OLED-displays-TCA9548A-I2C-Multiplexer.jpg)
以下是默认的 I2C 引脚,具体取决于您使用的微控制器:
微控制器 | I2C 引脚 |
ESP32 | GPIO 22 (SCL)、GPIO 21 (SDA) |
ESP8266 | 通用IO 5 (D1) (SCL), 通用IO 4 (D2) (SDA) |
Arduino Uno的 | A5 (SCL), A4 (SDA) |
多个OLED显示器,带I2C多路复用器代码
控制显示器就像控制一台显示器一样简单。您只需要考虑选择正确的 I2C 总线,然后再发送写入显示器的命令。
安装库
我们将使用以下库来控制OLED显示器。确保您已安装以下库:
您可以使用Arduino库管理器安装库。转到“程序”>“包括库”>“管理库”,然后搜索库名称。
如果将 VS Code 与 PlatformIO 扩展一起使用,请将以下内容复制到 platformio.ini 文件以包含库。
lib_deps = adafruit/Adafruit SSD1306@^2.4.6
adafruit/Adafruit GFX Library@^1.10.10
安装库后,可以继续。
将以下代码复制到 Arduino IDE 并将其上传到开发板。它将立即起作用。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Select I2C BUS
void TCA9548A(uint8_t bus){
Wire.beginTransmission(0x70); // TCA9548A address
Wire.write(1 << bus); // send byte to select bus
Wire.endTransmission();
Serial.print(bus);
}
void setup() {
Serial.begin(115200);
// Start I2C communication with the Multiplexer
Wire.begin();
// Init OLED display on bus number 2
TCA9548A(2);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
// Clear the buffer
display.clearDisplay();
// Init OLED display on bus number 3
TCA9548A(3);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
// Clear the buffer
display.clearDisplay();
// Init OLED display on bus number 4
TCA9548A(4);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
// Clear the buffer
display.clearDisplay();
// Init OLED display on bus number 5
TCA9548A(5);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
// Clear the buffer
display.clearDisplay();
// Write to OLED on bus number 2
TCA9548A(2);
display.clearDisplay();
display.setTextSize(8);
display.setTextColor(WHITE);
display.setCursor(45, 10);
// Display static text
display.println("1");
display.display();
// Write to OLED on bus number 3
TCA9548A(3);
display.clearDisplay();
display.setTextSize(8);
display.setTextColor(WHITE);
display.setCursor(45, 10);
// Display static text
display.println("2");
display.display();
// Write to OLED on bus number 4
TCA9548A(4);
display.clearDisplay();
display.setTextSize(8);
display.setTextColor(WHITE);
display.setCursor(45, 10);
// Display static text
display.println("3");
display.display();
// Write to OLED on bus number 5
TCA9548A(5);
display.clearDisplay();
display.setTextSize(8);
display.setTextColor(WHITE);
display.setCursor(45, 10);
// Display static text
display.println("4");
display.display();
}
void loop() {
}
代码的工作原理
继续阅读以了解代码的工作原理,或跳到演示部分。
首先,导入控制OLED显示器所需的库:Adafruit_GFX和Adafruit_SSD1306。使用 I2C 通信协议需要 Wire 库。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
定义OLED的宽度和高度。
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
创建一个Adafruit_SSD1306实例以与OLED显示器通信。
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
您可以使用同一实例与所有显示器进行通信。在这种情况下,您需要在写入另一个 OLED 之前清除显示缓冲区 (display.clearDisplay())。
或者,您可以创建多个 Adafruit_SSD1306 实例,每个 OLED 一个。在这种情况下,无需清除缓冲区。在本节末尾,我们将向您展示一个包含多个实例的示例。
选择 I2C 通道
可以调用 TCA9548A() 函数来选择要与之通信的总线。它向多路复用器发送一个带有端口号的字节。
// Select I2C BUS
void TCA9548A(uint8_t bus){
Wire.beginTransmission(0x70); // TCA9548A address
Wire.write(1 << bus); // send byte to select bus
Wire.endTransmission();
Serial.print(bus);
}
每当要选择 I2C 端口时,都必须调用此函数。
setup()
在 setup() 中,初始化串行通信以进行调试。
Serial.begin(115200);
在默认 I2C 引脚上与 I2C 多路复用器启动 I2C 通信。
Wire.begin();
然后,初始化每个显示器。以下几行显示了第一个OLED显示器(它连接到2号总线)的示例。
//Init OLED display on bus number 2
TCA9548A(2);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
// Clear the buffer
display.clearDisplay();
初始化其他显示器与此类似,但您需要使用相应的 I2C 总线号调用 TCA9548A() 函数。
然后,在显示器上写入一些内容。别忘了,每次要在OLED之间切换时,都需要调用TCA9548A()函数。在向OLED写入任何内容之前,您还需要清除显示缓冲区。
// Write to OLED on bus number 2
TCA9548A(2);
display.clearDisplay();
display.setTextSize(8);
display.setTextColor(WHITE);
display.setCursor(45, 10);
// Display static text
display.println("1");
display.display();
在这种情况下,我们只是在每个显示器上打印一个不同的数字。这是 OLED 编号 4 的示例(它连接到总线编号 5)。
// Write to OLED on bus number 5
TCA9548A(5);
display.clearDisplay();
display.setTextSize(8);
display.setTextColor(WHITE);
display.setCursor(45, 10);
// Display static text
display.println("4");
display.display();
这几乎就是代码的工作方式。
下面的代码显示了一个类似的示例,但使用了多个Adafruit_SSD1306实例。请注意,在写入显示器之前,无需清除缓冲区。
示范
将代码上传到您的看板。这是你应该得到的。
![TCA9548A I2C 多路复用器教程:ESP32、ESP8266、Arduino](https://static.qutaojiao.com/wp-content/uploads/2023/12/OLED-Demonstration-TCA9548A-I2C-Multiplexer-Sensor-Module.jpg)
如您所见,使用I2C多路复用器控制多个显示不同图形的OLED显示器非常容易。
读取多个 BME280 传感器—TCA9548A I2C 多路复用器
在本节中,您将学习如何使用 TCA9548A I2C 多路复用器从多个 BME280 传感器读取数据。我们将从 4 个传感器读取数据,但您最多可以连接 8 个传感器。
![TCA9548A I2C 多路复用器教程:ESP32、ESP8266、Arduino](https://static.qutaojiao.com/wp-content/uploads/2023/12/BME280-Demonstration-TCA9548A-I2C-Multiplexer-Sensor-Module.jpg)
所需零件
下面是此示例所需的部件列表:
- 微控制器(ESP32、ESP8266、Arduino 或其他);
- TCA9548A I2C 多路复用器
- 多个 BME280 传感器(最多 8 个)
- 面包板
- 跳线
多个 BME280 传感器,带有 I2C 多路复用器电路
连接四个 BME280 传感器,如下图所示。我们使用的是 2、3、4 和 5 路公交车。您可以选择任何其他端口号。
我们还将 A0、A1 和 A2 连接到 GND。这将选择多路复用器的地址0x70。
![TCA9548A I2C 多路复用器教程:ESP32、ESP8266、Arduino](https://static.qutaojiao.com/wp-content/uploads/2023/12/multiple-bme280-TCA9548A-I2C-Multiplexer.png)
以下是默认的 I2C 引脚,具体取决于您使用的微控制器:
微控制器 | I2C 引脚 |
ESP32 | GPIO 22 (SCL)、GPIO 21 (SDA) |
ESP8266 | 通用IO 5 (D1) (SCL), 通用IO 4 (D2) (SDA) |
Arduino Uno的 | A5 (SCL), A4 (SDA) |
多个 BME280 传感器,带 I2C 多路复用器代码
与OLED显示器类似,从多个传感器读取数据就像控制单个传感器一样简单。在与传感器通信之前,您只需要考虑选择正确的 I2C 总线即可。
安装库
我们将使用以下库从 BME280 传感器读取数据。确保您已安装以下库:
您可以使用Arduino库管理器安装库。转到“程序”>“包括库”>“管理库”,然后搜索库名称。
如果将 VS Code 与 PlatformIO 扩展一起使用,请将以下内容复制到 platformio.ini 文件以包含库。
lib_deps = adafruit/Adafruit Unified Sensor @ ^1.1.4
adafruit/Adafruit BME280 Library @ ^2.1.2
安装库后,可以继续。
将以下代码复制到 Arduino IDE 并将其上传到开发板。它将立即起作用。
代码的工作原理
继续阅读以了解代码的工作原理,或跳到演示部分。
首先,导入控制 BME280 显示器所需的库:Adafruit_BME280 和 Adafruit_Sensor。使用 I2C 通信协议需要 Wire 库。
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
然后,您需要创建多个 Adafruit_BME280 实例,每个传感器一个:bme1、bme2、bme3 和 bme4。
Adafruit_BME280 bme1; // I2C
Adafruit_BME280 bme2; // I2C
Adafruit_BME280 bme3; // I2C
Adafruit_BME280 bme4; // I2C
选择 I2C 通道
可以调用 TCA9548A() 函数来选择要与之通信的总线。它向多路复用器发送一个带有端口号的字节。
// Select I2C BUS
void TCA9548A(uint8_t bus){
Wire.beginTransmission(0x70); // TCA9548A address
Wire.write(1 << bus); // send byte to select bus
Wire.endTransmission();
Serial.print(bus);
}
每当要选择 I2C 端口时,都必须调用此函数。
printValues() 函数
然后,我们创建一个函数 printValues(),它允许我们在串行监视器中打印每个传感器的值。这个函数允许我们传递Adafruit_BME280实例及其总线。
在函数内部,我们通过调用 TCA9548A() 函数并将总线作为参数传递来选择要与之通信的 I2C 总线。
TCA9548A (bus);
然后,我们使用常用函数从传感器获取读数。
Serial.print("Sensor number on bus");
Serial.println(bus);
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");
setup()
在 setup() 中,初始化串行通信以进行调试。
Serial.begin(115200);
在默认 I2C 引脚上与 I2C 多路复用器启动 I2C 通信。
Wire.begin();
然后,初始化每个传感器。以下几行显示了第一个 BME280 传感器的示例(它连接到总线编号 2,它指的是 bme1 实例)。
//Init sensor on bus number 2
TCA9548A(2);
if (!bme1.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor on bus 2, check wiring!");
while (1);
}
Serial.println();
初始化其他传感器与此类似,但您需要使用相应的 I2C 总线号调用 TCA9548A() 函数。另外,不要忘记每个传感器都有自己的实例。
loop()
在 loop() 中,我们为每个传感器调用 printValues() 函数。
printValues(bme1, 2);
printValues(bme2, 3);
printValues(bme3, 4);
printValues(bme4, 5);
这几乎就是代码的工作方式。
示范
将代码上传到您的看板。以 115200 的波特率打开串行监视器。每个传感器的读数将显示在串行监视器上。
![TCA9548A I2C 多路复用器教程:ESP32、ESP8266、Arduino](https://static.qutaojiao.com/wp-content/uploads/2023/12/Multiple-BME280-Sensors-I2C-Multiplexer-Demonstration.png)
总结
本教程介绍了如何使用 TCA9548A I2C 多路复用器向微控制器添加更多 I2C 端口。如果要连接具有相同 I2C 地址的多个设备,这将特别有用。此外,多路复用器本身的 I2C 地址可以从 0x70 更改为 0x77。这使我们能够同时连接多达 8 个多路复用器,从而允许您控制 64 个设备。
本教程中展示的示例与 ESP32、ESP8266 和 Arduino 开发板兼容。