Протокол связи I2C хорош тем, что для подключения микроконтроллера к одному, двум или нескольким датчикам требуется всего два провода. Но это работает только в том случае, если у каждого датчика есть собственный адрес I2C. Предположим, вы хотите подключить четыре (или более) датчика с одним фиксированным адресом. Один из способов – использовать вместо этого протокол SPI.

Но не каждый датчик или коммутационная плата позволяет использовать протокол SPI. Так что можно сделать? Просто используйте мультиплексор I2C, вроде микросхемы TCA9548A от Texas Instruments. Это устройство доступно в качестве коммутационной платы для облегчения процесса подключения.
Итак, у этого компонента 8 каналов, это означает, что мы можем подключить до 8 датчиков к шине I2C. Хотя, на самом деле гораздо большею Давайте подробнее рассмотрим это устройство и способы его использования.
Этот мультиплексор TCA9548A вы можете подключать его к своему Arduino, как и любое другое устройство I2C. Вот его линии для подключения к Arduino:

Остальные 16 контактов подключены к 8 каналам мультиплексора. Таким образом, контакты SD0 и SC0 соответствуют линии данных (SDA) и линии синхронизации (SCL) от первой шины I2C, контакты SD1 и SC1 соответствуют линиям от второй шины I2C и т. д.

Каждая шина I2C мультиплексора независима друг от друга, и, как и шина I2C от вашего Arduino, вы можете подключить несколько устройств с разными адресами I2C к каждой шине мультиплексора.
В этом простом руководстве вы увидите, как подключить и запрограммировать мультиплексор на четыре датчика BME280, у которых один и тот же адрес I2C (0x77). Мы хотим подключить четыре платы, приведенные на следующем изображении, к Arduino Uno по протоколу I2C.

Давайте сначала соединим их друг с другом. Сначала соедините все контакты GND всех плат друг с другом (синие провода). Поскольку все платы работают от 5 В или 3,3 В, мы можем использовать любой из этих уровней для питания всех плат. Итак, давайте подключим 5V ко всем платам красными проводами.

Теперь подключим первый датчик к первой шине I2C от мультиплексора. Для этого подключите вывод SDI датчика к SD0 мультиплексора. Теперь подключите SCK от датчика к SC0 от мультиплексора.

Просто повторите то же самое для всех датчиков, подключив каждый к другой шине I2C от мультиплексора. Как видите, после всего этого у нас есть четыре разных шины I2C, где белые провода соответствуют линиям синхронизации, а серые провода представляют линии данных.

Наконец, подключите линии данных и часов от Arduino Uno к мультиплексору. В этом случае вывод A4 от Arduino идет на вывод SDA мультиплексора, а вывод A5 от Arduino подключается к выводу SCL мультиплексора. Как упоминалось ранее, мы используем 5 В для питания всех плат. Таким образом, вывод 5V от Arduino идет на вывод VIN мультиплексора, а также выводы VCC от каждой платы (красные провода). И конечно, соедините все контакты GND друг с другом (синие провода).

