OK, now to code up the example with two TCA9548As and thee BME280s.
Here's the code:
// SPDX-FileCopyrightText: 2022 Carter Nelson for Adafruit Industries
//
// SPDX-License-Identifier: MIT
#include <Adafruit_BME280.h>
// for each TCA9548A, add an entry with its address
const uint8_t TCA_ADDRESSES[] = {
0x70,
0x71
};
const uint8_t TCA_COUNT = sizeof(TCA_ADDRESSES) / sizeof(TCA_ADDRESSES[0]);
Adafruit_BME280 bme1; // BME280 #1
Adafruit_BME280 bme2; // BME280 #2
Adafruit_BME280 bme3; // BME280 #3
void tcaselect(uint8_t tca, uint8_t channel) {
if (tca >= TCA_COUNT) return;
if (channel > 7) return;
// loop over all TCA's
for (uint8_t i=0; i<TCA_COUNT; i++) {
Wire.beginTransmission(TCA_ADDRESSES[i]);
if (i == tca) {
// set output channel for selected TCA
Wire.write(1 << channel);
} else {
// for others, turn off all channels
Wire.write(0);
}
Wire.endTransmission();
}
}
void setup() {
Serial.begin(9600);
while(!Serial);
Serial.println("Multiple BME280 / Multiple TCA9548A Example.");
Serial.print("Total number of TCA's = "); Serial.println(TCA_COUNT);
for (uint8_t i=0; i<TCA_COUNT; i++) {
Serial.print(i); Serial.print(" : 0x"); Serial.println(TCA_ADDRESSES[i], 16);
}
// NOTE!!! VERY IMPORTANT!!!
// Must call this once manually before first call to tcaselect()
Wire.begin();
// Before using any BME280, call tcaselect to select its output channel
tcaselect(0, 0); // TCA 0, channel 0 for bme1
bme1.begin(); // use the default address of 0x77
tcaselect(0, 1); // TCA 0, channel 1 for bme2
bme2.begin(); // use the default address of 0x77
tcaselect(1, 0); // TCA 1, channel 0 for bme3
bme3.begin(); // use the default address of 0x77
}
void loop() {
float pressure1, pressure2, pressure3;
tcaselect(0, 0);
pressure1 = bme1.readPressure();
tcaselect(0, 1);
pressure2 = bme2.readPressure();
tcaselect(1, 0);
pressure3 = bme3.readPressure();
Serial.println("------------------------------------");
Serial.print("BME280 #1 Pressure = "); Serial.println(pressure1);
Serial.print("BME280 #2 Pressure = "); Serial.println(pressure2);
Serial.print("BME280 #3 Pressure = "); Serial.println(pressure3);
delay(1000);
}
With that sketch running on the Arduino board, the output in the Serial Monitor will look like this:
The key enabler here is the new tcaselect() helper function. It now takes two parameters - the TCA to use and the channel on that TCA to activate. It's not very complex. It just adds an extra bit of logic to send 0 for the channel to all the other muxers in order to disable their outputs.
There's also a bit of global information setup with these lines:
// for each TCA9548A, add an entry with its address
const uint8_t TCA_ADDRESSES[] = {
0x70,
0x71
};
const uint8_t TCA_COUNT = sizeof(TCA_ADDRESSES) / sizeof(TCA_ADDRESSES[0]);
The last line that computes TCA_COUNT can be left alone.
To set things up for more TCA9548As, or for TCA9548As with different addresses, update the entries in the TCA_ADDRESS array. Use the index in this array as the first parameter when calling tcaselect(). For example, to select the channel 3 on the TCA9548A at address 0x71, use:
tcaselect(1, 3);
Since 1 is the index in the TCA_ADDRESS array for the 0x71 address entry. (remember Arduino uses 0 based indexing)
Note that the code is klunky as it was before. The tcaselect() function must be called each time a different BME280 needs to be accessed.
tcaselect(0, 0); // TCA 0, channel 0 for bme1 bme1.begin(); // use the default address of 0x77 tcaselect(0, 1); // TCA 0, channel 1 for bme2 bme2.begin(); // use the default address of 0x77 tcaselect(1, 0); // TCA 1, channel 0 for bme3 bme3.begin(); // use the default address of 0x77
Page last edited January 22, 2025
Text editor powered by tinymce.