Hi everyone,
I'm working on a project where I need to connect 20 BMP280 pressure sensors to 3 TCA9548A multiplexers to collect and analyze data. However, for now, I'm focusing on just 2 multiplexers. I'am using the redboard from Sparkfun.
The problem I'm encountering is that when I use the second multiplexer, the pressure readings from the sensors on both multiplexers are identical when using the same port.
#include <Wire.h>
#include <Adafruit_BMP280.h>
// Define the number of sensors per multiplexer
#define NUMBER_OF_SENSORS_BMP280_MUX1 1 // Number of BMP280 sensors
#define NUMBER_OF_SENSORS_BMP280_MUX2 1 // BMP280 sensors on the 2nd multiplexer
#define MUX1_ADDR 0x70 // Address of first multiplexer
#define MUX2_ADDR 0x71 // Address of second multiplexer
int counter = 0;
Adafruit_BMP280 bmp280[NUMBER_OF_SENSORS_BMP280_MUX1]; // BMP280 sensors
Adafruit_BMP280 bmp281[NUMBER_OF_SENSORS_BMP280_MUX2];
// Function to control the TCA9548A multiplexer (with address)
void selectMultiplexer(uint8_t muxAddress, uint8_t bus) {
if (bus > 7) return; // Bus must be between 0 and 7
Wire.beginTransmission(muxAddress); // TCA9548A address
Wire.write(1 << bus); // Select the bus
Wire.endTransmission();
}
void setup() {
Serial.begin(115200);
Wire.setClock(400000); // I2C clock speed
Wire.begin();
// 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 port ");
Serial.println(i);
} else {
Serial.print("BMP280 sensor initialized on port ");
Serial.println(i);
}
//selectMultiplexer(MUX1_ADDR, 0xFF); // Disable the bus
}
// Initialize the sensors on the 2nd multiplexer (address 0x71)
for (byte x = 0; x < NUMBER_OF_SENSORS_BMP280_MUX2; x++) {
selectMultiplexer(MUX2_ADDR, x); // Select the bus on the 2nd multiplexer
if (!bmp281[x].begin(0x76)) { // Initialize the BMP280 sensor
Serial.print("Could not find BMP280 sensor on the 2nd mux, port ");
Serial.println(x);
} else {
Serial.print("BMP280 sensor initialized on the 2nd mux, port ");
Serial.println(x);
}
//selectMultiplexer(MUX2_ADDR, 0xFF); // Disable the bus
}
}
void loop() {
String output = ""; // Declare the output string
// 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
Serial.print("Mux1 port");
Serial.print (i);
Serial.print(" ");
Serial.print(pressure);
Serial.print(" ");
//selectMultiplexer(MUX1_ADDR, 0xFF); // Disable the bus
}
// Read BMP280 sensors on the 2nd multiplexer
for (byte x = 0; x < NUMBER_OF_SENSORS_BMP280_MUX2; x++) {
selectMultiplexer(MUX2_ADDR, x); // Select the bus on the 2nd multiplexer
float pressure = bmp281[x].readPressure(); // Read data from BMP280 sensor
Serial.print("Mux2 port ");
Serial.print (x);
Serial.print(" ");
Serial.print(pressure);
//selectMultiplexer(MUX2_ADDR, 0xFF); // Disable the bus
}
Serial.println(output); // Print the results
delay(100);
counter++; // Increment the counter
if (counter >= 10) {
while (1); // Infinite loop after 30 readings
}
}
You got the right idea here. Unless you turn off MUX1 before you select a channel of MUX2, you will have 2 sensors on the bus with the same address, which either not work at all, or will give the reading from one of the 2 sensors at random.
Unfortunately, you cannot simply un-comment those lines. The selectMultiplexer() function will do nothing if the parameter is > 7. You need to amend selectMultiplexer() function also so that when it receives 0xFF it sends zero to the multiplexer which will disable all channels.
Maybe like this
// 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();
}
Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.
Here is my circuit since a lot of you asked it. I'am using a Redborad instead of arduino UNO because I could not find it on fritzing. This is an axample with only 2 sensors an 2 MUX.
Here is the updated code and you can find the schematic above.
#include <Wire.h>
#include <Adafruit_BMP280.h>
// Define the number of sensors per multiplexer
#define NUMBER_OF_SENSORS_BMP280_MUX1 1 // Number of BMP280 sensors
#define NUMBER_OF_SENSORS_BMP280_MUX2 1 // BMP280 sensors on the 2nd multiplexer
#define MUX1_ADDR 0x70 // Address of first multiplexer
#define MUX2_ADDR 0x71 // Address of second multiplexer
int counter = 0;
Adafruit_BMP280 bmp280[NUMBER_OF_SENSORS_BMP280_MUX1]; // BMP280 sensors
Adafruit_BMP280 bmp281[NUMBER_OF_SENSORS_BMP280_MUX2];
// 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.setClock(400000); // I2C clock speed
Wire.begin();
// 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 port ");
Serial.println(i);
} else {
Serial.print("BMP280 sensor initialized on port ");
Serial.println(i);
}
selectMultiplexer(MUX1_ADDR, 0xFF); // Disable the bus
}
// Initialize the sensors on the 2nd multiplexer (address 0x71)
for (byte x = 0; x < NUMBER_OF_SENSORS_BMP280_MUX2; x++) {
selectMultiplexer(MUX2_ADDR, x); // Select the bus on the 2nd multiplexer
if (!bmp281[x].begin(0x76)) { // Initialize the BMP280 sensor
Serial.print("Could not find BMP280 sensor on the 2nd mux, port ");
Serial.println(x);
} else {
Serial.print("BMP280 sensor initialized on the 2nd mux, port ");
Serial.println(x);
}
selectMultiplexer(MUX2_ADDR, 0xFF); // Disable the bus
}
}
void loop() {
String output = ""; // Declare the output string
// 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
Serial.print("Mux1 port");
Serial.print (i);
Serial.print(" ");
Serial.print(pressure);
Serial.print(" ");
selectMultiplexer(MUX1_ADDR, 0xFF); // Disable the bus
}
// Read BMP280 sensors on the 2nd multiplexer
for (byte x = 0; x < NUMBER_OF_SENSORS_BMP280_MUX2; x++) {
selectMultiplexer(MUX2_ADDR, x); // Select the bus on the 2nd multiplexer
float pressure = bmp281[x].readPressure(); // Read data from BMP280 sensor
Serial.print("Mux2 port ");
Serial.print (x);
Serial.print(" ");
Serial.print(pressure);
selectMultiplexer(MUX2_ADDR, 0xFF); // Disable the bus
}
Serial.println(output); // Print the results
delay(100);
counter++; // Increment the counter
if (counter >= 10) {
while (1); // Infinite loop after 30 readings
}
}
The pull-ups on the left side here connect to the Vcc (=Vin) pin. But your Vin pins are not connected to anything.
The sensor boards have built-in 3.3V regulator and 5V-3.3V level shifters, so it's safe to power all components with 5V from the Uno instead of 3.3V. Use the Vin pins, not the 3V3 pins when powering the sensors.
Thanks for helping me ! Both sensors on each MUX are working. I did the wiring again and it works now. Now I will add the third MUX and all the sensors and see if it works.