Problem mit der Verbindung mehrerer I2C-Sensoren

Problembeschreibung

Ich arbeite an einem Projekt mit mehreren Näherungssensoren (AdaFruit VCNL4040). Es gibt 8 solcher Sensoren, die über einen I2C-Multiplexer (NXP PCA9547) verbunden sind. Zusätzlich muss ich einen zusätzlichen Sensor hinzufügen, den ich direkt mit dem I2C-Bus verbinden muss. Der zusätzliche Sensor ist vom gleichen Typ wie die gemultiplexten und hat die gleiche I2C-Adresse.

Geben Sie hier die Bildbeschreibung ein

Code

Erstellung von MUX- und Sensorobjekten.

#include <Arduino.h>
#include "PCA9547.h"
#include <Adafruit_VCNL4040.h>

PCA9547 i2c_select = PCA9547();
Adafruit_VCNL4040 proxy_mux = Adafruit_VCNL4040();
Adafruit_VCNL4040 proxy_extra = Adafruit_VCNL4040(); //

setup()Funktion. Beachten Sie, dass ich dasselbe Objekt der Klasse verwende AdaFruit_VCNL4040, um mit den Multiplex-Sensoren ( proxy_mux) und einem zweiten für den Extra-Sensor ( proxy_extra) zu kommunizieren.

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH); //RESET pin for MUX (HIGH for operation

  Wire.begin(); //Join i2c bus

  i2c_select.attatch(Wire);
  i2c_select.setAddress(0,0,0);
  i2c_select.disable();

    // Start with the setup of the extra sensor. 
  if (!proxy_extra.begin()) {
    Serial.println("Couldn't find VCNL4040 chip");
    while (1);
  }

  proxy_extra.enableProximity(true);
  proxy_extra.enableProximityInterrupts(VCNL4040_PROXIMITY_INT_CLOSE_AWAY);
  proxy_extra.setProximityLowThreshold(100);
  delay(200);
  proxy_extra.setProximityHighThreshold(120);
  delay(200);

    //Enable the Multiplexed sensors
  for (int i = 0; i < 8; i++){
    i2c_select.enable(i);
    if (!proxy_mux.begin()) {
      Serial.println("Couldn't find VCNL4040 chip");
      while (1);
    }
  }
    
    //Sensor settings for the Multiplexed sensors. 
  for (int i = 0; i < 8; i++){
    i2c_select.enable(i);
    proxy_mux.enableProximity(true);

    proxy_mux.enableProximityInterrupts(VCNL4040_PROXIMITY_INT_CLOSE_AWAY);
    proxy_mux.setProximityLowThreshold(100);
    delay(200);
    proxy_mux.setProximityHighThreshold(120);
    delay(200);

  }
}

loop()Funktion und Drucken von MUX-Sensorwerten.

void printProximityValues(){

    unsigned int vals[8];

    for (int i = 0; i < 8; i++){
        // WeightStackSensor::tcaselect(i);
        i2c_select.enable(i);
        vals[i] = proxy_mux.getProximity();
        delay(50);
    }

    char valsString[128];
    sprintf(valsString,
    "%u,%u,%u,%u,%u,%u,%u,%u,",
    vals[0],
    vals[1],
    vals[2],
    vals[3],
    vals[4],
    vals[5],
    vals[6],
    vals[7]);
  
    Serial.println(valsString);
    i2c_select.disable();

}

void loop() {
  // put your main code here, to run repeatedly:
  printProximityValues();
  delay(100);

  int extra_val = proxy_extra.getProximity();
  Serial.print("EXTRA:");
  Serial.println(extra_val);

}

Verhalten

Werte von den Multiplex-Sensoren erscheinen nur, wenn der Extra-Sensor betätigt wird. Wenn über den Zusatzsensor keine Näherungswerte gelesen werden, erscheinen die Näherungswerte vom MUX-Sensor als 0.

Beispielausgabe

Sowohl Multiplex-Sensoren als auch Näherungssensoren

MUX-Sensoren aktiviert und zusätzlicher Sensor NICHT aktiviert – FALSCHES VERHALTEN . Die MUX-Näherungswerte sollten zwischen 260 und 300 liegen

16:10:19.737 -> MUX VALS: 0,0,0,0,0,0,0,0 |EXTRA:0
16:10:20.267 -> MUX VALS: 0,0,0,0,0,0,0,0 |EXTRA:0
16:10:20.829 -> MUX VALS: 0,0,0,0,0,0,0,0 |EXTRA:0
16:10:21.392 -> MUX VALS: 0,0,0,0,0,0,0,0 |EXTRA:0

