DFR1185 I2C Address Shifter wiki

Fermion I2C address shifter

Introduction

The DFRobot Fermion I2C address shifter is a module that changes the address of I2C sensors. By hooking up this module between dev board and the sensor, the sensor will be recognised by the dev board with the new address. The module is plug-and-play, compact in size and easy to integrate into any I2C cascade system. Four new addresses can be obtained by adjusting the on-board dip switches, and at least 20 new addresses can be obtained additionally by soldering on-board resistors.

I2C communication is favoured by many developers in the open source hardware ecosystem because of its simplicity of connectivity and support for multiple dev board and sensors. Theoretically, it is possible to drive 127 devices with different addresses on one I2C channel at the same time. However, in practice, the problem of two sensors with the same address is bound to be encountered.
The solution in the past was to switch sensor ports through I2C multiplexer, but this would require developers to have some experience in developing I2C devices to avoid the possible timing effects of multiplexer. And frequent port switching in the main code would also greatly reduce code readability.

The DFRobot I2C address shifter provides a hardware solution, where the address conversion is done entirely inside the shifter, and the I2C physical address can be changed directly with a simple wire connection, without the need for complex port switching in the code, and without triggering any I2C timing bugs.

Although the I2C address shifter is powerful and easy-to-use, user need to pay attention to the following two things before using it:

  1. The address shifter does not support clock extension, so it is not suitable for special I2C sensor like the BNO055.
  2. Before using the address shifter, user need to understand how to change the sensor's I2C address in the code.

Product Characteristics

Specification

Pinout

Controller Side Description
VCC DC2.25V-5.5V input
GND Ground
SCL I2C Clock(To I2C controller)
SDA I2C Data(To I2C controller)
RDY Outputs a high level when I2C sensor address translation is complete
I2C sensor address translation not completed output low level
Sensor Side Description
VCC DC2.25-5.5V Output
GND Ground
SCL I2C Clock(To I2C sensor)
SDA I2C Data(To I2C sensor)
Dip Switch Description
A5 Controls whether the fifth bit of the I2C address is flipped (1 is flipped, 0 is not flipped)
A4 Controls whether the fourth bit of the I2C address is flipped (1 is flipped, 0 is not flipped)

I2C Address Calculate

The I2C address has 7bit, we define A6 as the highest bit and A0 as the lowest bit. The address converter flips A6 fixed by default (from 0 to 1 and from 1 to 0). You can also control whether bits A5 or A4 are flipped or not by using the on-board dip switches.

Let's take Gravity: BMI160 6-axis inertial motion sensor as an example. In the default state, the sensor address is 0x69, which translates to 0b1101001 in binary.
If the sensor is hooked up with an address shifter: And set the dip switch to A5=0,A4=0. Then only A6 is flipped from 1 to 0, A5 and A4 are not flipped, and the new address is 0b0101001 in binary, which is converted to 0x29 in hexadecimal.
If the dip switch is set to A5=1,A4=0, A6 and A5 are flipped at the same time and A4 is not reversed. The new address is 0b0001001 in binary, which converts to 0x09 in hexadecimal.
If the dip switch is set to A5=0,A4=1, then A6 and A4 are flipped at the same time and A4 is not fliped. The new address is 0b0111001 in binary,converted to 0x39 in hexadecimal.
If the dip switch is set to A5=1,A4=1, then A6,A5,A4 will be flipped at the same time, and the new address will be 0b0011001 in binary, or 0x19 in hexadecimal. Gravity: BMI160 6-axis Inertial Motion Sensorhas been set to four different new addresses.

In the meantime, you need to be aware of the following.

  1. Fermion: The I2C address shifter needs to be powered up again after adjusting the on-board dip switch to set the new address.
  2. If you are using a Windows computer, you can use the programmer function of the calculator that came with your computer to do hexadecimal (HEX) to binary (BIN) conversions
  3. In the above address description: 0b is the prefix of a binary number, which means the data that follows is in binary; 0x is the prefix of a hexadecimal number, which means the data that follows is in hexadecimal.

Tutorial

Preparation

Hardware

Software

Wiring Diagram

Sample code

Result

Serial monitor outputs the data of two Gravity: BMI160 6-axis Inertial Motion Sensor


Advance tutorial

