# Working with Multiple Same Address I2C Devices

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/111/318/medium800/sensors_banner_with_addr.png?1651678259)

[A previous guide](https://learn.adafruit.com/working-with-i2c-devices)&nbsp;discussed working with I2C devices in a general way, covering various topics. If you're new to I2C and need a broader overview, be sure to read that guide first, here's the link:

[Working with I2C Devices](https://learn.adafruit.com/working-with-i2c-devices)
This guide goes more in depth on working with _ **multiple** _ copies of the same I2C device, which most likely have the **same I2C address**. Getting this general configuration working seems to be a common source of confusion.

As mentioned in the guide linked above, every I2C device on the I2C bus needs to have a unique [address](https://learn.adafruit.com/working-with-i2c-devices/terminology). If you've only used a single I2C device, you may not even have realized this. Most drivers are written such that they use, without any further input from the user, a predefined default address. This may also have even been the case for using multiple, but different, I2C devices. In that case, each device's default address was different, so there was nothing else to do in terms of coding. Everything was just plug-and-play simple.

![](https://cdn-learn.adafruit.com/assets/assets/000/111/313/medium800/sensors_image.png?1651675796)

However, things get more interesting when [address conflicts](https://learn.adafruit.com/working-with-i2c-devices/address-conflicts) start happening. This is essentially unavoidable when attempting to use **multiple copies of the same I2C device**. As mentioned in the other guide, there are three main ways of dealing with this:

- Use an alternate address (if device allows)
- Use an I2C channel multiplexer if alternate address(es) not possible (recommended)
- Use alternate I2C ports (if desperate)

With any of these approaches, there is more work to be done. What is the alternate address? How do you actually "set" it? How do you change code to accommodate the alternate address? How do you incorporate using an I2C channel multiplexer? etc.

This guide aims to help answer those questions.

## Hardware

This guide uses the [Adafruit BME280 breakout](https://www.adafruit.com/product/2652) in the examples as a representative I2C device. However, there is nothing special about this particular sensor. So it's not really "required hardware". The information here should generally apply to **any** I2C breakout.

When it comes to an I2C multiplexer, the TCA9548A is currently the best option. It's available in a couple of different breakouts:

### TCA9548A I2C Multiplexer

[TCA9548A I2C Multiplexer](https://www.adafruit.com/product/2717)
You just found the perfect I2C sensor, and you want to wire up two or three or more of them to your Arduino when you realize "Uh oh, this chip has a fixed I2C address, and from what I know about I2C, you cannot have two devices with the same address on the same SDA/SCL pins!" Are you...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2717)
[Related Guides to the Product](https://learn.adafruit.com/products/2717/guides)
![Angled Shot of the TCA9548A I2C Multiplexer.](https://cdn-shop.adafruit.com/640x480/2717-05.jpg)

The [Adafruit TCA9548A breakout](https://www.adafruit.com/product/2717)is used in this guide. However, the SparkFun breakout has the benefit of not needing any soldering. Everything can be connected using STEMMA QT cables.

Also, an [ItsyBitsy M4](https://www.adafruit.com/product/3800) is shown in the wiring diagrams. However, the information in this guide should apply to **any** Arduino or CircuitPython board with an I2C port. Which is pretty much most of them.

# Working with Multiple Same Address I2C Devices

## Single Device using Default Settings

This is the trivial case. It should be possible to wire the breakout per its guide and run a simple example without any modifications. It should "just work". The I2C address itself never needs to be directly dealt with.

This configuration is covered here to simply provide a basic starting point. Here's the wiring:

Info: 

![](https://cdn-learn.adafruit.com/assets/assets/000/111/207/medium800/sensors_one_device.png?1651181075)

### STEMMA QT / Qwiic JST SH 4-pin to Premium Male Headers Cable

[STEMMA QT / Qwiic JST SH 4-pin to Premium Male Headers Cable](https://www.adafruit.com/product/4209)
This 4-wire cable is a little over 150mm / 6" long and fitted with JST-SH female 4-pin connectors on one end and premium Dupont male headers on the other. Compared with the chunkier JST-PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert...

In Stock
[Buy Now](https://www.adafruit.com/product/4209)
[Related Guides to the Product](https://learn.adafruit.com/products/4209/guides)
![Angled Shot of the STEMMA QT / Qwiic JST SH 4-pin to Premium Male Headers Cable.](https://cdn-shop.adafruit.com/640x480/4209-05.jpg)

### Half Sized Premium Breadboard - 400 Tie Points

[Half Sized Premium Breadboard - 400 Tie Points](https://www.adafruit.com/product/64)
This is a cute, half-size breadboard with&nbsp;400 tie points, good for small projects. It's 3.25" x 2.2" / 8.3cm&nbsp;x 5.5cm&nbsp;with a standard double-strip in the middle and two power rails on both sides.&nbsp;You can pull the power rails off easily to make the breadboard as...

In Stock
[Buy Now](https://www.adafruit.com/product/64)
[Related Guides to the Product](https://learn.adafruit.com/products/64/guides)
![Angled shot of half-size solderless breadboard with red and black power lines.](https://cdn-shop.adafruit.com/640x480/64-06.jpg)

# Working with Multiple Same Address I2C Devices

## Arduino

There's really not much to do other than run the basic example from the library, as is. No code changes should be needed. This is no different than what the BME280 primary guide has you do here:

[BME280 Arduino Test](https://learn.adafruit.com/adafruit-bme280-humidity-barometric-pressure-temperature-sensor-breakout/arduino-test)
Once the Adafruit BME280 library is installed, open the example in the Arduino IDE:

**File-\>Examples-\>Adafruit\_BME280-\>bme280test**

and upload the sketch to the board. The output in the Serial Monitor should look like this:

![](https://cdn-learn.adafruit.com/assets/assets/000/111/211/medium800/sensors_Screenshot_from_2022-04-28_14-47-18.png?1651182839)

# Working with Multiple Same Address I2C Devices

## CircuitPython

Again, the basic example from the library should work as is without any code changes. This is no different than what the BME280 primary guide has you do here:

[BME280 CircuitPython Test](https://learn.adafruit.com/adafruit-bme280-humidity-barometric-pressure-temperature-sensor-breakout/python-circuitpython-test)
With the [bme280\_simpletest.py](https://github.com/adafruit/Adafruit_CircuitPython_BME280/blob/main/examples/bme280_simpletest.py) example running, the output should look like this:

```terminal
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:

Temperature: 19.3 C
Humidity: 46.9 %
Pressure: 1014.0 hPa
Altitude = -6.30 meters

Temperature: 19.3 C
Humidity: 46.8 %
Pressure: 1014.0 hPa
Altitude = -6.17 meters
```

# Working with Multiple Same Address I2C Devices

## Two Devices using Alternate Address

OK, now let's try using two BME280s. Now there's some work to do. Both the hardware and the code will need to be changed.

Both BME280s can't use the default address of 0x77. Not all devices have this capability, but the BME280 allows setting a second I2C address of 0x76. That allows for the following setup:

![](https://cdn-learn.adafruit.com/assets/assets/000/111/208/medium800/sensors_two_devices.png?1651181356)

But how did we know the alternate address was 0x76? And how was the breakout altered to set the address to 0x76?

## Finding and Setting Alternate Addresses

How do you know if any given device has the ability to set an alternate I2C address? Ideally, it will be mentioned in the product guide or some other documentation. Sometimes this may require digging into the device's datasheet. Also, since the most common method of setting the alternate address is by using additional pins, there are some physical features to look for on any given breakout. For example, the BME280 has a solder pad for setting the alternate address on the backside of the board:

![](https://cdn-learn.adafruit.com/assets/assets/000/111/282/medium800/sensors_addr_jumper.png?1651523422)

If nothing is done, the BME280 has the indicated default address of 0x77. By adding a blob of solder to electrically connect to the two copper pads, the alternate address of 0x76 is set. Here is what a blob of solder on the address jumper pad looks like:

![](https://cdn-learn.adafruit.com/assets/assets/000/111/288/medium800/sensors_bme280_addr_solder.png?1651528673)

Another place to look would be the row of header pins. For example, the ADS1105 and ADS1115 ADC breakouts have a dedicated pin for setting the alternate address.

![](https://cdn-learn.adafruit.com/assets/assets/000/111/283/medium800/sensors_ads1115_addr_pin.png?1651523866)

This is done since setting alternate addresses for the ADS1015/1115 is not as simple as making/breaking a **single** connection - which is what solder pad jumpers are used for. A total of four different addresses can be set depending on what the ADDR pin is connected to.

![](https://cdn-learn.adafruit.com/assets/assets/000/111/284/medium800/sensors_ads1115_addresses.png?1651523943)

Trying to do that with solder jumpers would be a bit of a mess.

## Coding for Alternate Address Usage

Once the hardware has been modified to set an alternate I2C address, what are the required code changes? To use an alternate, non-default address, it must be explicitly called out in user code. But exactly where and how is that done? It's different for Arduino and CircuitPython.

### Arduino

For Adafruit Arduino libraries, the alternate address is passed in when calling `begin()` on the sensor object. This code is typically placed in an Arduino sketch's `setup()` function. For example, to specify the alternate address of 0x76 for the BME280:

```cpp
bme.begin(0x76);  // specify the alternate address of 0x76
```

Info: 

 **NOTE** : There can be some library-to-library variability in the specific format for calling `begin()`. So be sure to look at the associated library documents.

### CircuitPython

For Adafruit CircuitPython libraries, the alternate address is passed in when creating the instance for the sensor. For example, to specify the alternate address of 0x76 for the BME280:

```python
bme = adafruit_bme280.Adafruit_BME280_I2C(i2c, 0x76)
```

Info: 

 **NOTE** : Sometimes a parameter name, like `addr` or `address` is used.

## Consult The List

The following guide attempts provide a list of I2C addresses for popular I2C devices:

[I2C Addresses - The List](https://learn.adafruit.com/i2c-addresses/the-list)
There are a lot. One could text search on that page and see if a given device is there. For example, search for "BME280" to find the entry:

![](https://cdn-learn.adafruit.com/assets/assets/000/111/285/medium800/sensors_i2c_the_list.png?1651524303)

And now it's known that the BME280 can have an I2C address of either 0x76 or 0x77.

However, this list requires manually updating. So the page may or may not have the sensor you're looking for.

## When In Doubt, Scan

Running an [I2C scan](https://learn.adafruit.com/scanning-i2c-addresses/overview) is a good way to sanity check the setup. Not only will it report the I2C addresses for all discovered devices, it's also a good way to verify the I2C connections themselves are OK. There's a dedicated guide on I2C scanning here:

[How to Scan and Detect I2C Addresses](https://learn.adafruit.com/scanning-i2c-addresses/overview)
There are examples for scanning with Arduino, CircuitPython, and on Raspberry Pi. Here is what typical Arduino scan output looks like:

![](https://cdn-learn.adafruit.com/assets/assets/000/111/212/medium800/sensors_Screenshot_from_2022-04-28_14-58-00.png?1651183215)

There's something at 0x76 and 0x77! That's the two BME280 breakouts as shown in the wiring diagram above. One is unaltered and has an I2C address of 0x77. One has the solder jumper closed and has an I2C address of 0x76.

# Working with Multiple Same Address I2C Devices

## Arduino

OK, to actually code up a simple example using two BME280's, one without any changes having the default address of 0x77 and one with the solder pad connected to set the alternate address of 0x76.

Here's the sketch code:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/I2C_Multiple_Same_Address/arduino/multi_bme280_2x/multi_bme280_2x.ino

With that sketch running on the Arduino board, the output in the Serial Monitor will look like this:

![](https://cdn-learn.adafruit.com/assets/assets/000/111/292/medium800/sensors_Screenshot_from_2022-05-02_16-28-59.png?1651534149)

Note how for each device, there is a separate instance created:

```cpp
Adafruit_BME280 bme1;  // BME280 #1 @ 0x77
Adafruit_BME280 bme2;  // BME280 #2 @ 0x76
```

And then for each, the `begin()` function is called and the address is specified:

```cpp
bme1.begin(0x77);  // address = 0x77 (default)
bme2.begin(0x76);  // address = 0x76
```

Here we intentionally specify the default 0x77 address just to be explicit.

Once that is taken care of, the two instances can be used to directly read the sensor values:

```cpp
pressure1 = bme1.readPressure();
pressure2 = bme2.readPressure();
```

# Working with Multiple Same Address I2C Devices

## CircuitPython

Let's do the same thing in CircuitPython.

Here's the code:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/I2C_Multiple_Same_Address/circuitpython/multi_bme280_2x/code.py

With that code running on the CircuitPython board, the output will look like this:

```terminal
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Two BME280 Example
--------------------
BME280 #1 Pressure = 1013.98
BME280 #2 Pressure = 1013.16
--------------------
BME280 #1 Pressure = 1013.98
BME280 #2 Pressure = 1013.13
--------------------
BME280 #1 Pressure = 1014.0
BME280 #2 Pressure = 1013.16
--------------------
BME280 #1 Pressure = 1014.01
BME280 #2 Pressure = 1013.2
```

These are the two important lines:

```python
bme1 = adafruit_bme280.Adafruit_BME280_I2C(i2c, 0x77)  # address = 0x77
bme2 = adafruit_bme280.Adafruit_BME280_I2C(i2c, 0x76)  # address = 0x76
```

They create a separate sensor instance for each BME280 and specify the I2C address for each. We intentionally specify the default 0x77 address just to be explicit.

After that, each can be used to read the sensor values:

```cpp
pressure1 = bme1.pressure
pressure2 = bme2.pressure
```

So things are pretty easy if alternate addresses can be used.

# Working with Multiple Same Address I2C Devices

## Three Devices using Multiplexer

Now let's look at using **three** BME280s. There are no easy options, since the BME280 only has two available I2C addresses. So now the [TCA9548A I2C multiplexer](https://www.adafruit.com/product/2717) is used. Also, to help illustrate the use of the TCA9548A, we will ignore the BME280's alternate address. Therefore, this example is exactly like what one would deal with when trying to use three copies of any I2C device with a **single fixed address**.

Here is the wiring diagram for the setup. Note that the TCA9548A itself has an I2C address of 0x70. Each BME280 has the same address of 0x77.

![](https://cdn-learn.adafruit.com/assets/assets/000/111/209/medium800/sensors_three_devices.png?1651181577)

## The TCA9548A Multiplexer

This is a simple device. It has only one trick up its sleeve. It has one input and eight outputs. The only I2C "command" it accepts is one to set what outputs are active. That's it. That's all it does.

It is an I2C device though, so does have an I2C address. The address can be changed, but in this guide we'll only use its default 0x70 address. **No other device can have the same address as the TCA9548A.** So the basic rule about unique addresses still applies.

### Changing Output Channels

While the TCA9548A can have more than one output channel active at a time, here we only show using a single channel at a time. The one "command" that the TCA9548A accepts is a single byte value, where each bit represents an output channel:

![](https://cdn-learn.adafruit.com/assets/assets/000/111/289/medium800/sensors_tca_register.jpg?1651529766)

If the bit is 1, the channel is active. If the bit is 0, the channel is not active. Super simple.

The easiest way to generate the proper byte to activate a **single** channel is to [left shift](https://en.wikipedia.org/wiki/Logical_shift) 1 by the channel number. An example Arduino code snippet to do this would look like:

```cpp
Wire.beginTransmission(TCA_ADDRESS);
Wire.write(1 &lt;&lt; CHANNEL_NUMBER);
Wire.endTransmission();
```

Where `TCA_ADDRESS` would be the 0x70 (or other) address of the TCA9548A and `CHANNEL_NUMBER` would be an integer value 0 to 7 for the desired output channel. The `<<` is the left shift operator.

This is the exact same code as shown in the [TCA9548A guide](https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout/wiring-and-test) and will also be used here in the Arduino examples. **There is no dedicated Arduino library for the TCA9548A.** Channel switching must be done **manually** in Arduino sketch code.

When using CircuitPython, things are a little fancier. There is a [CircuitPython library for the TCA9548A](https://github.com/adafruit/Adafruit_CircuitPython_TCA9548A). Under the hood, it's no different than the Arduino example above. [The left shifting can be seen here](https://github.com/adafruit/Adafruit_CircuitPython_TCA9548A/blob/a91df151f930464196346f9f5c43c107ac94c765/adafruit_tca9548a.py#L47). The neat thing about the CircuitPython library is that it can take care of sending the channel switch byte to the TCA9548A **automatically**.

# Working with Multiple Same Address I2C Devices

## Arduino

OK, now to code up the example with a TCA9548A multiplexer and three BME280s, all with I2C addresses of 0x77.

Here's the code:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/I2C_Multiple_Same_Address/arduino/multi_bme280_3x/multi_bme280_3x.ino

With that sketch running on the Arduino board, the output in the Serial Monitor will look like this:

![](https://cdn-learn.adafruit.com/assets/assets/000/111/290/medium800/sensors_Screenshot_from_2022-05-02_16-08-31.png?1651533155)

Similar to the two BME280s example, a separate instance is created for each sensor:

```cpp
Adafruit_BME280 bme1;  // BME280 #1
Adafruit_BME280 bme2;  // BME280 #2
Adafruit_BME280 bme3;  // BME280 #3
```

A helper function is used to make switching TCA9548A channels easy. Note that the code is no different than what was discussed above about setting TCA9548A output channels:

```cpp
void tcaselect(uint8_t channel) {
  if (channel &gt; 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 &lt;&lt; channel);
  Wire.endTransmission();  
}
```

While simple, this function is using the Wire bus directly. Therefore, it is **very important** to remember to call `Wire.begin();` before the first call to `tcaselect()`. It only needs to be called once.

```cpp
// NOTE!!! VERY IMPORTANT!!!
// Must call this once manually before first call to tcaselect()
Wire.begin();
```

Also important is noting that `tcaselect()` must be called each time to set the output channel to the specific BME280. This is done in `setup()` before calling `begin()` on each sensor:

```cpp
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
```

And also in the `loop()` before reading each sensor:

```cpp
tcaselect(0);
pressure1 = bme1.readPressure();
tcaselect(1);
pressure2 = bme2.readPressure();
tcaselect(2);
pressure3 = bme3.readPressure();
```

Yes, that is a bit klunky. Code lines to deal with the TCA9548A must be interleaved in with the sensor reading code. Think in terms of "I want to use the sensor on TCA9548A channel X, so first must switch the TCA9548A to channel X." The `tcaselect()` function is what does that switching.

# Working with Multiple Same Address I2C Devices

## CircuitPython

Here is the CircuitPython code for a TCA9548A and three BME280s:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/I2C_Multiple_Same_Address/circuitpython/multi_bme280_3x/code.py

With that code running on the CircuitPython board, the output will look like this:

```terminal
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Three BME280 Example
--------------------
BME280 #1 Pressure = 1013.96
BME280 #2 Pressure = 1013.72
BME280 #3 Pressure = 1013.76
--------------------
BME280 #1 Pressure = 1013.97
BME280 #2 Pressure = 1013.73
BME280 #3 Pressure = 1013.77
--------------------
BME280 #1 Pressure = 1013.98
BME280 #2 Pressure = 1013.73
BME280 #3 Pressure = 1013.73
```

The TCA9548A itself is setup like any other I2C device:

```python
tca = adafruit_tca9548a.TCA9548A(i2c)
```

The board's I2C bus (`i2c`) is passed in. The I2C address for the TCA9548A would also be specified here. But in this case we leave it out to show how to use with the default 0x70 address. Remember - that's the address of the TCA9548A.

 **The important difference to note** is what is being passed in when creating each instance of the BME280 device:

```cpp
bme1 = adafruit_bme280.Adafruit_BME280_I2C(tca[0])   # TCA Channel 0
bme2 = adafruit_bme280.Adafruit_BME280_I2C(tca[1])   # TCA Channel 1
bme3 = adafruit_bme280.Adafruit_BME280_I2C(tca[2])   # TCA Channel 2
```

Instead of passing in the I2C bus (`i2c`), the `[]` operator is used on the `tca` instance to access and specify that output channel. So `tca[0]` is channel 0 of the TCA9548A, etc.

**This is the fancy thing that the Adafruit CircuitPython TCA9548A library does.** Because of this feature, once the initial setup is done, the instances can be used in a normal way:

```python
pressure1 = bme1.pressure
pressure2 = bme2.pressure
pressure3 = bme3.pressure
```

There's no need to worry about dealing with the TCA9548A directly, changing its output channel, etc.

Exactly how the library does this is beyond the scope of this guide. But it relies on some Python specific tricks, which is why a similar capability is lacking in Arduino land.

# Working with Multiple Same Address I2C Devices

## Four Devices using Multiplexer

This is really no different than the example with three devices. There's just one more BME280 device added. But hopefully this example helps reinforce the idea that adding yet-another-same-address-device is a simple matter of connecting it to an available channel on the TCA9548A and adding a few more lines of code. So by looking at the three BME280 example and then the four BME280 example, one can expand this to five, six, etc. BME280s.

Here's the setup:

![](https://cdn-learn.adafruit.com/assets/assets/000/111/210/medium800/sensors_four_devices.png?1651181817)

Why stop at 4 BME280s? Or even 8? A single TCA9548A can support up to 8 total same address devices. By using multiple TCA9548As, each with its own I2C address, more than 8 same address devices can be used. There are 8 total settable addresses for the TCA9548A, with values 0x70 to 0x77. So the grand total of same address devices that could be used is 8 TCA9548As x 8 output channels each = 64.

# Working with Multiple Same Address I2C Devices

## Arduino

OK, now to code up the example with a TCA9548A multiplexer and four BME280s, all with I2C addresses of 0x77.

Here's the code:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/I2C_Multiple_Same_Address/arduino/multi_bme280_4x/multi_bme280_4x.ino

With that sketch running on the Arduino board, the output in the Serial Monitor will look like this:

![](https://cdn-learn.adafruit.com/assets/assets/000/111/291/medium800/sensors_Screenshot_from_2022-05-02_16-07-28.png?1651533167)

Hopefully by comparing the 4xBME280 code to the previous 3xBME280 code example, the basic code pattern can be seen. It's essentially just a copy-paste of the same code to add one more instance:

```cpp
Adafruit_BME280 bme4;  // BME280 #4
```

And then call `tcaselect()` same as done for the other BME280s:

```cpp
tcaselect(3);      // TCA channel for bme4
bme4.begin();      // use the default address of 0x77
```

Danger: 

Danger: 

# Working with Multiple Same Address I2C Devices

## CircuitPython

Here's the same thing for CircuitPython:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/I2C_Multiple_Same_Address/circuitpython/multi_bme280_4x/code.py

With that code running on the CircuitPython board, the output will look like this:

```terminal
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Four BME280 Example
--------------------
BME280 #1 Pressure = 1014.0
BME280 #2 Pressure = 1013.72
BME280 #3 Pressure = 1013.73
BME280 #4 Pressure = 1013.75
--------------------
BME280 #1 Pressure = 1013.99
BME280 #2 Pressure = 1013.72
BME280 #3 Pressure = 1013.76
BME280 #4 Pressure = 1013.73
--------------------
BME280 #1 Pressure = 1013.98
BME280 #2 Pressure = 1013.71
BME280 #3 Pressure = 1013.74
BME280 #4 Pressure = 1013.75
```

Again, there is little more done compared to the 3xBME280s example other than adding a new instance for the 4th sensor, specifying the TCA9548A channel:

```python
bme4 = adafruit_bme280.Adafruit_BME280_I2C(tca[3])   # TCA Channel 3
```

And then using it like the others:

```python
pressure4 = bme4.pressure
```

# Working with Multiple Same Address I2C Devices

## Multiple Muxers

But wait! There's more!

A single TCA9548A muxer allows for up to 8 same address I2C devices. But what if you want more than 8? As mentioned previously, the I2C address of the TCA9548A itself can be changed. This allows using more than one muxer - up to 8 TCA9548As. So with 8 muxers having 8 channels each, that allows for **up to 64 total same address devices**.

This requires a little more effort in user code. The host controller's I2C bus will see **everything** on **any** active channel(s) of **any** TCA9548A(s). When using a single TCA9548A, we just activated one channel at a time. When using multiple TCA9548As, the same general approach is taken - only one channel on one TCA9548A will be active at any given time. This means all the other channels for all the other TCA9548As should be "deactivated". This is done by sending a 0 to the channel select control register.

![](https://cdn-learn.adafruit.com/assets/assets/000/116/851/medium800/sensors_ctrl_reg_ds.png?1669915769)

The CircuitPython library for the TCA9548A takes care of that for you under the hood. For Arduino, this must done in user sketch code.

## Example Setup

We'll show code for an Arduino example and a CircuitPython example based on the following hardware setup.

![](https://cdn-learn.adafruit.com/assets/assets/000/116/853/medium800/sensors_multiple_tcas_2x.png?1669916667)

We are intentionally not using the BME280's alternate address - so each BME280 has an address of **0x77**. The first TCA9548A is using the default **0x70** address. For the second TCA9548A, the address has been set to **0x71** using the address select solder jumpers.

## Setting the TCA9548A I2C Address

The host I2C controller will always see each TCA9548A attached. Therefore, each must have a unique I2C address. Up to 8 different addresses can be set.

Info: 

Use the solder pads **A0** , **A1** , and **A2** on the back of the breakout to set different addresses.

![sensors_tca_addr_pads.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/999/medium640/sensors_tca_addr_pads.jpg?1670522473)

![I2C](https://cdn-learn.adafruit.com/assets/assets/000/115/951/medium640/components_i2ctable.jpg?1666044858 )

In the table above, **L** (for "low") is with the address jumpers open / unsoldered - i.e. their default configuration. **H** (for "high") is set by adding a solder blob to short out the two pads of the jumper.

Here's an example of setting address `0x71` by shorting the **A0** pad with a solder blob.

![sensors_pin.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/855/medium640/sensors_pin.jpg?1669921565)

![sensors_pin2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/856/medium640/sensors_pin2.jpg?1669921668)

# Working with Multiple Same Address I2C Devices

## Arduino

OK, now to code up the example with two TCA9548As and thee BME280s.

Here's the code:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/I2C_Multiple_Same_Address/arduino/multi_tca_2x/multi_tca_2x.ino

With that sketch running on the Arduino board, the output in the Serial Monitor will look like this:

![](https://cdn-learn.adafruit.com/assets/assets/000/116/854/medium800/sensors_Screenshot_from_2022-12-01_09-59-12.png?1669917579)

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:

```cpp
// 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:

```auto
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.

```cpp
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
```

# Working with Multiple Same Address I2C Devices

## CircuitPython

Here's the CircuitPython code that uses the multiple TCA9548As:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/I2C_Multiple_Same_Address/circuitpython/multi_tca_2x/code.py

With that code running on the CircuitPython board, the output will look like this:

```terminal
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Multiple BME280 / Multiple TCA9548A Example
--------------------
BME280 #1 Pressure = 994.355
BME280 #2 Pressure = 994.413
BME280 #3 Pressure = 994.165
--------------------
BME280 #1 Pressure = 994.39
BME280 #2 Pressure = 994.425
BME280 #3 Pressure = 994.159
```

The CircuitPython library already disables all channel outputs (when context manager exits) on the TCA9548As. Therefore, the only extra work needed is in the initial setup. For each TCA9548A, a separate instance is created:

```python
# For each TCA9548A, create a separate instance and give each
# the *same* I2C bus but with specific address for each
tca1 = adafruit_tca9548a.TCA9548A(i2c, 0x70)   # TCA with address 0x70
tca2 = adafruit_tca9548a.TCA9548A(i2c, 0x71)   # TCA with address 0x71
```

Then, just like before, the TCA channel is passed in when creating each BME280 instance:

```auto
# Create each BME280 using the TCA9548A channel instead of the I2C object
# Be sure to use the TCA instance each BME280 is attached to
bme1 = adafruit_bme280.Adafruit_BME280_I2C(tca1[0])   # TCA 1 Channel 0
bme2 = adafruit_bme280.Adafruit_BME280_I2C(tca1[1])   # TCA 1 Channel 1
bme3 = adafruit_bme280.Adafruit_BME280_I2C(tca2[0])   # TCA 2 Channel 0
```

 **NOTE** - be careful on the specific instance variable used. Note how `tca1` is used for `bme1` and `bme2`, while `tca2` is used for `bme3`.

After the initial setup, nothing special needs to be done. Simply use the properties of each instance:

```python
# Access each sensor via its instance
pressure1 = bme1.pressure
pressure2 = bme2.pressure
pressure3 = bme3.pressure
```

# Working with Multiple Same Address I2C Devices

## Two Devices using Address Translator

Info: Running an I2C scan to verify a setup is highly recommended when using an address translator.

But that's not all! There's yet another approach for dealing with multiple same address I2C devices - address translation.

With this approach, instead of using a muxer, a different specialized device (address translator) is used which translates the device's I2C address on the fly. This has the benefit of not needing to worry about changing the muxer's channel, but has some other quirks and limitations. Here we show some usage examples using the LTC4316.

### Adafruit LTC4316 I2C Address Translator

[Adafruit LTC4316 I2C Address Translator](https://www.adafruit.com/product/5914)
Adafruit has hundreds of designs that use I2C - a two-wire protocol that can let you quickly connect sensors, OLEDs, GPIO expanders, and more. [Folks love I2C because you can simply connect 4 wires for power and data, and even...](https://learn.adafruit.com/working-with-i2c-devices)

In Stock
[Buy Now](https://www.adafruit.com/product/5914)
[Related Guides to the Product](https://learn.adafruit.com/products/5914/guides)
![Angled shot of black, rectangular I2C address breakout board.](https://cdn-shop.adafruit.com/640x480/5914-01.jpg)

See the main guide for details about the LTC4316:

[LTC4316 Main Guide](https://learn.adafruit.com/adafruit-ltc4316-i2c-address-translator/overview)
Warning: The LTC4316 does not work well with clock stretching I2C devices.

## Example Setup

We'll show code for an Arduino example and a CircuitPython example based on the following hardware setup.

![](https://cdn-learn.adafruit.com/assets/assets/000/129/316/medium800/sensors_ltc4316_two_devices.png?1712767316)

In this setup both BME280's are using the default `0x77` I2C address. The LTC4316 is configured with the A4 and A5 switches ON. This means those bits of the I2C address are _ **not** _ XOR'd. Therefore, only the upper bit of the I2C address is XOR'd. As a result, the BME280 "behind" the LTC4316 will have its address show up as `0x37`.

# Working with Multiple Same Address I2C Devices

## Arduino

## I2C Scan Sanity Check

To verify the I2C addresses, an I2C scan can be used. See the guide linked below for more information on I2C scanning. The guide also has a Arduino I2C scan code example that can be used.

[Arduino I2C Scan](https://learn.adafruit.com/scanning-i2c-addresses/arduino)
Here is the resulting output seen in the Arduino Serial Monitor:

![](https://cdn-learn.adafruit.com/assets/assets/000/129/075/medium800/sensors_Screenshot_from_2024-03-29_13-24-14.png?1711743956)

The BME280 found at address `0x77` is the one directly attached. The `0x37` address is the BME280 located downstream of the LTC4316. These are the two addresses we need for modifying the code. The `0x37` address can be thought of as an alternate address for the BME280. In that manner, the code usage is the same as the **Two Devices using Alternate Address** approach shown previously. The only difference is the actual address.

## Code Example

Here's the code:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/I2C_Multiple_Same_Address/arduino/multi_bme280_ltc4316/multi_bme280_ltc4316.ino

Here's the output:

![](https://cdn-learn.adafruit.com/assets/assets/000/129/072/medium800/sensors_Screenshot_from_2024-03-29_13-12-22.png?1711743162)

Note how for each device, there is a separate instance created:

```cpp
Adafruit_BME280 bme1;  // BME280 #1 @ 0x77
Adafruit_BME280 bme2;  // BME280 #2 @ 0x37
```

And then for each, the `begin()` function is called and the address is specified:

```cpp
bme1.begin(0x77);  // address = 0x77 (default)
bme2.begin(0x37);  // address = 0x37 (behind TCA4316)
```

Here we intentionally specify the default `0x77` address just to be explicit. And `0x37` is the address for the BME280 behind the TCA4316.

Once that is taken care of, the two instances can be used to directly read the sensor values:

```cpp
pressure1 = bme1.readPressure();
pressure2 = bme2.readPressure();
```

# Working with Multiple Same Address I2C Devices

## CircuitPython

## I2C Scan Sanity Check

To verify the I2C addresses, an I2C scan can be used. See the guide linked below for more information on I2C scanning. The guide also has a CircuitPython I2C scan code example that can be used.

[CircuitPython I2C Scan](https://learn.adafruit.com/scanning-i2c-addresses/circuitpython)
Running that I2C scan code with the two BME280's attached shows:

```terminal
Checking board.I2C()...ADDED.
Checking board.STEMMA_I2C()...ADDED.
Checking busio.I2C(board.GP1, board.GP0)...SKIPPED: no such attribute
----------------------------------------
I2C SCAN
----------------------------------------
board.I2C() addresses found: ['0x37', '0x77']
board.STEMMA_I2C() addresses found: ['0x37', '0x77']
board.I2C() addresses found: ['0x37', '0x77']
board.STEMMA_I2C() addresses found: ['0x37', '0x77']
board.I2C() addresses found: ['0x37', '0x77']
board.STEMMA_I2C() addresses found: ['0x37', '0x77']
```

The BME280 found at address `0x77` is the one directly attached. The `0x37` address is the BME280 located downstream of the LTC4316. These are the two addresses we need for modifying the code. The `0x37` address can be thought of as an alternate address for the BME280. In that manner, the code usage is the same as the **Two Devices using Alternate Address** approach shown previously. The only difference is the actual address.

## Code Example

Here's the code:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/I2C_Multiple_Same_Address/circuitpython/multi_bme280_ltc4316/code.py

Here's the output:

```terminal
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Two BME280 Example
--------------------
BME280 #1 Pressure = 1002.28
BME280 #2 Pressure = 1001.88
--------------------
BME280 #1 Pressure = 1002.28
BME280 #2 Pressure = 1001.91
--------------------
BME280 #1 Pressure = 1002.26
BME280 #2 Pressure = 1001.88
--------------------
BME280 #1 Pressure = 1002.26
BME280 #2 Pressure = 1001.88
```

These are the two important lines:

```python
bme1 = adafruit_bme280.Adafruit_BME280_I2C(i2c, 0x77)  # address = 0x77
bme2 = adafruit_bme280.Adafruit_BME280_I2C(i2c, 0x37)  # address = 0x37
```

They create a separate sensor instance for each BME280 and specify the I2C address for each. We intentionally specify the default `0x77` address just to be explicit. The `0x37` address was determined from the I2C scan.

After that, each can be used to read the sensor values:

```python
pressure1 = bme1.pressure
pressure2 = bme2.pressure
```


## Featured Products

### TCA9548A I2C Multiplexer

[TCA9548A I2C Multiplexer](https://www.adafruit.com/product/2717)
You just found the perfect I2C sensor, and you want to wire up two or three or more of them to your Arduino when you realize "Uh oh, this chip has a fixed I2C address, and from what I know about I2C, you cannot have two devices with the same address on the same SDA/SCL pins!" Are you...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2717)
[Related Guides to the Product](https://learn.adafruit.com/products/2717/guides)
### SparkFun STEMMA QT / Qwiic TCA9548A Mux Breakout - 8 Channel

[SparkFun STEMMA QT / Qwiic TCA9548A Mux Breakout - 8 Channel](https://www.adafruit.com/product/4704)
Do you have too many sensors with the same I2C address? Put them on the **SparkFun Qwiic Mux Breakout** to get them all talking on the same bus! The Qwiic Mux Breakout with&nbsp;TCA9548A enables communication with multiple I2C devices that have the same address that makes it...

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/4704)
[Related Guides to the Product](https://learn.adafruit.com/products/4704/guides)
### Adafruit BME280 I2C or SPI Temperature Humidity Pressure Sensor

[Adafruit BME280 I2C or SPI Temperature Humidity Pressure Sensor](https://www.adafruit.com/product/2652)
Bosch has stepped up their game with their new BME280 sensor, an environmental sensor with temperature, barometric pressure&nbsp;and&nbsp;humidity! This sensor is great for all sorts of indoor environmental sensing and can even be used in both I2C and SPI!

This precision sensor from...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2652)
[Related Guides to the Product](https://learn.adafruit.com/products/2652/guides)
### STEMMA QT / Qwiic JST SH 4-pin Cable - 100mm Long

[STEMMA QT / Qwiic JST SH 4-pin Cable - 100mm Long](https://www.adafruit.com/product/4210)
This 4-wire cable is a little over 100mm / 4" long and fitted with JST-SH female 4-pin connectors on both ends. Compared with the chunkier JST-PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert and remove.

<a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/4210)
[Related Guides to the Product](https://learn.adafruit.com/products/4210/guides)
### STEMMA QT / Qwiic JST SH 4-pin to Premium Male Headers Cable

[STEMMA QT / Qwiic JST SH 4-pin to Premium Male Headers Cable](https://www.adafruit.com/product/4209)
This 4-wire cable is a little over 150mm / 6" long and fitted with JST-SH female 4-pin connectors on one end and premium Dupont male headers on the other. Compared with the chunkier JST-PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert...

In Stock
[Buy Now](https://www.adafruit.com/product/4209)
[Related Guides to the Product](https://learn.adafruit.com/products/4209/guides)
### Half Sized Premium Breadboard - 400 Tie Points

[Half Sized Premium Breadboard - 400 Tie Points](https://www.adafruit.com/product/64)
This is a cute, half-size breadboard with&nbsp;400 tie points, good for small projects. It's 3.25" x 2.2" / 8.3cm&nbsp;x 5.5cm&nbsp;with a standard double-strip in the middle and two power rails on both sides.&nbsp;You can pull the power rails off easily to make the breadboard as...

In Stock
[Buy Now](https://www.adafruit.com/product/64)
[Related Guides to the Product](https://learn.adafruit.com/products/64/guides)
### Adafruit LTC4316 I2C Address Translator

[Adafruit LTC4316 I2C Address Translator](https://www.adafruit.com/product/5914)
Adafruit has hundreds of designs that use I2C - a two-wire protocol that can let you quickly connect sensors, OLEDs, GPIO expanders, and more. [Folks love I2C because you can simply connect 4 wires for power and data, and even...](https://learn.adafruit.com/working-with-i2c-devices)

In Stock
[Buy Now](https://www.adafruit.com/product/5914)
[Related Guides to the Product](https://learn.adafruit.com/products/5914/guides)

## Related Guides

- [Adafruit LTC4316 I2C Address Translator](https://learn.adafruit.com/adafruit-ltc4316-i2c-address-translator.md)
- [How to Scan and Detect I2C Addresses](https://learn.adafruit.com/scanning-i2c-addresses.md)
- [CircuitPython Libraries on Linux and the 96Boards DragonBoard 410c](https://learn.adafruit.com/circuitpython-libraries-on-linux-and-the-96boards-dragonboard-410c.md)
- [Adafruit IO Environmental Monitor for Feather or Raspberry Pi](https://learn.adafruit.com/adafruit-io-air-quality-monitor.md)
- [DIY Trinkey No-Soldering USB Air Quality Monitor](https://learn.adafruit.com/diy-trinkey-no-solder-air-quality-monitor.md)
- [Working with I2C Devices](https://learn.adafruit.com/working-with-i2c-devices.md)
- [I2C Addresses and Troublesome Chips](https://learn.adafruit.com/i2c-addresses.md)
- [Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout](https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout.md)
- [CircuitPython Libraries on Linux and the NVIDIA Jetson Nano](https://learn.adafruit.com/circuitpython-libraries-on-linux-and-the-nvidia-jetson-nano.md)
- [IoT Air Quality Sensor with Adafruit IO](https://learn.adafruit.com/diy-air-quality-monitor.md)
- [Feather + Raspberry Pi Weather Monitoring Network with LoRa or LoRaWAN](https://learn.adafruit.com/multi-device-lora-temperature-network.md)
- [CircuitPython Libraries with the Binho Nova Multi-Protocol USB Host Adapter](https://learn.adafruit.com/circuitpython-with-binho-nova-multi-protocol-usb-host-adapter.md)
- [Integrating Home Assistant with Adafruit IO](https://learn.adafruit.com/integrating-adafruit-io-with-home-assistant.md)
- [Adafruit BME280 Humidity + Barometric Pressure + Temperature Sensor Breakout](https://learn.adafruit.com/adafruit-bme280-humidity-barometric-pressure-temperature-sensor-breakout.md)
- [Air Quality Sensor 3D Printed Enclosure](https://learn.adafruit.com/air-quality-sensor-silo-house.md)
- [No-Code IKEA Vindriktning Air Quality Sensor Hack with Adafruit IO](https://learn.adafruit.com/no-code-ikea-vindriktning-hack-with-qt-py-esp32-s3-and-adafruit-io.md)