MUX-Sensoren aktiviert und zusätzlicher Sensor aktiviert

16:07:49.735 -> MUX VALS: 282,260,260,266,292,256,305,256 |EXTRA:308
16:07:50.265 -> MUX VALS: 292,258,256,275,288,256,309,306 |EXTRA:311
16:07:50.827 -> MUX VALS: 293,288,262,276,294,260,306,292 |EXTRA:309
16:07:51.390 -> MUX VALS: 292,273,261,276,292,256,304,308 |EXTRA:307

Es scheint, dass die Sensorwerte den Werten des Extrasensors folgen?

Extra Sensor deaktivieren und trennen

Die Näherungswerte für die Multiplex-Sensoren sind hoch, was die richtige Funktionalität ist.

16:15:26.425 -> MUX VALS: 308,379,365,236,289,198,171,173 |
16:15:26.954 -> MUX VALS: 307,378,364,224,273,189,161,165 |
16:15:27.484 -> MUX VALS: 297,376,356,216,258,176,149,153 |
16:15:28.047 -> MUX VALS: 296,365,351,218,270,182,153,155 |

Die MUX-Sensoren und der Extra-Sensor funktionieren korrekt, wenn sie getrennt sind. Wenn es jedoch so aussieht, als ob die MUX-Sensorwerte nicht angezeigt werden, es sei denn, der Extra-Sensor wird betätigt. Warum scheinen sie nicht entkoppelt und voneinander abhängig zu sein, was nicht der Fall sein sollte?

Sie haben acht Kanäle, aber neun Sensoren. Sie haben Adresskonflikte.
"Zusätzlich muss ich einen zusätzlichen Sensor hinzufügen, den ich direkt mit dem I2C-Bus verbinden muss. Der zusätzliche Sensor ist vom gleichen Typ wie die gemultiplexten und hat die gleiche I2C-Adresse ." Warum denkst du, dass das funktionieren wird? Es ist genau das Problem, das Ihr Mux vermutlich lösen sollte (aber Sie besiegen den Mux mit dem zusätzlichen Sensor).
Wenn ich das Kanalsteuerregister auf "kein Kanal ausgewählt" setze, könnte ich dann nicht die Extra-Sensor-Register lesen, während ich die an den Multiplexer angeschlossenen Sensoren ignoriere? Die Funktion 'i2c_select.disable()' setzt das Steuerregister auf 0, was ein Befehl "kein Kanal ausgewählt" sein sollte.
Nein, ich habe mich geirrt, die anderen Kommentare sind richtig. Wenn Sie Mux auf "keine Kanäle" einstellen, sollten Sie in der Lage sein, zusätzliche Sensoren zu lesen. ABER wenn Sie einen beliebigen Kanal auswählen, haben Sie immer noch diesen zusätzlichen Sensor angeschlossen und er wird den ausgewählten stören
Der Multiplexer ermöglicht die Koexistenz von 8 Geräten mit derselben Adresse auf demselben I2C-Bus, ändert jedoch nicht die I2C-Adresse des Geräts. Ihr 9. steht im Konflikt mit dem Multiplex. Sie könnten den Multiplexer deaktivieren, um 9. zu lesen, aber 9. wird IMMER mit allen anderen in Konflikt geraten. Keine Lösung.

Antworten (3)

Sie können keinen Sensor hinter dem Mux an der Adresse X lesen oder schreiben, da Sie bereits einen Sensor haben, der immer an der gleichen Adresse X am Bus ist und auf die gleichen Lese- und Schreibvorgänge reagiert, und Sie können nicht immer verbunden sein Sensor, das in irgendeiner Weise zu ignorieren.

Es gibt keine Softwarelösung. Sie müssen einen neuen Multiplexer an einer neuen Adresse für den 9. hinzufügen oder den 9. auf einen neuen I2C-Port verschieben (falls verfügbar).

Der Multiplexer ermöglicht die Koexistenz von 8 Geräten mit derselben Adresse auf demselben I2C-Bus, ändert jedoch nicht die I2C-Adresse des Geräts.

Ihr 9. steht im Konflikt mit dem, der gerade gemultiplext wird. Sie könnten den Multiplexer deaktivieren (über das Steuerregister - kein Kanal ausgewählt), um den 9. zu lesen, aber der 9. wird IMMER mit allen anderen in Konflikt geraten. Der Multiplexer schaltet SCK und SDA auf einen der 8 Busse.