Fermion: The I2C address shifter can be switched via on-board dip switch to set the sensor to four different addresses.
If this is not enough for your needs. We have reserved a 0805 resistor pad (R2) on the module, you can refer to the schematic and Page 9 of the datasheet at the bottom of this wiki,solder the resistor to control whether the remaining I2C address bits are flipped.
This pad is connected to the XORL pin, which controls whether the lower four bits of the I2C address are flipped or not. We fixed RLB (R1 in our schematic) to 100kΩ, and you can calculate the resistance value of RLT (R2 in our schematic) and solder it yourself. Here is how we determine an R2:

  1. Firstly, from the datasheet, the module determines whether a bit of the I2C address is flipped or not by the voltage of the XORH or XORL pin, i.e. the ratio of VXORH or VORL relative to VCC. In table 2 and table 3 of the datasheet, a 1 under bit means flip-flop and a 0 means no flip-flop.

  2. Assuming that the module supply VCC is now 5V, we want to set A3-A0 to a 1 0 0 0 mode, i.e. A3 flips and A2~A0 do not. That means the VOXRL/VCC ratio should be 0.53125 ±0.015

  3. To help you quickly calculate the resistance, the DFRobot R&D team has summarised a general formula:
    [VCC/(R1+R2)]R1=VXORL
    Where VCC has been specified as 5V in the previous assumptions and R1 is known to be 100kΩ, the target VXORL should be 0.53125*5V = 2.65625V After substituting all the known parameters into the general formula above, it is possible to arrive at R2 ≈ 88.23529kΩ

  4. Given that the calculated R2 is not a common resistance value, we need to match it to the closest common resistance value and verify this common resistance value by substituting it back into the common formula. In this case, the closest common resistance value to 88.23529kΩ is 86.6kΩ, which when substituted into the calculation gives VXORL ≈ 2.67953V, or VXORL/VCC ≈ 0.53906. This ratio falls in the range of 0.53125 ± 0.015, so we can use 86.6kΩ as the resistance value for R2.

    To help save you the tedious calculations, we've helped you list a few R2 resistance values that we've verified:

    R2 A3 A2 A1 A0
    91kΩ/86.6kΩ 1 0 0 0
    68kΩ 1 0 0 1
    51kΩ 1 0 1 0
    39kΩ 1 0 1 1
    27kΩ 1 1 0 0

    If you are unsure of the new address after soldering the resistor, we recommend using an Arduino or ESP32 and uploading the I2C scanner to find our the new address.

FAQ

Q1: Why did the sensor address not change after adjusting the on-board dip switch.

A1: Fermion: I2C Address Shifter needs to be power off and on after adjusting the dip switch for the new address.

Q2: Why do I need to solder resistor to adjust the lower four bits of the I2C address, instead of also designing more dip switch to adjustment other bit?

A2:Dip Switch schange the address by connecting a large number of resistors in parallel or not. If the lower four bits are also use the dip switch, this will greatly increase the number of resistors on board.This makes the size of this module very large.

Q3:How to quickly confirm the new I2C slave address after changing toggles or soldering resistors

A3:You can connect the sensor to an Arduino or ESP32 via an address converter and upload the I2C Scanner code below. The serial monitor will output the new I2C address.

/**
   @file i2cScanner.ino
   @brief The i2c_scanner see if a device did acknowledge to the address.
   @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
   @license The MIT License (MIT)
   @author [thdyyl](yuanlong.yu@dfrobot.com)
   @version V0.1
   @date 2024-08-05
*/
#include <Wire.h>

void setup(){
  Wire.begin();
  Serial.begin(115200);
  Serial.println();
  Serial.println("I2C Scanner");
}

void loop(){
  uint8_t error, address;
  int numDevices;
  Serial.println("Scanning...");
  numDevices = 0;
  for (address = 1; address < 127; address++ ){
    // The i2c_scanner uses the return value of the 
    // Write.endTransmisstion to see if a device 
    // did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0){
      Serial.print("I2C device found at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.print(address, HEX);
      Serial.println(" !");
      numDevices++;
    }else if (error == 4){
      Serial.print("Unknow error at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  if (numDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
  delay(2000); // wait 2 seconds for next scan
}

More

DFshopping_car1.png Get one from DFRobot store