Hello guys,
I’m currently working on a project, and I need help connecting multiple (more than 8) TCA9548 devices together. Additionally, I need to be able to dynamically change the order of the connected TCA9548 modules.
I have:
- Arduino UNO Wifi REV 2
- TCA9548 1xI2C master - 8xI2C slave expander
- EEPROM modul, AT24C256, I2C
I need to all TCA9548 devices to operate on a single address (default 0x70), and I am looking for a way to switch between them. Each TCA9548 has an EEPROM connected to it, containing a unique ID.
The connections are set up as follows:
- The SDA and SCL lines from the Arduino are connected to the input pins (SDA and SCL) of TCA9548 #1.
- The SD0 and SC0 (CH0) lines of TCA9548 #1 are connected to an EEPROM.
- The SD1 and SC1 (CH1) lines of TCA9548 #1 are connected to the SDA and SCL inputs of TCA9548 #2.
- On TCA9548 #2, the SD0 and SC0 (CH0) lines are again connected to another EEPROM.
In the following code, I attempted to first read the value from the EEPROM connected to TCA9548 #1 on SD0 and SC0 (CH0). Then, I switched to CH1 (SD1 and SC1) to read the value from the EEPROM connected to TCA9548 #2 on SD0 and SC0 (CH0). However, the value read from the EEPROM on TCA9548 #1 is the same as that from TCA9548 #2. I suspect that there might be some kind of looping occurring, or that the switch to TCA9548 #2 is not happening correctly, causing the value to always come from TCA9548 #1.
I am stuck and unsure how to resolve this. Have you encountered anyone dealing with a similar issue? Or do you know of any guides, articles, or videos that could help? Any advice would be greatly appreciated.
#include <Wire.h>
#define MUX_ADDRESS 0x70 // TCA9548 (both MUX #1 and MUX #2)
#define EEPROM_ADDRESS 0x50
// -------------------------------------------------------------------------
// Helper function to check if a device responds (ACK) at MUX_ADDRESS.
bool isMuxPresent() {
Wire.beginTransmission(MUX_ADDRESS);
return (Wire.endTransmission() == 0);
}
// -------------------------------------------------------------------------
// Selects (opens) a specific channel 'channel' (0–7) on TCA9548.
// Returns true if endTransmission() returns 0 (success).
bool selectMuxChannel(uint8_t channel) {
if (channel > 7) return false;
Wire.beginTransmission(MUX_ADDRESS);
Wire.write(1 << channel);
return (Wire.endTransmission() == 0);
}
// -------------------------------------------------------------------------
// Closes all channels on TCA9548 (i.e., sends 0x00).
bool disableAllMuxChannels() {
Wire.beginTransmission(MUX_ADDRESS);
Wire.write((uint8_t)0x00);
return (Wire.endTransmission() == 0);
}
// -------------------------------------------------------------------------
// Reads 3 bytes from EEPROM (0x50) starting from internal address 0x0000
// and stores them in `outBuf[0..2]`, appending '\0'.
// Returns true if 3 bytes were successfully read, otherwise false.
bool readEeprom3Bytes(char* outBuf) {
// Move the EEPROM internal address pointer to 0x0000
Wire.beginTransmission(EEPROM_ADDRESS);
Wire.write((uint8_t)0x00);
Wire.write((uint8_t)0x00);
if (Wire.endTransmission() != 0) {
return false;
}
// Request 3 bytes
uint8_t numBytes = 3;
Wire.requestFrom((int)EEPROM_ADDRESS, (int)numBytes);
if (Wire.available() < numBytes) {
return false;
}
for (uint8_t i = 0; i < numBytes; i++) {
outBuf[i] = Wire.read();
}
outBuf[numBytes] = '\0';
return true;
}
// -------------------------------------------------------------------------
void setup() {
Serial.begin(115200);
Wire.begin();
delay(1000);
// Check if MUX #1 exists at address 0x70
if (!isMuxPresent()) {
Serial.println("MUX #1 (0x70) on the main bus is not responding. Exiting.");
while (1) {} // End
}
Serial.println("Found MUX #1 (0x70).");
// (A) OPEN CH0 on MUX #1 and read EEPROM
if (!selectMuxChannel(0)) {
Serial.println("Failed to open CH0 on MUX #1.");
while (1) {}
}
delay(5);
// Read 3 bytes from EEPROM #1
char buffer1[4];
if (readEeprom3Bytes(buffer1)) {
Serial.print("Value from EEPROM on MUX #1 CH0: '");
Serial.print(buffer1);
Serial.println("'");
} else {
Serial.println("Error reading EEPROM on MUX #1 CH0.");
}
// (B) CLOSE ALL CHANNELS, WAIT 10s
if (!disableAllMuxChannels()) {
Serial.println("Failed to close all channels on MUX #1.");
}
Serial.println("All channels on MUX #1 are closed.");
delay(2000);
// (C) OPEN CH1 on MUX #1 (where MUX #2 is located)
if (!selectMuxChannel(1)) {
Serial.println("Failed to open CH1 on MUX #1.");
while (1) {}
}
delay(5);
// Check if MUX #2 responds with ACK at 0x70
if (!isMuxPresent()) {
Serial.println("MUX #2 (0x70) behind CH1 is not detected.");
while (1) {}
}
Serial.println("Found MUX #2 (0x70) on CH1 of MUX #1.");
// (D) Within MUX #2, select CH0 where EEPROM #2 is located
if (!selectMuxChannel(0)) {
Serial.println("Failed to open CH0 on MUX #2.");
while (1) {}
}
delay(5);
// Read 3 bytes from EEPROM #2
char buffer2[4];
if (readEeprom3Bytes(buffer2)) {
Serial.print("Value from EEPROM on MUX #2 CH0: '");
Serial.print(buffer2);
Serial.println("'");
} else {
Serial.println("Error reading EEPROM on MUX #2 CH0.");
}
}
void loop() {
}
Thanks. :))
