Kostenloser Versand für Bestellungen über 60 €

So verbinden Sie mehrere Sensoren mithilfe eines I²C-Multiplexers

Das I²C-Kommunikationsprotokoll ist großartig, da es nur zwei Drähte benötigt, um Ihren Mikrocontroller mit einem, zwei oder mehreren Sensoren zu verbinden. Dies funktioniert aber nur, wenn jeder Sensor eine eigene I²C-Adresse hat. Angenommen, Sie möchten vier (oder mehr) Sensoren mit derselben festen Adresse verbinden. Eine Möglichkeit wäre, stattdessen das SPI-Protokoll zu verwenden, wie ich es in einem anderen Tutorial beschrieben habe.

Allerdings ermöglicht nicht jeder Sensor oder jedes Breakout-Board die Verwendung des SPI-Protokolls. Was können Sie also tun? Nun, verwenden Sie einfach einen I²C-Multiplexer, wie den Chip TCA9548A von Texas Instruments (Benötigen Sie ein Datenblatt?). Dieses Gerät ist als Breakout-Board von Adafruit erhältlich und Sie können sich das tolle Tutorial über diesen Link ansehen: Adafruit TCA9548A 1-to-8 I²C Multiplexer Breakout.

Okay, dieses Ding hat also 8 Kanäle, was bedeutet, dass ich bis zu 8 Sensoren an den I²C-Bus anschließen kann, oder? Nun ja, aber viel mehr als das! Schauen wir uns dieses Gerät und seine Verwendung genauer an!

I²C Multiplexer TCA9548A

Dies ist der TCA9548A Multiplexer. Sie können es wie jedes andere I²C-Gerät an Ihren Arduino anschließen:

  • VIN-Pin. Verbinden Sie den VIN-Pin der Platine mit dem 5-V- oder 3,3-V-Ausgang des Arduino.
  • GND-Pin. Verbinden Sie den GND-Pin der Platine mit dem GND-Pin des Arduino.
  • SDA-Pin. Verbinden Sie den SDA-Pin dieser Platine mit der SDA-Leitung des Arduino. Dies wäre der A4-Pin vom Arduino Uno.
  • SCL-Pin. Verbinden Sie den SCL-Pin dieser Platine mit der SCL-Leitung des Arduino. Dies entspricht dem A5-Pin vom Arduino Uno.

Wie der Name schon sagt, wird der Reset-Pin (RST-Pin) zum Zurücksetzen des Multiplexers verwendet, indem er mit GND verbunden wird. Standardmäßig ist es auf HIGH gesetzt, Sie können es also einfach so lassen, wie es ist. Die Pins A0, A1 und A2 werden für den Fall verwendet, dass wir die I²C-Adresse vom Multiplexer ändern müssen. Lassen Sie sie in diesem Beispiel einfach unverbunden.

Die anderen 16 verfügbaren Pins sind mit den 8 Kanälen des Multiplexers verbunden. Die Pins SD0 und SC0 entsprechen also der Datenleitung (SDA) und einer Taktleitung (SCL) vom ersten I²C-Bus; Die Pins SD1 und SC1 entsprechen den Leitungen vom zweiten I²C-Bus usw.

Jeder I²C-Bus des Multiplexers ist unabhängig vom anderen, und genau wie der I²C-Bus Ihres Arduino können Sie mehrere Geräte mit unterschiedlichen I²C-Adressen an jeden Bus des Multiplexers anschließen!

Erste Schritte!

In diesem einfachen Tutorial erfahren Sie, wie Sie den Multiplexer mit vier Umgebungssensoren BME280 unter Verwendung derselben I²C-Adresse (0x77) verbinden und programmieren. Schauen Sie sich das Bild unten an, darüber reden wir. Wir wollen diese vier Platinen über das I²C-Protokoll mit einem Arduino Uno verbinden. In diesem speziellen Fall teilen sich alle vier Sensoren die gleiche I²C-Adresse (0x77).

Verbinden wir sie zunächst miteinander, dann bringen wir den Arduino Uno ins Spiel. Verbinden Sie zunächst alle GND-Pins aller Platinen miteinander (blaue Drähte). Da alle Platinen entweder mit 5 V oder 3,3 V betrieben werden, können wir beide zur Stromversorgung aller Platinen verwenden. Schließen wir also über die roten Drähte 5V an alle Platinen an.

