Мультиплексирование Arduino I2C с использованием TCA9548A
Я использую 5 датчиков, два из которых имеют одинаковый адрес I2C и подключены через мультиплексор TCA9548. Остальные 3 датчика подключены к основной шине arduino I2C. В примерах скетчей онлайн я вижу следующую функцию для выбора конкретного порта/канала на мультиплексоре:
#define MPLXADR 0x70 // Адрес мультиплексора I2C TCA9548A
void multiplexer (uint8_t ch) {
if (ch > 7) return;
Wire.beginTransmission(MPLXADR);
Wire.write(1 << ch);
Wire.endTransmission();
}
Я понимаю, что эту функцию следует вызывать перед выполнением инструкций для датчиков с общим адресом, но как она все равно отправит данные на нужный датчик, когда последняя строка "Wire.endTransmission();" просто закрывает соединение?
Поскольку в моей схеме есть датчики, которые подключены непосредственно к шине I2C Arduino, мне интересно, если код, относящийся к этим датчикам, идет после кода для датчиков с общим адресом, не будут ли эти инструкции также отправлены датчикам. с общим адресом I2C? На мой взгляд, имеет больше смысла, если инструкции для датчиков общего адреса заключены в вышеупомянутую функцию следующим образом:
выбор канала -> выполнить инструкцию -> завершить передачу
Но использование, которое я вижу в учебниках, ставит меня в тупик. Может ли кто-нибудь прояснить эти моменты? Спасибо
Вот полный скетч, который я использую:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <AHT10.h>
#include <HDC2080.h>
Adafruit_BME280 bme1; // на шине Arduino I2C
Adafruit_BME280 bme2; // на шине I2C мультиплексора
Adafruit_BME280 bme3; // на шине I2C мультиплексора
AHT10 AHT(AHT10_ADDRESS_0X38); // на шине Arduino I2C
HDC2080 HDC2080(0x41);// на шине Arduino I2C
#define MPLXADR 0x70 // Адрес мультиплексора I2C TCA9548A
void multiplexer (uint8_t ch) {
if (ch > 7) return;
Wire.beginTransmission(MPLXADR);
Wire.write(1 << ch);
Wire.endTransmission();
}
void setup() {
Serial.begin(115200);
while (AHT.begin() != true)
{
Serial.println(F("AHT10 not connected or fail to load calibration coefficient"));
delay(5000);
}
Serial.println(F("AHT10 OK"));
HDC2080.begin();
// Начнем со сброса устройства
HDC2080.reset();
// Настраиваем зону комфорта
HDC2080.setHighTemp(28); // Высокая температура 28С
HDC2080.setLowTemp(22); // Низкая температура 22C
HDC2080.setHighHumidity(55); // Высокая влажность 55%
HDC2080.setLowHumidity(40); // Низкая влажность 40%
// Настройка измерений
HDC2080.setMeasurementMode(TEMP_AND_HUMID); // Установить измерения температуры и влажности
HDC2080.setRate(ONE_HZ); // Установите частоту измерения на 1 Гц
HDC2080.setTempRes(FOURTEEN_BIT);
HDC2080.setHumidRes(FOURTEEN_BIT);
// начинаем измерение
HDC2080.triggerMeasurement();
Serial.println();
Serial.println(F("BME280 test"));
//датчик BME280 1
multiplexer(0);
if (! bme1.begin(0x77, &Wire)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
// мониторинг погоды
Serial.println("-- Weather Station Scenario --");
Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
Serial.println("filter off");
bme1.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // температура
Adafruit_BME280::SAMPLING_X1, // давление
Adafruit_BME280::SAMPLING_X1, // влажность
Adafruit_BME280::FILTER_OFF );
//датчик BME280 2
multiplexer(1);
if (! bme2.begin(0x77, &Wire)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
// мониторинг погоды
Serial.println("-- Weather Station Scenario --");
Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
Serial.println("filter off");
bme2.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // температура
Adafruit_BME280::SAMPLING_X1, // давление
Adafruit_BME280::SAMPLING_X1, // влажность
Adafruit_BME280::FILTER_OFF );
//датчик BME280 3
if (! bme3.begin(0x76, &Wire)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
// мониторинг погоды
Serial.println("-- Weather Station Scenario --");
Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
Serial.println("filter off");
bme3.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // температура
Adafruit_BME280::SAMPLING_X1, // давление
Adafruit_BME280::SAMPLING_X1, // влажность
Adafruit_BME280::FILTER_OFF );
// рекомендуемая частота 1/60 Гц (1 м)
}
void loop() {
bme3.takeForcedMeasurement(); // не действует в обычном режиме
printValuesBME3();
delay(5000);
printValuesAHT();
delay(5000);
printValuesHDC2080();
delay(5000);
multiplexer(0);
bme1.takeForcedMeasurement(); // не действует в обычном режиме
printValuesBME1();
delay(5000);
multiplexer(1);
bme2.takeForcedMeasurement(); // не действует в обычном режиме
printValuesBME2();
delay(10000);
}
void printValuesBME1() {
Serial.println();
Serial.print("BME1 Readings");
Serial.print("Temperature = ");
Serial.print(bme1.readTemperature());
Serial.println(" *C");
Serial.print("Humidity = ");
Serial.print(bme1.readHumidity());
Serial.println(" %");
Serial.println();
}
void printValuesBME2() {
Serial.println();
Serial.print("BME2 Readings");
Serial.print("Temperature = ");
Serial.print(bme2.readTemperature());
Serial.println(" *C");
Serial.print("Humidity = ");
Serial.print(bme2.readHumidity());
Serial.println(" %");
Serial.println();
}
void printValuesBME3() {
Serial.println();
Serial.print("BME3 Readings");
Serial.print("Temperature = ");
Serial.print(bme3.readTemperature());
Serial.println(" *C");
Serial.print("Humidity = ");
Serial.print(bme3.readHumidity());
Serial.println(" %");
Serial.println();
}
void printValuesHDC2080() {
Serial.println("HDC2080 Values");
Serial.print("Temperature (C): "); Serial.print(HDC2080.readTemp());
Serial.print("\t\tHumidity (%): "); Serial.println(HDC2080.readHumidity());
}
void printValuesAHT() {
Serial.println(F("AHT10: read 12-bytes, show 255 if communication error is occurred"));
Serial.print(F("Temperature: ")); Serial.print(AHT.readTemperature()); Serial.println(F(" +-0.3C")); //по умолчанию "AHT10_FORCE_READ_DATA"
Serial.print(F("Humidity...: ")); Serial.print(AHT.readHumidity()); Serial.println(F(" +-2%")); //по умолчанию "AHT10_FORCE_READ_DATA"
}
@Zaffresky, 👍0
1 ответ
Лучший ответ:
TCA9548 — это коммутатор.
Вы начинаете с ним транзакцию, меняете канал, через который он проходит, а затем завершаете эту конкретную транзакцию.
С этого момента к вашему автобусу подключен один и только один из двух других датчиков - другого не существует. Когда вы сообщаете адрес этого датчика, он проходит через TCA9548, как будто его не существует.
Вы можете думать о TCA9548 как о контроллере, который находится рядом с коммутатором:
Отправьте канал 0, и он переключит переключатель в одну сторону. Отправьте канал 1, и он переключит переключатель в другую сторону. Когда переключатель щелкнут, он останется включенным, пока вы не скажете иначе.
С точки зрения скетчей, два HDC2080 на MUX — это всего лишь один HDC2080. Просто переведите переключатель в нужное положение, чтобы получить доступ к конкретному физическому устройству, которое вам нужно в данный момент.
- Отправка и получение различных типов данных через I2C в Arduino
- Как работают функции вне цикла void?
- Как отображать переменные на 0,96-дюймовом OLED-дисплее с библиотекой u8glib?
- Несколько датчиков I2C с одинаковым адресом
- OVF в последовательном мониторе вместо данных
- ЖК-дисплей I2C отображает странные символы
- Соединение I2C зависает Ведущий если ведомый отключается
- Экран LCD 16*02 I2C показывает только первый напечатанный символ