Von PCA9547 - 8-Kanal-I2C-Bus-Multiplexer mit Reset :

Geben Sie hier die Bildbeschreibung ein

Aus: Anwendungshinweis – AN262_2 PCA954X-Familie von I²C-/SMBus-Multiplexern und -Schaltern :

Sobald ein oder mehrere Kanäle ausgewählt wurden, fungiert das Gerät als Draht , der es dem Master auf dem Upstream-Kanal ermöglicht, Befehle an Geräte auf allen aktiven Downstream-Kanälen zu senden, und Geräten auf den aktiven Downstream-Kanälen, miteinander und mit dem Master zu kommunizieren .

Die 9. und die 1 auf dem aktivierten Kanal stehen immer in Konflikt (0x60). Sie haben ein Upstream-Gerät UND ein Downstream-Gerät. Tatsächlich wählt 0x60 zwei Geräte aus.

Sie benötigen entweder MUX mit mehr Kanälen oder einen zweiten MUX, der mit einer anderen Adresse konfiguriert ist, oder einen anderen Sensor, der die Adressauswahl für dieses 9. Gerät ermöglicht.

AKTUALISIEREN:

Das bedeutet, dass ich die Exta-Sensor-Register nicht einstellen kann. Sobald ich den MUX aktiviere und versuche, in die Register zu schreiben, würden die Register des zusätzlichen Sensors überschrieben?

Natürlich können Sie Extra-Sensor-Register einstellen.

  • Ich konnte keinen I2C-MUX mit mehr als 8 Kanälen finden, daher denke ich, dass Sie die erste Option ignorieren können.

  • Wenn Sie mit zusätzlichem MUX arbeiten, aktivieren Sie nur einen der beiden MUXs und sprechen dann mit einem der Slave-Sensoren auf diesem MUX. Dies umfasst sowohl das Setzen seiner Register als auch das Lesen seiner Daten.

Ihr Code wird wie folgt aussehen:

  1. Aktivieren Sie MUX 1
  2. Wählen Sie einen MUX1-Kanal nach dem anderen aus und lesen (oder schreiben) Sie die Register des Sensors auf dem aktuellen Kanal
  3. MUX 1 deaktivieren, MUX 2 aktivieren
  4. Wählen Sie einen MUX2-Kanal nach dem anderen aus und lesen (oder schreiben) Sie die Register des Sensors auf dem aktuellen Kanal
  • Wenn Sie ähnliche Sensoren mit konfigurierbarer Adresse finden, stellen Sie eine Adresse für alle MUX-fähigen Sensoren und eine andere Adresse für zusätzliche Sensoren ein. Wenn MUX dann deaktiviert ist, verwenden Sie eine zusätzliche Sensoradresse, um mit diesem einen Sensor zu kommunizieren. Wenn MUX aktiviert ist, verwenden Sie eine gemeinsame Adresse, um mit einem Sensor zu kommunizieren, der derzeit über MUX verbunden ist. Dies beinhaltet wiederum sowohl das Setzen seiner Register als auch das Lesen seiner Daten.

Ihr Code wird wie folgt aussehen:

  1. MUX aktivieren
  2. Wählen Sie die MUX-Kanäle einzeln aus und lesen (oder schreiben) Sie die Register des Sensors auf dem aktuellen Kanal mit der Adresse 1
  3. MUX deaktivieren
  4. Lesen (oder schreiben) Sie die Register des zusätzlichen Sensors mit Adresse 2

Beachten Sie, dass Sie unabhängig von der gewählten Option immer nur mit einem Sensor arbeiten. Das heißt, Sie können die Register aller MUX-Sensoren nicht gleichzeitig einstellen, Ihre Software muss sie einzeln durchlaufen. Und dann deaktivieren Sie MUX und tun es noch einmal für zusätzlichen Sensor.

Das bedeutet, dass ich die Exta-Sensor-Register nicht einstellen kann. Sobald ich den MUX aktiviere und versuche, in die Register zu schreiben, würden die Register des zusätzlichen Sensors überschrieben?
@jquinno Der zusätzliche Sensor sieht immer, was Sie an die anderen 8 Sensoren senden, und weiß nicht, dass Sie versuchen, mit einem anderen Sensor zu sprechen.
@jquinno siehe ein Update