TCA9548A + 8x BME280: Probleme initialisierung [Gelöst]

Hallo Forum.
Ich wollte mal zur Abwechslung zu meinen Serial Problemen was "einfaches" machen.

Ich habe eine Arduino Mega per I2C mit einem TCA9548A verbunden.
Am TCA9548A sind 8 BME280 angeschlossen.

Da man die Adresse der BME280 nicht ändern kann wollte ich diese mit dem TCA abfragen.

Nur leider habe ich das Problem, dass ich erst die Daten von allen 8 BME bekomme wenn ich nach und nach zum ablauf des Loops den Reset am Adruino drücke

Erst dann bekomme ich eine Verbindung und die Informationen.

Die Delays sind der einfachheit halber drin zum testen.

Was mich einfach wurmt ist das ich nicht dahinter komme wie ich die BME's direkt per Code zum laufen bekomme ohne reset.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>


Adafruit_BME280 bme0;
Adafruit_BME280 bme1;
Adafruit_BME280 bme2;
Adafruit_BME280 bme3;
Adafruit_BME280 bme4;
Adafruit_BME280 bme5;
Adafruit_BME280 bme6;
Adafruit_BME280 bme7;


//Adafruit_BME280 bme;



#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);
  //bme.begin();


  bme0.begin();
  bme1.begin();
  bme2.begin();
  bme3.begin();
  bme4.begin();
  bme5.begin();
  bme6.begin();
  bme7.begin();

}


void loop()
{

  tcaselect(0);
  Serial.println("tcaselect(0)");
  Serial.print("Temperature = ");
  Serial.print(bme0.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme0.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();


  delay(2000);                            //Hier drücke ich immer den Reset Button am Arduino und das bei
                                               //jedem Einzelenen von 0 bis 7
                                               //Nach dem Reset bekomme ich dann die Daten vom BME

  tcaselect(1);
  Serial.println("tcaselect(1)");
  Serial.print("Temperature = ");
  Serial.print(bme1.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme1.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(2);
  Serial.println("tcaselect(2)");
  Serial.print("Temperature = ");
  Serial.print(bme2.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme2.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(3);
  Serial.println("tcaselect(3)");
  Serial.print("Temperature = ");
  Serial.print(bme3.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme3.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(4);
  Serial.println("tcaselect(4)");
  Serial.print("Temperature = ");
  Serial.print(bme4.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme4.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(5);
  Serial.println("tcaselect(5)");
  Serial.print("Temperature = ");
  Serial.print(bme5.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme5.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(6);
  Serial.println("tcaselect(6)");
  Serial.print("Temperature = ");
  Serial.print(bme6.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme6.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(7);
  Serial.println("tcaselect(7)");
  Serial.print("Temperature = ");
  Serial.print(bme7.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme7.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);
}

Was mich aber weiter Wundert ist das wenn ich mit dem I2C (TCA) Scanner an die Sache ran gehe findet er sofort jeden BME.

/*
  TCA9548 I2CScanner.pde -- I2C bus scanner for Arduino

  Based on code c. 2009, Tod E. Kurt, http://todbot.com/blog/

*/

#include "Wire.h"

extern "C" {
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}

#define TCAADDR 0x70


void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}


void setup()
{
  while (!Serial);
  delay(1000);

  Wire.begin();

  Serial.begin(9600);
  Serial.println("\nTCAScanner ready!");

  for (uint8_t t = 0; t < 8; t++) {
    tcaselect(t);
    Serial.print("TCA Port #"); Serial.println(t);

    for (uint8_t addr = 0; addr <= 127; addr++) {
      if (addr == TCAADDR) continue;

      uint8_t data;
      if (! twi_writeTo(addr, &data, 0, 1, 1)) {
        Serial.print("Found I2C 0x");  Serial.println(addr, HEX);
      }
    }
  }
  Serial.println("\ndone");

}



void loop()
{

}

Hier die serielle Ausgabe

TCAScanner ready!
TCA Port #0
Found I2C 0x76
TCA Port #1
Found I2C 0x76
TCA Port #2
Found I2C 0x76
TCA Port #3
Found I2C 0x76
TCA Port #4
Found I2C 0x76
TCA Port #5
Found I2C 0x76
TCA Port #6
Found I2C 0x76
TCA Port #7
Found I2C 0x76

done

Du musst vor jedem bmeX.begin() erst diesen BME über den TCA9548A auswählen. Wie sollen die Daten sonst dahin kommen?

Gruß Tommy

Tommy56:
Du musst vor jedem bmeX.begin() erst diesen BME über den TCA9548A auswählen. Wie sollen die Daten sonst dahin kommen?

Gruß Tommy

Oh Mann das ich darauf nicht gekommen bzw. das jetzt nicht gesehen hatte, ist mit ehrlich gesagt peinlich.

Dank dir für den Hinweis.

Gruß
Micha

Hi

Da hier 8x genau das Gleiche gemacht wird, kann man sich Da nicht 7 der Instanzen sparen?
Stelle mir das so vor, daß nach jedem TCA-Select und bme.beginn() der TCA weiter geschaltet wird und die letzte BME-Instanz wieder zerstört wird.
Außer beim letzten BME.
Wenn jetzt der TCA umgeschaltet wird, sind sämtliche BME identisch konfiguriert und sollten ebenso identisch funktionieren.

MfG

postmaster-ino:
Stelle mir das so vor, daß nach jedem TCA-Select und bme.beginn() der TCA weiter geschaltet wird und die letzte BME-Instanz wieder zerstört wird.

Warum und vor allem wodurch sollte da eine Instanz zerstört werden?

Gruß Tommy

Hi

Das meine ich: Da wird Nichts zerstört - deshalb werden wohl 8 Instanzen der BME-Lib im SPeicher 'ihr Unwesen treiben' - wo mir eine Instanz reichen müsste.
Dem Arduino ist's egal, Welcher der 8 BME antwortet, Er würde mit der letzten erstellten Instanz alle 8 BME 'verstehen' können, für Ihn sind Das eh nur neue Daten.
Daher meine ich, daß man die vorherigen Instanzen gar nicht braucht.
Vll. reicht auch EINE Instanz, ich rufe aber die .begin()-Methode bei jedem der BME 1x auf - müsste in die Lib schauen, was Da passiert, nicht, daß dort z.B. Speicher reserviert wird.

Adafruit_BME280 bme0;
Adafruit_BME280 bme1;
Adafruit_BME280 bme2;
Adafruit_BME280 bme3;
Adafruit_BME280 bme4;
Adafruit_BME280 bme5;
Adafruit_BME280 bme6;
Adafruit_BME280 bme7;

Das müsste sich doch durch EINE Zeile genau so erledigen lassen, oder?
Dann im setup() für jeden TCA-Aufruf (für jede Umschaltung) die .begin() aufgerufen, und der jeweilige BME ist eingestellt.
In der loop() dann wieder für jeden TCA-Aufruf die Daten auslesen, fertig.

Vll. habe ich mich blöd ausgedrückt, wenn nur eine Instanz erstellt wird und Diese mehrfach benutzt wird, muß natürlich Keine davon wieder zerstört werden.

MfG

postmaster-ino:
Hi

Das meine ich: Da wird Nichts zerstört - deshalb werden wohl 8 Instanzen der BME-Lib im SPeicher 'ihr Unwesen treiben' - wo mir eine Instanz reichen müsste.
Dem Arduino ist's egal, Welcher der 8 BME antwortet, Er würde mit der letzten erstellten Instanz alle 8 BME 'verstehen' können, für Ihn sind Das eh nur neue Daten.
Daher meine ich, daß man die vorherigen Instanzen gar nicht braucht.
Vll. reicht auch EINE Instanz, ich rufe aber die .begin()-Methode bei jedem der BME 1x auf - müsste in die Lib schauen, was Da passiert, nicht, daß dort z.B. Speicher reserviert wird.

Adafruit_BME280 bme0;

Adafruit_BME280 bme1;
Adafruit_BME280 bme2;
Adafruit_BME280 bme3;
Adafruit_BME280 bme4;
Adafruit_BME280 bme5;
Adafruit_BME280 bme6;
Adafruit_BME280 bme7;



Das müsste sich doch durch EINE Zeile genau so erledigen lassen, oder?
Dann im setup() für jeden TCA-Aufruf (für jede Umschaltung) die .begin() aufgerufen, und der jeweilige BME ist eingestellt.
In der loop() dann wieder für jeden TCA-Aufruf die Daten auslesen, fertig.

Vll. habe ich mich blöd ausgedrückt, wenn nur eine Instanz erstellt wird und Diese mehrfach benutzt wird, muß natürlich Keine davon wieder zerstört werden.

MfG

Hi.
Danke für den Tip.

Hab es gleich mal umgesetzt und getestet

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

Adafruit_BME280 bme;

#define TCAADDR 0x70


void tcaselect(uint8_t i)
{
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

void setup()
{

  Wire.begin();
  Serial.begin(9600);

  tcaselect(0);
  bme.begin();

  tcaselect(1);
  bme.begin();

  tcaselect(2);
  bme.begin();

  tcaselect(3);
  bme.begin();

  tcaselect(4);
  bme.begin();

  tcaselect(5);
  bme.begin();

  tcaselect(6);
  bme.begin();

  tcaselect(7);
  bme.begin();
}


void loop()
{

  tcaselect(0);
  Serial.println("tcaselect(0)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(1);
  Serial.println("tcaselect(1)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(2);
  Serial.println("tcaselect(2)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(3);
  Serial.println("tcaselect(3)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(4);
  Serial.println("tcaselect(4)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(5);
  Serial.println("tcaselect(5)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(6);
  Serial.println("tcaselect(6)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(7);
  Serial.println("tcaselect(7)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);

}

Läuft.

Gruß
Micha

Danke für die Rückmeldung. Da haben Postmaster-ino für die Idee und Du für den Test den Nachnutzern einiges an Speicher gespart.

Das funktioniert aber nicht automatisch bei jedem IC. Man muss da schauen/probieren, ob er vorher gespeicherte Werte braucht.

Gruß Tommy

Hi

@Micha
Danke für die Umsetzung :slight_smile:
Kannst Du noch Mal den alten Sketch drauf packen, was (oder ob überhaupt) Das für einen Unterschied im Speicher macht?

@Tommy
Klar, wenn die Lib Daten vom Sensor beibehält, wird Das nicht klappen - schadet aber bestimmt nicht, daß Das hier noch Mal erwähnt wurde.

MfG

@Postmaster-ino: Sonst denken einige, dass geht immer so.
Meistens wird es auch so funktionieren, aber immer mit Sicherheit nicht.

Gruß Tommy

postmaster-ino:
Hi

@Micha
Danke für die Umsetzung :slight_smile:
Kannst Du noch Mal den alten Sketch drauf packen, was (oder ob überhaupt) Das für einen Unterschied im Speicher macht?

MfG

Klar kann ich das machen.

Sketch V1

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

Adafruit_BME280 bme0;
Adafruit_BME280 bme1;
Adafruit_BME280 bme2;
Adafruit_BME280 bme3;
Adafruit_BME280 bme4;
Adafruit_BME280 bme5;
Adafruit_BME280 bme6;
Adafruit_BME280 bme7;

#define TCAADDR 0x70


void tcaselect(uint8_t i)
{
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

void setup()
{

  Wire.begin();
  delay(100);
  Serial.begin(9600);
  delay(100);

  tcaselect(0);
  bme0.begin();
  delay(100);

  tcaselect(1);
  bme1.begin();
  delay(100);

  tcaselect(2);
  bme2.begin();
  delay(100);

  tcaselect(3);
  bme3.begin();
  delay(100);

  tcaselect(4);
  bme4.begin();
  delay(100);

  tcaselect(5);
  bme5.begin();
  delay(100);

  tcaselect(6);
  bme6.begin();
  delay(100);

  tcaselect(7);
  bme7.begin();
  delay(100);

}


void loop()
{

  tcaselect(0);
  Serial.println("tcaselect(0)");
  Serial.print("Temperature = ");
  Serial.print(bme0.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme0.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();


  delay(2000);



  tcaselect(1);
  Serial.println("tcaselect(1)");
  Serial.print("Temperature = ");
  Serial.print(bme1.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme1.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();


  delay(2000);



  tcaselect(2);
  Serial.println("tcaselect(2)");
  Serial.print("Temperature = ");
  Serial.print(bme2.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme2.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();



  delay(2000);



  tcaselect(3);
  Serial.println("tcaselect(3)");
  Serial.print("Temperature = ");
  Serial.print(bme3.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme3.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(4);
  Serial.println("tcaselect(4)");
  Serial.print("Temperature = ");
  Serial.print(bme4.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme4.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(5);
  Serial.println("tcaselect(5)");
  Serial.print("Temperature = ");
  Serial.print(bme5.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme5.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(6);
  Serial.println("tcaselect(6)");
  Serial.print("Temperature = ");
  Serial.print(bme6.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme6.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();


  delay(2000);


  tcaselect(7);
  Serial.println("tcaselect(7)");
  Serial.print("Temperature = ");
  Serial.print(bme7.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme7.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);

}

Speicher V1

Der Sketch verwendet 9278 Bytes (3%) des Programmspeicherplatzes. Das Maximum sind 253952 Bytes.
Globale Variablen verwenden 957 Bytes (11%) des dynamischen Speichers, 7235 Bytes für lokale Variablen verbleiben. Das Maximum sind 8192 Bytes.

Sketch V2

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

Adafruit_BME280 bme;

#define TCAADDR 0x70


void tcaselect(uint8_t i)
{
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

void setup()
{

  Wire.begin();
  Serial.begin(9600);

  tcaselect(0);
  bme.begin();

  tcaselect(1);
  bme.begin();

  tcaselect(2);
  bme.begin();

  tcaselect(3);
  bme.begin();

  tcaselect(4);
  bme.begin();

  tcaselect(5);
  bme.begin();

  tcaselect(6);
  bme.begin();

  tcaselect(7);
  bme.begin();
}


void loop()
{

  tcaselect(0);
  Serial.println("tcaselect(0)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(1);
  Serial.println("tcaselect(1)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(2);
  Serial.println("tcaselect(2)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(3);
  Serial.println("tcaselect(3)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(4);
  Serial.println("tcaselect(4)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(5);
  Serial.println("tcaselect(5)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(6);
  Serial.println("tcaselect(6)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);


  tcaselect(7);
  Serial.println("tcaselect(7)");
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Serial.println();
  Serial.println();

  delay(2000);

}

Speicher V2

Der Sketch verwendet 9164 Bytes (3%) des Programmspeicherplatzes. Das Maximum sind 253952 Bytes.
Globale Variablen verwenden 600 Bytes (7%) des dynamischen Speichers, 7592 Bytes für lokale Variablen verbleiben. Das Maximum sind 8192 Bytes.