Access multiple eeproms over TCA9548A

Hi guys,
I'm new to Arduino and for a simple challenge, I need your help. I had three eeprom (AT24C02) memories with 0x50 addresses over I2C. I want to read the stored data of all three eeproms simultaneously, but because of the same I2C address', I use a tca9548 module as an i2c multiplexer. I looked at some available examples of tca9548 which in most people use the same displays or same sensors. But for accessing eeprom stings, I cannot manage the code. here I put the of one eeproms, which works well, but to merge it into three eeprom with tca9548 I have some problems.

#include <Wire.h>
int P4;
const byte EEPROM_ID = 0x50;
int A50[128];
byte I2CEEPROM_Read (unsigned int address)
{
  byte data;
  Wire.beginTransmission(EEPROM_ID);
  Wire.write(address);
  Wire.endTransmission();
  Wire.requestFrom(EEPROM_ID,(byte)1);
  while(Wire.available() == 0);
  data = Wire.read();
    return data;
}

void setup() 
{ 
  Serial.begin(9600);
  Wire.begin();        
Serial.println("Serial begin...");
}
void loop() 
{ 
for (int i = 0; i <127; i++)
  {
    A50[i] = I2CEEPROM_Read(i);
   }
   

 P4 = ((int) A50[60]<<8) | ((int) A50[61]);


DynamicJsonDocument data(1024);
//JsonArray array = doc.to<JsonArray>();

 
  data["s"] = P4;// P4
  serializeJson(data, Serial);
  delay(1000);
 
}```

For that you would need 3 I2C buses to start with :wink:

Unless your devices are in the SOT-23 package, I would suggest that you use the address lines on the chip to give them different addresses.

Please show your code attempt at using the TCA9548. Also please provide a wiring diagram.

This is more than likely outside my league.

I don't see any mention of a TCA9548 in your code.

I've not used it but this library seems quite easy to use:

I would start with the example called tca9548_search_device.ino to see if your 3 EEPROMs are detected.

It appears that once you have called the mux begin function, a call to selectChannel is all that is needed to switch busses.

However, if your EEPROMs have address pins, then it's simpler to stick with 1 bus and change their addresses as already suggested.

Dear sterretje,

Thanks for your reply and sorry for the delay.
I should mention that I have no problem with an eeprom.
Sorry, I have no access to fritzing or others to draw the wiring diagram. Wiring is so simple;

  • On one eeprom config, the vcc and ground were connected to power pins on arduino mega and Sda/Scl were also connected to related pins(21/22) on arduino.
    ** On three config, eeproms all powered by arduino, and Sda/Scl of the first eeprom to the third one are wired to channel 0 to channel 2 of TCA9548A in order. Also, the multiplexer is powered by arduino.

You are right but, the above code is related to one eeprom, so I didn't put any TCA9548 header or library.
In most cases people usually use TCA9548.h, which is available on Arduino's online library.

My problem is how to merge 3 codes of the above one( with same i2c address; 0x50) , to use by TCA9548.

I (also) asked for the code for your attempt to use the TCA9548

A photo of a hand-drawn one is fine.

ok, well
I will send it.

Here I put a code of using 3 same sensors (BME280) work with arduino on the same i2c address (0x77), which taken from ;
https://learn.adafruit.com/working-with-multiple-i2c-devices?view=all

// SPDX-FileCopyrightText: 2022 Carter Nelson for Adafruit Industries
//
// SPDX-License-Identifier: MIT

#include <Adafruit_BME280.h>

#define TCAADDR 0x70

// For each device, create a separate instance.
Adafruit_BME280 bme1;  // BME280 #1
Adafruit_BME280 bme2;  // BME280 #2
Adafruit_BME280 bme3;  // BME280 #3

// Helper function for changing TCA output channel
void tcaselect(uint8_t channel) {
  if (channel > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << channel);
  Wire.endTransmission();  
}

void setup() {
  Serial.begin(9600);
  while(!Serial);
  Serial.println(F("Three BME280 Example"));

  // NOTE!!! VERY IMPORTANT!!!
  // Must call this once manually before first call to tcaselect()
  Wire.begin();
  
  // Before using any BME280, call tcaselect to set the channel.
  tcaselect(0);      // TCA channel for bme1
  bme1.begin();      // use the default address of 0x77

  tcaselect(1);      // TCA channel for bme2
  bme2.begin();      // use the default address of 0x77

  tcaselect(2);      // TCA channel for bme3
  bme3.begin();      // use the default address of 0x77
}


void loop() {
  float pressure1, pressure2, pressure3;

  // Read each device separately
  tcaselect(0);
  pressure1 = bme1.readPressure();
  tcaselect(1);
  pressure2 = bme2.readPressure();
  tcaselect(2);
  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);
}

but in my case, I have 2 functions, one for reading the string:

for (int i = 0; i <127; i++)
  {
    A50[i] = I2CEEPROM_Read(i);
   }
   

the second one is to do some calculations on the string:

P4 = ((int) A50[60]<<8) | ((int) A50[61]);

I have some challenges to merge these.

One thing more, I know AT24C02 has ability to have different i2c address by selecting different values on A0, A1 and A2 pins.
the challenge is to set all 3 eeproms on the same address.

Ok. How many pins does your EEPROM have? Is it an 8-pin DIL (aka PDIP) package or another type of surface mount package as @sterretje has already mentioned?

The Atmel datasheet for an AT24C02 shows the following available packages (datasheet from 2007 I think):
image
As you can see from the above, all package variants EXCEPT SOT23 have the A0, A1 and A2 address pins available. If your device is one of these, then you don't need the multiplexer. Simply connect up the A0, A1 and A2 pins to assign different addresses to each EEPROM.

Again, from the datasheet:

The A2, A1 and A0 pins are device address inputs that are hard wired for the AT24C01A and the AT24C02. As many as eight 1K/2K devices may be addressed on a single bus system (device addressing is discussed in detail under the Device Addressing section).

If you have the SOT23 devices, then you would need to determine if the EEPROM library you are using supports 3 instances of the EEPROM with the same address. As I suspect that having only one instance of the EEPROM but switching between 3 physical devices using the I2C mux might mess things up for you.

Why? Is this some sort of assignment you've been given? The EEPROMs have those address pins for a reason.

not an assignment, but it is a challenge.
Technically, do you think it is impossible?

Yes. No problem. If you want to keep each EEPROM at the same address, then you can use the I2C mux to switch between them.

Simply select the MUX channel for the EEPROM you want to address the read or write your data.

That's it. But check the EEPROM library you intend to use first in case it does some clever stuff such as caching the data as it will go wrong when you switch MUX channels and access a different EEPROM - the library won't know you've done this.

Exactly you got what I mean and what the challenge is.

You can always do away with the library and access the chip directly with the two wire library. Then you will know exactly what is going on.