8-Kanal I2C-Multiplexer TCA9548A

Üblicherweise hat bei Verwendung eines I2C-Busses jeder Busteilnehmer eine I2C-Adresse, die nur einmalig am Bus vorkommen darf. Was aber tun, wenn sich das nicht vermeiden lässt?

Für die Verwendung von zwei oder mehreren Busteilnehmern mit identischen I2C-Adressen bietet sich der 8-kanalige I2C-Multiplexer TCA9548A als Abhilfe an. Über I2C-Kommunikation mit dem Baustein kann jeweils nur ein einzelner I2C-Kanal durchgeschaltet werden, alle anderen Kanäle sind während dieser Zeit hochohmig. So können z.B. mit einem TCA9584A hintereinander bis zu 8 Sensoren mit identischer I2C-Adresse abgefragt werden. Der TCA9584A selbst hat 3 Adresseingänge (A0-A2), so dass bis zu 8 TCAs angesprochen und daher bis zu 8 x 8 = 64 Busteilnehmer mit identischer I2C-Adresse abgefragt werden können.

Aber wann oder wofür wird denn das benötigt?

Ich selbst habe einmal TCAs für den Anschluss von mehreren BME280-Sensoren verwendet, um die Messergebnisse für Luftdruck und Luftfeuchtigkeit zu vergleichen. Beim BME280 kann man nämlich nur zwischen zwei möglichen I2C-Adressen wählen.

Es gibt auch Sensoren, die haben nur eine einzige I2C-Adresse. So musste ich einmal die gemessenen Temperaturen von drei PT1000-Fühler, mit I2C-Modulen mit nur einer möglichen I2C-Adresse, für die Steuerung eines Boilers einlesen, wo ich dann ebenfalls den TCA9548A eingesetzt habe.

Und genau für solche Anwendungsfälle habe ich damals schon eine kleine Library geschrieben, die ich hier vorstelle.

                 

Bild 1: Ansicht mit Anschlussbelegung des I2c-Multiplexers TCA9548A

  • VIN, GND: Stromversorgung 1,65 - 5,5 V
  • SCL, SDA: Serial Clock und Serial Data Bus
  • RST: Reseteingang (aktiv LOW)
  • A0-A2: I2C-Adresseingänge
  • SCx, SDx: Serial Clock und Serial Data der Kanäle 0....7

I2C-Adresse:

Standardmäßig ist die I2C-Adresse des TCA9548A-Moduls 0x70, die Adresseingänge A0-A2 brauchen dazu wegen der vorhandenen Pulldown-Widerständen am Modul nicht beschaltet werden. Durch entsprechende Beschalten der Adresseingänge mit VCC kann die Adresse von 0x71 bis 0x77 eingestellt werden.

Pullup-Widerstände:

Die Signalleitungen SCL und SDA des I2C-Busses sind am Modul bereits mit 10 kOhm Pullup-Widerständen versehen.

Die Signalleitungen SCx und SDx der Kanäle 0...7 benötigen Pullup-Widerstände, sofern diese nicht bei den Busteilnehmern bereits integriert sind.

Der aktiv-LOW Reseteingang ist am Modul bereits ebenfalls mit einem 10 kOhm Pullup-Widerstand versehen, daher ist - sofern er nicht benötigt wird - keine Beschaltung erforderlich.

Testaufbau:

Verwendete Bauteile:

  • 1 Arduino Nano
  • 1 I2C-Multiplexer TCA9548A
  • 2 I2C-Sensoren (z.B. Temperatursensor MCP9808)

Optional (nicht dargestellt):

  • 4 Widerstände 10 kOhm (Pullup-Widerstände für die sensorseitigen Bus-Leitungen, falls diese nicht auf den Sensormodulen integriert sind)


Hinweis: Der TCA9548A kann auch für die Spannungsumsetzung als Logic-Level-Converter verwendet werden. Man kann also verschiedene Busspannungen auf jedem SCn/SDn-Bus betreiben, so dass Bauteile mit 1,8 V-, 2,5 V- oder 3,3 V-Versorgungs- und Signalspannung mit 5V-Komponenten kommunizieren können. Dies wird durch die externen Pull-Up-Widerstände erreicht, um den Bus und die einzelnen Kanäle auf die gewünschten Spannungen zu ziehen.