Jetzt verbinden wir den ersten Sensor mit dem ersten I²C-Bus vom Multiplexer. Verbinden Sie dazu den SDI-Pin des Sensors mit dem SD0 des Multiplexers. Verbinden Sie nun den SCK vom Sensor mit dem SC0 vom Multiplexer.

Wiederholen Sie das Gleiche einfach für alle Sensoren und verbinden Sie jeden einzelnen vom Multiplexer aus mit einem anderen I²C-Bus. Wie Sie sehen, haben wir immerhin vier verschiedene I²C-Busse, wobei die weißen Drähte den Taktleitungen und die grauen Drähte den Datenleitungen entsprechen.

Zum Schluss verbinden Sie die Daten- und Taktleitungen vom Arduino Uno mit dem Multiplexer. In diesem Fall geht Pin A4 vom Arduino zum SDA-Pin des Multiplexers, während Pin A5 vom Arduino mit Pin SCL vom Multiplexer verbunden ist. Wie bereits erwähnt, verwenden wir 5 V zur Stromversorgung aller Platinen. Der 5V-Pin des Arduino geht also an den VIN-Pin des Multiplexers sowie an die VCC-Pins jeder Platine (rote Drähte). Und natürlich alle GND-Pins (blaue Drähte) verbinden.

Der Code

Die Sensoren und der Multiplexer sind nun alle problemlos mit einem Arduino Uno verbunden. Also fangen wir mit dem Programmieren an!

Der Multiplexer TCA9548A benötigt keine Bibliothek, der BME280 Sensor jedoch. Wenn Sie es noch nicht getan haben, laden Sie es jetzt über den untenstehenden Link herunter. Wenn Sie den Multiplexer mit einem anderen Sensor verbinden möchten, ignorieren Sie diesen Schritt einfach.

Sie können jetzt die Arduino-Skizze, die ich für dieses Beispiel geschrieben habe, über den nächsten Link herunterladen. Aber keine Sorge, wir gehen den Code Schritt für Schritt durch.

Ganz am Anfang unserer Skizze fügen wir die Wire-Bibliothek zur Nutzung des I²C-Protokolls und die BlueDot BME280-Bibliothek ein. Der nächste Schritt ist sehr wichtig. Für jeden Sensor, den wir verwenden möchten, müssen wir eine andere Instanz erstellen. In diesem Fall verbinden wir vier BME280-Sensoren, sodass wir vier verschiedene Instanzen erstellen (bme280_0, bme280_1, bme280_2 und bme280_3). Die Bedeutung dieser Fälle wird im Folgenden klar werden.

  #include <Wire.h>
#include "BlueDot_BME280.h" BlueDot_BME280 bme280_0;
BlueDot_BME280 bme280_1;
BlueDot_BME280 bme280_2;
BlueDot_BME280 bme280_3;

Jetzt definieren wir die I²C-Adresse für den Multiplexer mithilfe der Variablen TCAADDR. Wenn die Pins A0, A1 und A2 der Multiplexerplatine nicht angeschlossen sind, verwenden wir die 0x70-Adresse. Ihr Arduino sieht nur diese Adresse auf dem I²C-Bus. Anschließend erstellen wir die Funktion tcaselect für den Multiplexer. Mit dieser Funktion können wir den Multiplexer anweisen, zwischen seinen acht Kanälen umzuschalten und das I²C-Protokoll für die Kommunikation mit jedem angeschlossenen Gerät zu verwenden. Die Kommunikation erfolgt also zunächst über die Pins SD0 und SC0, dann über die Pins SD1 und SC1 bis hin zu den Pins SD7 und SC7.

#define TCAADDR 0x70
void tcaselect (uint8_t i) {
if (i > 7) return;

Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}