Датчики и мультиплексор теперь успешно подключены друг к другу и к Arduino Uno, поэтому теперь приступим к программированию. Мультиплексор TCA9548A не требует какой-либо библиотеки, а датчик BME280 требует. Если вы этого еще не сделали, скачайте библиотеку сейчас по этой ссылке. Если вы хотите подключить мультиплексор к другому датчику, просто пропустите этот шаг. Далее приведен код программы Arduino для взаимодействия с TCA9548 и получения данных от датчиков BME280.
#include <Wire.h>
//#include <avr/wdt.h>
#include "BlueDot_BME280.h"
BlueDot_BME280 bme280_0;
BlueDot_BME280 bme280_1;
BlueDot_BME280 bme280_2;
BlueDot_BME280 bme280_3;
#define TCAADDR 0x70
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
void setup() {
Serial.begin(9600);
Wire.begin();
Serial.println(F("##############################"));
Serial.println(F("Starting Initialization"));
Serial.println(F("##############################"));
//*************INITIALIZING FIRST SENSOR*******************************
tcaselect(0);
bme280_0.parameter.communication = 0;
bme280_0.parameter.I2CAddress = 0x77;
bme280_0.parameter.sensorMode = 0b11;
bme280_0.parameter.IIRfilter = 0b100;
bme280_0.parameter.humidOversampling = 0b101;
bme280_0.parameter.tempOversampling = 0b101;
bme280_0.parameter.pressOversampling = 0b101;
if (bme280_0.init() != 0x60)
{ Serial.print(F("BME280 Nr.1 detected?\t")); Serial.println(F("No"));}
else
{ Serial.print(F("BME280 Nr.1 detected?\t")); Serial.println(F("Yes"));}
//**********************************************************************
//*************INITIALIZING SECOND SENSOR*******************************
tcaselect(1);
bme280_1.parameter.communication = 0;
bme280_1.parameter.I2CAddress = 0x77;
bme280_1.parameter.sensorMode = 0b11;
bme280_1.parameter.IIRfilter = 0b100;
bme280_1.parameter.humidOversampling = 0b101;
bme280_1.parameter.tempOversampling = 0b101;
bme280_1.parameter.pressOversampling = 0b101;
if (bme280_1.init() != 0x60)
{ Serial.print(F("BME280 Nr.2 detected?\t")); Serial.println(F("No"));}
else
{ Serial.print(F("BME280 Nr.2 detected?\t")); Serial.println(F("Yes"));}
//*********************************************************************
//*************INITIALIZING THIRD SENSOR********************************
tcaselect(2);
bme280_2.parameter.communication = 0;
bme280_2.parameter.I2CAddress = 0x77;
bme280_2.parameter.sensorMode = 0b11;
bme280_2.parameter.IIRfilter = 0b100;
bme280_2.parameter.humidOversampling = 0b101;
bme280_2.parameter.tempOversampling = 0b101;
bme280_2.parameter.pressOversampling = 0b101;
if (bme280_2.init() != 0x60)
{ Serial.print(F("BME280 Nr.3 detected?\t")); Serial.println(F("No"));}
else
{ Serial.print(F("BME280 Nr.3 detected?\t")); Serial.println(F("Yes"));}
//**********************************************************************
//*************INITIALIZING FOURTH SENSOR********************************
tcaselect(3);
bme280_3.parameter.communication = 0;
bme280_3.parameter.I2CAddress = 0x77;
bme280_3.parameter.sensorMode = 0b11;
bme280_3.parameter.IIRfilter = 0b100;
bme280_3.parameter.humidOversampling = 0b101;
bme280_3.parameter.tempOversampling = 0b101;
bme280_3.parameter.pressOversampling = 0b101;
if (bme280_3.init() != 0x60)
{ Serial.print(F("BME280 Nr.4 detected?\t")); Serial.println(F("No"));}
else
{ Serial.print(F("BME280 Nr.4 detected?\t")); Serial.println(F("Yes"));}
//**********************************************************************
//**********************************************************************
Serial.println();
Serial.println(F("##############################"));
Serial.println(F("Initialization Finished"));
Serial.println(F("##############################"));
Serial.println();
Serial.println();
}
//*********************************************************************
//********************MEASURING****************************************
void loop()
{
tcaselect(0);
Serial.print(F("Duration1[s]=\t"));
Serial.print(float(millis())/1000);
Serial.print("\t");
Serial.print(F("Temperature1[C]=\t"));
Serial.print(bme280_0.readTempC());
Serial.print("\t");
Serial.print(F("Humidity1[%]=\t"));
Serial.print(bme280_0.readHumidity());
Serial.print("\t");
Serial.print(F("Pressure1[Pa]=\t"));
Serial.print(bme280_0.readPressure());
Serial.print("\t");
Serial.println();
tcaselect(1);
Serial.print(F("Duration2[s]=\t"));
Serial.print(float(millis())/1000);
Serial.print("\t");
Serial.print(F("Temperature2[C]=\t"));
Serial.print(bme280_1.readTempC());
Serial.print("\t");
Serial.print(F("Humidity2[%]=\t"));
Serial.print(bme280_1.readHumidity());
Serial.print("\t");
Serial.print(F("Pressure2[Pa]=\t"));
Serial.print(bme280_1.readPressure());
Serial.print("\t");
Serial.println();
tcaselect(2);
Serial.print(F("Duration3[s]=\t"));
Serial.print(float(millis())/1000);
Serial.print("\t");
Serial.print(F("Temperature3[C]=\t"));
Serial.print(bme280_2.readTempC());
Serial.print("\t");
Serial.print(F("Humidity3[%]=\t"));
Serial.print(bme280_2.readHumidity());
Serial.print("\t");
Serial.print(F("Pressure3[Pa]=\t"));
Serial.print(bme280_2.readPressure());
Serial.print("\t");
Serial.println();
tcaselect(3);
Serial.print(F("Duration4[s]=\t"));
Serial.print(float(millis())/1000);
Serial.print("\t");
Serial.print(F("Temperature4[C]=\t"));
Serial.print(bme280_3.readTempC());
Serial.print("\t");
Serial.print(F("Humidity4[%]=\t"));
Serial.print(bme280_3.readHumidity());
Serial.print("\t");
Serial.print(F("Pressure4[Pa]=\t"));
Serial.print(bme280_3.readPressure());
Serial.print("\t");
Serial.println();
Serial.println();
Serial.println();
delay(1000);
}
Теперь загрузите код и откройте последовательный монитор на скорости 9600 бод, чтобы получить температуру, влажность и давление от всех четырех датчиков.

© digitrode.ru