In this example we are going to create a I2C logic level converter.
Disclaimer:
We do not take any responsibility for possible errors in the guide or errors that you might do wiring it up. Incorrect wiring can result in damaged sensor or damaged Raspberry PI.
The problem:
Some I2C devices their logic on 3.3 V while others on 5V. Getting 5V on your I2C pins on Raspberry PI can damage your Raspberry PI. And incorrect voltages can also give you wrong results.
In some of our guides we have used 15k resistors to drop the voltage on the I2C bus to make it safe. But this is not good solution if you have many more than one device and will not work with all devices.
A proper solution is to use I2C logic converter where some devices can run their logic on 5 V while others on 3.3 and the logic converter takes care of converting the signals seamlessly in both directions.
As you can see then the I2C bus in the picture bellow is running on 2 separate voltages.
For our BMP180 Barometer guide then it was done like this:
But better would be like this:
Same goes for the PCF8591 Analog To Digital guide, using Logic converter would be far better there.
There are many cheap brakeout-boards that you can buy to convert I2C voltages. In this guide we will go into the deep end of the pool and just make our own. At bottom we cover how to wire up some of the bought pre-made ones.
Pieces we use in this example:
- Raspberry PI 2 (or Raspberry PI 3)
- Cobbler and Cobbler cable
- You either need to be able to run our BMP180 Barometer guide or our PCF8591 Analog To Digital guide to test this.
- Mosfet 2N7000 (2x)
- Resistor 10kΩ (4x)
If you are not familiar with breadboards, how to place a cobbler on the breadboard or need to know how to read the color codings on the resistors then click here bellow
Using breadboard Resistor color codings
The circuit:
It is good idea to test this on breadboard.
About the Mosfets that we use:
The 2N7000 uses this symbol where the Gate, drain and source are as follows.
Physically it looks like this:
Where 1 is the Source (S), 2 is the Gate (G), and 3 is the Drain (D)
Testing it all:
To test this then you can either update our BMP180 Barometer guide or our PCF8591 Analog To Digital guide. Removing the 15kΩ resistors. And connecting the SDA and SCL through the new device. And of course connecting 5V to 5V and 3.3V to 3.3V.
Then have Volt meter connected to SCL 3.3V and to ground as follows:
When running the examples you should be measuring close to 3.3V here. (I was using the Barometer example)
In my test I did get perfect reading !
If everything is all right then we proceed and move the Volt meter to the 5V side of the SCL:
I got 5.19 V here, I felt it was a little high but measuring the Raspberry PI’s 5V gave me 5.2 V, so the 5.19V is perfect result.
Then I proceeded testing the 3,3V SDA in same way and finally the 5V SDA. Once I had gotten perfect results for all 4 when using the Barometer then I had proven that we have the I2C bus working on 2 separate voltages like this:
In the end I made my own brake-out board to be able to have I2C converter ready for future experiments where I use I2C bus. The way I made it then I can push it right into a breadboard.
I was a bit cocky, using surface mounted resistors that are so tiny that I could not see them at all. Soldering them was absolute nightmare. But in the end it somehow worked, and the brake-out board fits perfectly on breadboard and is small.
Using this converter then you should now be able to use many I2C devices on your bus at once if they have separate addresses, and they can run either on the 5V side or 3.3V side depending on the device.
If you buy a ready made logic converter then the following 2 layouts are probably the most common ones you will see:
With this format then you wire it like this:
5V -> HV
GND -> GND
3.3V -> LV
GND -> GND
SDL3.3V -> LV1
SDL5V -> HV1
SDA3.5V -> LV2
SDA5V -> HV2
Then you use the two first channels, first for SDL conversion and 2nd channel for SDA conversion. Leaving channel 3 and channel 4 unused.
The other format you will commonly see, which is more for use to convert serial or SPI communications, but can be used for I2C also is:
Here only the TX lanes are bi directional while the RX lanes go only from high to low. So this board only has 2 channels.
So for use with I2C conversion then you would wire it like:
5V -> HV
GND -> GND
3.3V -> LV
GND -> GND
SDL3.3V -> TXI (Channel 1)
SDL5V -> TXO (Channel 1)
SDA3.5V -> TXI (Channel 2)
SDA5V -> TXO (Channel 2)
This is it for now.