Nachdem wir die serielle Kommunikation gestartet haben (mit einer Baudrate von 9600, Sie können aber auch schneller gehen, wenn Sie möchten) und das I²C-Protokoll über die Funktion Wire.begin() aktiviert haben, initialisieren wir den ersten BME280-Sensor. Dann weisen wir den Multiplexer mit der Funktion tcaselect(0) an, eine Verbindung zum Sensor an den Pins SD0 und SC0 herzustellen. Danach verwenden wir für jede Variable und jede Funktion die Instanz des ersten Sensors (bme280_0). Wir initialisieren den ersten Sensor mit dieser Konfiguration.

//*************INITIALIZING FIRST SENSOR*******************************
tcaselect(0);
bme280_0.parameter.communication = 0;
bme280_0.parameter.I2CAddress = 0x77; //Choose I2C Address
bme280_0.parameter.sensorMode = 0b11; //Choose sensor mode
bme280_0.parameter.IIRfilter = 0b100; //Setup for IIR Filter
bme280_0.parameter.humidOversampling = 0b101; //Setup Humidity Oversampling
bme280_0.parameter.tempOversampling = 0b101; //Setup Temperature Oversampling
bme280_0.parameter.pressOversampling = 0b101; //Setup Pressure Oversampling
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")); }
//**********************************************************************

Wir wiederholen den Vorgang nun für den zweiten, dritten und vierten Sensor. Beachten Sie, dass wir die Initialisierung mit der Funktion tcaselect beginnen und dass jeder Sensor seine Instanz (bme280_1, bme280_2 und bme280_3) und seinen eigenen Parametersatz hat. Das bedeutet, dass wir für jeden Sensor eine andere Konfiguration verwenden können.

//*************INITIALIZING SECOND SENSOR*******************************
tcaselect(1);
bme280_1.parameter.communication = 0;
bme280_1.parameter.I2CAddress = 0x77; //Choose I2C Address
bme280_1.parameter.sensorMode = 0b11; //Choose sensor mode
bme280_1.parameter.IIRfilter = 0b100; //Setup for IIR Filter
bme280_1.parameter.humidOversampling = 0b101; //Setup Humidity Oversampling
bme280_1.parameter.tempOversampling = 0b101; //Setup Temperature Oversampling
bme280_1.parameter.pressOversampling = 0b101; //Setup Pressure Oversampling
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; //Choose I2C Address
bme280_2.parameter.sensorMode = 0b11; //Choose sensor mode
bme280_2.parameter.IIRfilter = 0b100; //Setup for IIR Filter
bme280_2.parameter.humidOversampling = 0b101; //Setup Humidity Oversampling
bme280_2.parameter.tempOversampling = 0b101; //Setup Temperature Oversampling
bme280_2.parameter.pressOversampling = 0b101; //Setup Pressure Oversampling
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; //Choose I2C Address
bme280_3.parameter.sensorMode = 0b11; //Choose sensor mode
bme280_3.parameter.IIRfilter = 0b100; //Setup for IIR Filter
bme280_3.parameter.humidOversampling = 0b101; //Setup Humidity Oversampling
bme280_3.parameter.tempOversampling = 0b101; //Setup Temperature Oversampling
bme280_3.parameter.pressOversampling = 0b101; //Setup Pressure Oversampling
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")); }
//**********************************************************************

Nach der Initialisierung der Sensoren gehen wir zur Schleifenfunktion und starten die Messungen. Zunächst beginnen wir mit der Funktion tcaselect(0). Wir verwenden drei Funktionen, um Werte für Temperatur (Funktion readTempC), Luftfeuchtigkeit (readHumidity) und Druck (readPressure) auszulesen. Wie zuvor verwenden Sie vor jeder Funktion die Instanz bme280_0, um den ersten Sensor anzusprechen.

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(F("Humidity1[%]=\t"));
Serial.print(bme280_0.readHumidity());
Serial.print("\t");
Serial.print(F("Pressure1[hPa]=\t"));
Serial.print(bme280_0.readPressure());
Serial.print("\t");
Serial.println();

Wenn wir das Gleiche für die verbleibenden drei Sensoren wiederholen, erhalten wir den Rest des Codes. Laden Sie nun den Code hoch und öffnen Sie den seriellen Monitor mit einer Baudgeschwindigkeit von 9600, um die Temperatur, Luftfeuchtigkeit und den Druck aller vier Sensoren abzurufen.

Lassen Sie uns den Code ausführen!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert