Issue reading more than 14 BMP280 sensors

Hi everyone,
I’m working on reading data from 20 BMP280 sensors using a Redboard and 3 TCA9458A multiplexers. I know I could use 2 multiplexers by adjusting sensor adressess but I want to keep the setup very simple.

The problem I’am encountering is related to the number of sensors red. When I’m attempting to read a total of more than 14 sensors regardless how many are connected to multiplexers. All sensors are being initilized correctly but I read only the first 10 of them.

All multiplexers and sensors are working. The wiring is good. I also checked the power supply from the board. The code seems to be good too.

I don’t understand what’s happening. Maybe someone here can help me to solve this issue.

Here is my setup and my code. The first multiplexer connected to the board with tha adress 0X70 the second one 0X71 and the third one 0X72. On the image there is only 17 sensors.

#include <Wire.h>
#include <Adafruit_BMP280.h>

// Define the number of sensors per multiplexer
#define NUMBER_OF_SENSORS_BMP280_MUX1 8
#define NUMBER_OF_SENSORS_BMP280_MUX2 6
#define NUMBER_OF_SENSORS_BMP280_MUX3 0

//Addresses of multiplexers
#define MUX1_ADDR 0x70  
#define MUX2_ADDR 0x71 
#define MUX3_ADDR 0x72

int counter = 0;
Adafruit_BMP280 bmp280[NUMBER_OF_SENSORS_BMP280_MUX1 + NUMBER_OF_SENSORS_BMP280_MUX2 + NUMBER_OF_SENSORS_BMP280_MUX3]; // BMP280 sensors

// Function to control the TCA9548A multiplexer (with address)

void selectMultiplexer(uint8_t muxAddress, uint8_t bus) {
  uint8_t busMask = 0;
  if (bus < 8) busMask = 1 << bus; // Bus must be between 0 and 7, otherwise all channels will be disabled
  Wire.beginTransmission(muxAddress); // TCA9548A address
  Wire.write(busMask); // Select the bus
  Wire.endTransmission();
}

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000); // I2C clock speed

  // Initialize the sensors on the 1st multiplexer (address 0x70)

  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX1; i++) {
    selectMultiplexer(MUX1_ADDR, i); // Select the bus
    if (!bmp280[i].begin(0x76)) { // Initialize the BMP280 sensor
      Serial.print("Could not find BMP280 sensor on MUX1 port ");
      Serial.println(i);
    } else {
      Serial.print("BMP280 sensor initialized on MUX1 port ");
      Serial.println(i);
    }
    delay(500);
    selectMultiplexer(MUX1_ADDR, 0xFF); // Disable the bus
  }

  // Initialize the sensors on the 2nd multiplexer (address 0x71)

  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX2; i++) {
    selectMultiplexer(MUX2_ADDR, i); // Select the bus on the 2nd multiplexer
    if (!bmp280[i + NUMBER_OF_SENSORS_BMP280_MUX1].begin(0x76)) { // Initialize the BMP280 sensor
      Serial.print("Could not find BMP280 sensor on MUX2 port ");
      Serial.println(i);
    } else {
      Serial.print("BMP280 sensor initialized on MUX2 port ");
      Serial.println(i);
    }
    delay(500);
    selectMultiplexer(MUX2_ADDR, 0xFF); // Disable the bus
  }
   // Initialize the sensors on the 3rd multiplexer (address 0x72)

  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX3; i++) {
    selectMultiplexer(MUX3_ADDR, i); // Select the bus
    if (!bmp280[i + NUMBER_OF_SENSORS_BMP280_MUX1 + NUMBER_OF_SENSORS_BMP280_MUX2].begin(0x76)) { // Initialize the BMP280 sensor
      Serial.print("Could not find BMP280 sensor on MUX3 port ");
      Serial.println(i);
    } else {
      Serial.print("BMP280 sensor initialized on MUX3 port ");
      Serial.println(i);
    }

    delay(500);
    selectMultiplexer(MUX3_ADDR, 0xFF); // Disable the bus
  }
   String headers = "";
  
  // MUX1 Headers
  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX1; i++) {
    headers += "     MUX1_S" + String(i);
  }

  // MUX2 Headers
  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX2; i++) {
    headers += "    MUX2_S" + String(i);
  }

  // MUX3 Headers
  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX3; i++) {
    headers += "MUX3_S" + String(i) + "    ";
  }

  // Send the headers
  Serial.println(headers);
}

void loop() {
  String output = ""; // Declare the output string
  Serial.print(counter);
  Serial.print(" | ");
  // Read BMP280 sensors on the 1st multiplexer
  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX1; i++) {
    selectMultiplexer(MUX1_ADDR, i); // Select the bus
    float pressure = bmp280[i].readPressure(); // Read data from BMP280 sensor
     output +=String(pressure) + " ; ";//output += "S" +  String(i) + " MUX1 " + String(pressure) + " Pa "; output +=String(pressure) + " ; ";
    selectMultiplexer(MUX1_ADDR, 0xFF); // Disable the bus
  }

  // Read BMP280 sensors on the 2nd multiplexer
  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX2; i++) {
    selectMultiplexer(MUX2_ADDR, i); // Select the bus on the 2nd multiplexer
    float pressure = bmp280[i + NUMBER_OF_SENSORS_BMP280_MUX1].readPressure(); // Read data from BMP280 sensor
    output +=String(pressure) + " ; ";
    selectMultiplexer(MUX2_ADDR, 0xFF); // Disable the bus
  }

  // Read BMP280 sensors on the 3rd multiplexer
  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX3; i++) {
    selectMultiplexer(MUX3_ADDR, i); // Select the bus on the 2nd multiplexer
    float pressure = bmp280[i + NUMBER_OF_SENSORS_BMP280_MUX1 + NUMBER_OF_SENSORS_BMP280_MUX2].readPressure(); // Read data from BMP280 sensor
     output +=String(pressure) + " ; ";
    selectMultiplexer(MUX3_ADDR, 0xFF); // Disable the bus
  }
  Serial.println(output);
  delay(10);

  counter++; // Increment the counter
  if (counter >= 10) {
    while (1); // Infinite loop after 30 readings
  }
}

I only see a total of 14 sensor ports enabled:

#define NUMBER_OF_SENSORS_BMP280_MUX1 8
#define NUMBER_OF_SENSORS_BMP280_MUX2 6
#define NUMBER_OF_SENSORS_BMP280_MUX3 0

Could that be your issue ?

No, I use this to change the number of sensors on each multiplexer.
For example when I set the number of sensors on MUX2 to 7 so #define NUMBER_OF_SENSORS_BMP280_MUX2 7 and keep 8 on the first one. It deosn’t let me read 15 of them but instead I reiceve data from 10 of them.

When I get back to 14 sensors I manage to read all of them. I can’t read more than 14.

understand.

Also wondering about the allocation of the constructor. Will that really create many instances or just a table to hold the instances ??

Adafruit_BMP280 bmp280[NUMBER_OF_SENSORS_BMP280_MUX1 + NUMBER_OF_SENSORS_BMP280_MUX2 + NUMBER_OF_SENSORS_BMP280_MUX3]; // BMP280 sensors

Maybe try this. I know it is a bit clumsy but just for test :
global define

Adafruit_BMP280 bmp2811;  // mux1
Adafruit_BMP280 bmp2812;
Adafruit_BMP280 bmp2813;
Adafruit_BMP280 bmp2814;
Adafruit_BMP280 bmp2815;
Adafruit_BMP280 bmp2816;
Adafruit_BMP280 bmp2817;
Adafruit_BMP280 bmp2818;
Adafruit_BMP280 bmp2821;  // mux2
Adafruit_BMP280 bmp2822;
Adafruit_BMP280 bmp2823;
Adafruit_BMP280 bmp2824;
Adafruit_BMP280 bmp2825;
Adafruit_BMP280 bmp2826;

in setup() now do :

bmp280[0] = bmp2811;   // mux1
bmp280[1] = bmp2812;
bmp280[2] = bmp2813;
bmp280[3] = bmp2814;
bmp280[4] = bmp2815;
bmp280[5] = bmp2816;
bmp280[6] = bmp2817;
bmp280[7] = bmp2818;

bmp280[8] = bmp2821;  //mux2
bmp280[9] = bmp2822;
bmp280[10] = bmp2823;
bmp280[11] = bmp2824;
bmp280[12] = bmp2825;
bmp280[13] = bmp2826;

Leave the rest the same and see what happens …

Also wondering about the allocation of the constructor. Will that really create many instances or just a table to hold the instances ??

Adafruit_BMP280 bmp280[NUMBER_OF_SENSORS_BMP280_MUX1 + NUMBER_OF_SENSORS_BMP280_MUX2 + NUMBER_OF_SENSORS_BMP280_MUX3]; // BMP280 sensors

This is to hold the instances.

I tried what you suggested but the serial monitor does not show anything. Not even the initialization of sensors.

Trying changing the constructors in the table to pointers to constructors.

I’m a beginner, I’dont understand what you mean sorry.

I also tried with the easiest code I could do. I have the same result the serial monitor doesn’t show anything and I can read a maximum of 13 sensors.

#include <Wire.h>
#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp2811;  // mux1
Adafruit_BMP280 bmp2812;
Adafruit_BMP280 bmp2813;
Adafruit_BMP280 bmp2814;
Adafruit_BMP280 bmp2815;
Adafruit_BMP280 bmp2816;
Adafruit_BMP280 bmp2817;
Adafruit_BMP280 bmp2818;

Adafruit_BMP280 bmp2820;  // mux2
Adafruit_BMP280 bmp2821;  
Adafruit_BMP280 bmp2822;
Adafruit_BMP280 bmp2823;
Adafruit_BMP280 bmp2824;
Adafruit_BMP280 bmp2825;
Adafruit_BMP280 bmp2826;
Adafruit_BMP280 bmp2827;

int counter = 0;
void selectMultiplexer(uint8_t muxAddress, uint8_t bus) {
  uint8_t busMask = 0;
  if (bus < 8) busMask = 1 << bus; // Bus must be between 0 and 7, otherwise all channels will be disabled
  Wire.beginTransmission(muxAddress); // TCA9548A address
  Wire.write(busMask); // Select the bus
  Wire.endTransmission();
}

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000); // I2C clock speed

selectMultiplexer (0x70, 0);
 if(!bmp2811.begin(0x76)){
  Serial.println("Sensor0 Mux 1 fail");
  while(1);
 }
 else{
    Serial.println("S0 MUX1 OK");
  }
 delay(500);
selectMultiplexer(0x70, 0xFF);

selectMultiplexer (0x70, 1);
 if(!bmp2812.begin(0x76)){
  Serial.println("Sensor1 Mux 1 fail");
  while(1);
 }
  delay(500);
selectMultiplexer(0x70, 0xFF);

selectMultiplexer (0x70, 2);
 if(!bmp2813.begin(0x76)){
  Serial.println("Sensor2 Mux 1 fail");
 while(1);
}
 delay(500);
selectMultiplexer(0x70, 0xFF);

selectMultiplexer (0x70, 3);
 if(!bmp2814.begin(0x76)){
  Serial.println("Sensor3 Mux 1 fail");
 while(1);
}
 delay(500);
selectMultiplexer(0x70, 0xFF);

selectMultiplexer (0x70, 4);
 if(!bmp2815.begin(0x76)){
  Serial.println("Sensor4 Mux 1 fail");
 while(1);
  delay(500);
}
selectMultiplexer(0x70, 0xFF);

selectMultiplexer (0x70, 5);
 if(!bmp2816.begin(0x76)){
  Serial.println("Sensor5 Mux 1 fail");
 while(1);
  delay(500);
}
selectMultiplexer(0x70, 0xFF);

selectMultiplexer (0x70, 6);
 if(!bmp2817.begin(0x76)){
  Serial.println("Sensor6 Mux 1 fail");
 while(1);
  delay(500);
}
selectMultiplexer(0x70, 0xFF);

selectMultiplexer (0x70, 7);
 if(!bmp2818.begin(0x76)){
  Serial.println("Sensor7 Mux 1 fail");
 while(1);
 delay(500);
}
else{
    Serial.println("S7 MUX1 OK");
  }

selectMultiplexer(0x70, 0xFF);

selectMultiplexer (0x71, 0);
 if(!bmp2820.begin(0x76)){
  Serial.println("Sensor0 Mux 2 fail");
 while(1);
 delay(500);
}
else{
    Serial.println("S0 MUX2 OK");
  }

selectMultiplexer(0x71, 0xFF);

selectMultiplexer (0x71, 1);
 if(!bmp2821.begin(0x76)){
  Serial.println("Sensor1 Mux 2 fail");
 while(1);
 delay(500);
}
selectMultiplexer(0x71, 0xFF);

selectMultiplexer (0x71, 2);
 if(!bmp2822.begin(0x76)){
  Serial.println("Sensor2 Mux 2 fail");
 while(1);
 delay(500);
}
selectMultiplexer(0x71, 0xFF);

selectMultiplexer (0x71, 3);
 if(!bmp2823.begin(0x76)){
  Serial.println("Sensor3 Mux 2 fail");
 while(1);
 delay(500);
}
selectMultiplexer(0x71, 0xFF);

selectMultiplexer (0x71, 4);
 if(!bmp2824.begin(0x76)){
  Serial.println("Sensor4 Mux 2 fail");
 while(1);
 delay(500);
}
else{
    Serial.println("S4 MUX2 OK");
  }
selectMultiplexer(0x71, 0xFF);

selectMultiplexer (0x71, 5);
 if(!bmp2825.begin(0x76)){
  Serial.println("Sensor5 Mux 2 fail");
 while(1);
 delay(500);
}
selectMultiplexer(0x71, 0xFF);

// selectMultiplexer (0x71, 6);
//  if(!bmp2826.begin(0x76)){
//   Serial.println("Sensor6 Mux 2 fail");
//  while(1);
//  delay(500);
// }
// selectMultiplexer(0x71, 0xFF);

// selectMultiplexer (0x71, 7);
//  if(!bmp2827.begin(0x76)){
//   Serial.println("Sensor7 Mux 2 fail");
//  while(1);
//  delay(500);
// }
// else{
//     Serial.println("S7 MUX2 OK");
//   }
// selectMultiplexer(0x71, 0xFF);



}
void loop() {
  Serial.print(counter);
  Serial.print(" | ");
  
  float bmp001 = 0.0;
  float bmp002 = 0;
  float bmp003 = 0;
  float bmp004 = 0;
  float bmp005 = 0;
  float bmp006 = 0;
  float bmp007 = 0;
  float bmp008 = 0;
  float bmp020 = 0;
  float bmp021 = 0;
  float bmp022 = 0;
  float bmp023 = 0;
  float bmp024 = 0;
  float bmp025 = 0;
  // float bmp026 = 0;
  // float bmp027 = 0;
 
selectMultiplexer(0x70, 0);
delay(50);
bmp001=bmp2811.readPressure();
selectMultiplexer(0x70, 0xFF);

selectMultiplexer(0x70, 1);
delay(50);
bmp002=bmp2812.readPressure();
selectMultiplexer(0x70, 0xFF);

selectMultiplexer(0x70, 2);
delay(50);
bmp003=bmp2813.readPressure();
selectMultiplexer(0x70, 0xFF);

selectMultiplexer(0x70, 3);
delay(50);
bmp004=bmp2814.readPressure();
selectMultiplexer(0x70, 0xFF);

selectMultiplexer(0x70, 4);
delay(50);
bmp005=bmp2815.readPressure();
selectMultiplexer(0x70, 0xFF);

selectMultiplexer(0x70, 5);
delay(50);
bmp006=bmp2816.readPressure();
selectMultiplexer(0x70, 0xFF);

selectMultiplexer(0x70, 6);
delay(50);
bmp007=bmp2817.readPressure();
selectMultiplexer(0x70, 0xFF);

selectMultiplexer(0x70, 7);
delay(50);
bmp008=bmp2818.readPressure();
selectMultiplexer(0x70, 0xFF);

selectMultiplexer(0x71, 0);
delay(50);
bmp020=bmp2820.readPressure();
selectMultiplexer(0x71, 0xFF);

selectMultiplexer(0x71, 1);
delay(50);
bmp021=bmp2821.readPressure();
selectMultiplexer(0x71, 0xFF);

selectMultiplexer(0x71, 2);
delay(50);
bmp022=bmp2822.readPressure();
selectMultiplexer(0x71, 0xFF);

selectMultiplexer(0x71, 3);
delay(50);
bmp023=bmp2823.readPressure();
selectMultiplexer(0x71, 0xFF);

selectMultiplexer(0x71, 4);
delay(50);
bmp024=bmp2824.readPressure();
selectMultiplexer(0x71, 0xFF);

selectMultiplexer(0x71, 5);
delay(50);
bmp025=bmp2825.readPressure();
selectMultiplexer(0x71, 0xFF);

// selectMultiplexer(0x71, 6);
// bmp026=bmp2826.readPressure();
// selectMultiplexer(0x71, 0xFF);

// selectMultiplexer(0x71, 7);
// bmp027=bmp2827.readPressure();
// selectMultiplexer(0x71, 0xFF);

Serial . println ( bmp001);
Serial . println ( bmp002);
Serial . println ( bmp003);
Serial . println ( bmp004);
Serial . println ( bmp005);
Serial . println ( bmp006);
Serial . println ( bmp007);
Serial . println ( bmp008);
Serial.println("MUX2");
Serial . println ( bmp020);
Serial . println ( bmp021);
Serial . println ( bmp022);
Serial . println ( bmp023);
Serial . println ( bmp024);
Serial . println ( bmp025);
// Serial . println ( bmp026);
//Serial . println ( bmp027);

  counter++; // Increment the counter
  if (counter >= 1) {
    while (1); 
  }
}

Your last test is a good one to start. I looked at the code and Adafruit is using a seperate i2C driver. Maybe there is something as well.

In the library Arduino_BusIO, file Adafruit_I2CDevice.cpp, Uncomment the line in the top:
//#define DEBUG_SERIAL Serial

Now recompile with the latest version and run. Maybe there is a message displayed to can help to find the root cause

Unfortunately, I still have the same problem but I think it’s due to memory storage. I managed to read 18 sensors now by changing the sensors adressess. When I add one more the same problem appears.
When I read 18 sensors the dynamic memory is 1429 bytes and the programm storage space is 13386 bytes.
However, when I try to read 19 sensors, the dynamic space increases to 1474 bytes and the programm storage space to13406 bytes and the serial monitor stop displaying. I will try to optimize my code to increase storage space. What do you think ?

so it looks the issue is related to memory usage. During program execution more memory is normally dynamically allocated and there is not enough of that available.
Which board to you use and can you share your latest sketch. I can try to help to reduce.

You can try a board that has more memory.

One aspect you can try also for each serial.print(“chris”); change to serial.print(F(“chris”)); this will store the printed message in program memory and increase a little the dynamic space (actually bcc-space).

1 Like

I finally sucessfully read all of the 20 sensors. I changed my code and I implemented what you suggested. The board I 'am using is the Redboard Qwiic.

#include <Wire.h>
#include <Adafruit_BMP280.h>

// Define the number of multiplexer
#define NUMBER_OF_MULTIPLEXER 2

// Define the number of sensors per multiplexer
#define NUMBER_OF_SENSORS_BMP280_MUX1 12
#define NUMBER_OF_SENSORS_BMP280_MUX2 8

// Multiplexer adresses
#define MUX1_ADDR 0x70   
#define MUX2_ADDR 0x71  

// Sensor adresses
#define BMP280_ADDR1 0x76   
#define BMP280_ADDR2 0x77   

byte Sensor_Address[] = {BMP280_ADDR1, BMP280_ADDR2};
byte Sensors_Per_Multiplexer[] = {NUMBER_OF_SENSORS_BMP280_MUX1, NUMBER_OF_SENSORS_BMP280_MUX2};
Adafruit_BMP280 bmp280[NUMBER_OF_SENSORS_BMP280_MUX1 + NUMBER_OF_SENSORS_BMP280_MUX2]; 

int counter = 0;

// Function to control the TCA9548A multiplexer 
void Select_Multiplexer(uint8_t muxAddress, uint8_t bus) {
  uint8_t busMask = 0;
  if (bus < 8) busMask = 1 << bus; // Bus must be between 0 and 7, otherwise all channels will be disabled
  Wire.beginTransmission(muxAddress); // TCA9548A address
  Wire.write(busMask); // Select the bus
  Wire.endTransmission();
}

void setup() {
  Serial.begin(115200);
  Wire.setClock(400000); // I2C clock speed
  Wire.begin();

  // Initialize the sensors 
  for (byte tca = 0; tca < NUMBER_OF_MULTIPLEXER; tca++){
    for (byte i = 0; i < Sensors_Per_Multiplexer[tca]; i++) {
     byte bmp = i % 2;
     byte x = (tca == 1) ? (i + Sensors_Per_Multiplexer[tca - 1]) : i;
     
     Select_Multiplexer(MUX1_ADDR + tca, i/2 ); // Select the bus (one bus for two sensors)
     // Initialize sensor 
     if (!bmp280[x].begin(Sensor_Address[bmp])) {
       Serial.print(F("Could not find BMP280 0x"));
       Serial.print((Sensor_Address[bmp]),HEX);
       Serial.print(F(" sensor on MUX"));
       Serial.print(tca+1);
       Serial.print(F(" port "));
       Serial.println(i/2);
     } else {
       Serial.print(F("BMP280 sensor 0x"));
       Serial.print((Sensor_Address[bmp]),HEX);
       Serial.print(F(" initialized on MUX"));
       Serial.print(tca+1);
       Serial.print(F(" port "));
       Serial.println(i/2);
     }
     delay(500);
     Select_Multiplexer(MUX1_ADDR + tca, 0xFF); // Disable the bus
   }
  }
}

void loop() {
  String output = ""; // Declare the output string

  // Read BMP280 sensors 
  for (byte tca = 0; tca < NUMBER_OF_MULTIPLEXER; tca++){
    for (byte i = 0; i < Sensors_Per_Multiplexer[tca]; i++ ) {
     Select_Multiplexer(MUX1_ADDR + tca, i / 2); // Select the bus
     byte bmp = i % 2; 
     byte x = (tca == 1) ? (i + Sensors_Per_Multiplexer[tca - 1]) : i;
     float pressure = bmp280[x].readPressure();

     if (bmp == 0){
      Serial.print(F("Mux"));
      Serial.print(tca + 1);
      Serial.print(F(" port "));
      Serial.print(i/2);
      Serial.print (F(" (0x"));
      Serial.print((Sensor_Address[bmp]),HEX);
      Serial.print(F("): "));
      Serial.print(pressure);
      Serial.print(F(" Pa "));
     }
     else{
      Serial.print(F(" | (0x"));
      Serial.print((Sensor_Address[bmp]),HEX);
      Serial.print(F("): "));
      Serial.print(pressure);
      Serial.println(F(" Pa"));
      Select_Multiplexer(MUX1_ADDR + tca, 0xFF);
      delay(500);
     }
    }
  }
   
  Serial.println(output);
  delay(100);
  if (counter > 10){
    exit(0);
  }
  counter++;
}

Great to hear. top. :+1:

1 Like