TCA9548A-Scanner:

Der nachfolgende Sketch scannt alle Kanäle von gefundenen TCA9548A-Bausteinen mit I2C-Adresse von 0x70 bis 0x77 und zeigt diese am Seriellen Monitor an (siehe Bild 2). Es sollten daher am I2C-Bus keine anderen Busteilnehmer mit diesen Adressen vorhanden sein, sehr wohl können aber die Kanäle damit beschaltet sein. So nutzen z.B. die Sensoren BMP180/280 oder BME280 diesen Adressbereich.

TCA9548A_Scanner.ino.txt

Leider kann ich hier keine "ino"-Files hochladen, daher zum Verwenden des Programms ".txt" aus den Dateinamen entfernen und in einem neuen Verzeichnis mit dem Namen "TCA9548A_Scanner" speichern.


Bild 2: Ausgabe des TCA9548A-Scanners bei Verwendung mit obigem Testaufbau


Library MyTCA9548A:

Folgende Funktionen stehen zur Verfügung:


  • Abfrage, ob der Baustein über I2C ansprechbar ist
  • Festlegen, welche Kanäle mit Busteilnehmern beschaltet sind
  • Setzen des Kanals, der durchgeschaltet werden soll
  • Rücksetzen des durchgeschalteten Kanals
  • Abfrage, welcher Kanal durchgeschaltet ist


Die Library kann hier heruntergeladen werden:

Sollte die Library jemand verwenden oder testen, würde ich mich über eine Rückmeldung sehr freuen!

Version 1.0

MyTCA9548A.cpp.txt

MyTCA9548A.h.txt

keywords.txt

Leider kann ich hier keine "cpp"- oder "h"-Files hochladen, daher zum Verwenden der Library das Suffix ".txt" aus diesen Dateinamen entfernen und in einem neuen Verzeichnis mit dem Namen "MyTCA9548A" im Sketchbook-Ordner im Ordner "libraries" speichern.


Zur Auflistung der Funktionen der Library geht es hier: Funktionen

Beispiel:

Mit nachfolgendem Programmbeispiel werden - wie im Testaufbau ersichtlich - die mit MCP9808-Sensoren gemessenen Temperaturen alle 5 Sekunden eingelesen und am Seriellen Monitor angezeigt (siehe Bild 3).

Verwendete Libraries: Neben der Standard-Library Wire und der hier vorgestellten MyTCA9548A-Library benötigt man noch für die Abfrage der Temperatursensoren meine Library MyMCP9808. Diese gibt es hier: Temp.sensor MCP9808


//Programmbeispiel TCA9548 mit MCP9808
//Code fuer Arduino
//Author Retian
//Version 1.0


//Prototype:
void messwertAusgabe(float);


#include <MyMCP9808.h>
#include <MyTCA9548A.h>

MyTCA9548A TCA(0x70);
MyMCP9808 MCP(0x18);

float temp[8];


void setup() {
  Serial.begin(115200);

  if (TCA.isReady())
  {
    Serial.println("TCA9548A ok");
    //Nur Kanal 0 und 1 ist mit Sensoren beschaltet
    TCA.defineWiredChannel(1, 1, 0, 0, 0, 0, 0, 0);
  }
  else
  {
    Serial.println("TCA9548A Fehler");
    while (1); //Im Fehlerfall geht's hier nicht weiter
  }
}


void loop() {
  for (byte i = 0; i < 8; i++)
  {
    //Schaltet Kanal i durch, wenn dieser beschaltet ist
    if (TCA.setChannel(i))
    {
      temp[i] = MCP.readTemp();
      messwertAusgabe(temp[i]);
    }
    else
    {
      Serial.print("Ch");
      Serial.print(i);
      Serial.println(": nicht beschaltet!");
    }
  }
  Serial.println();
  delay(5000);
}


void messwertAusgabe(float messwert)
{
  Serial.print("Ch");
  Serial.print(TCA.getChannel());
  Serial.print(": ");
  Serial.print(messwert);
  Serial.println(" °C");
}

Bild 3: Ausgabe des Programmbeispiels am Seriellen Monitor