Let's Make Robots!

Running both 5v and 3.3v devices on I2C

 

Problem Statement:

 

 

  1. Arduino UNO is the most prolific version of Arduino board, and runs at 5v DC.  It's I2C interface (Analog pins A4 and A5)  will drive to 5v.
  2. Raspberry Pi runs at 3.3v.  Both of it's I2C interfaces run at 3.3v.
  3. I2C devices purchased through Sparkfun, Adafruit, SeeedStudio, Parallax,  Pololu, can be any combination of 3.3v or 5v

I know the mantra is that if you only pull the SDA and SCL lines up to 3.3v on a I2C device,

they will work fine on a 5v I2C bus, but depending on tolerances of the device..

 

 

Running a 3.3v I2C device on a 5v I2C bus 

can either destroy the device immediately... 

or more likely... 

significantly reduce it's lifespan. 



 

So, how do we safely run 3.3v devices alongside 5v devices on the same bus?  

With a Bi-directional Logic Level Converter...

 

 

Logic Level Converter:  https://www.sparkfun.com/products/11978

 

 

From Sparkfun's Tutorial: ( Sparkfun: Using the Logic Level Converter )

LLC input and output arrowsLLC divided into thirdsThe LLC is designed to be very easy to use. Silkscreen indicators help identify which pins do what. There are twelve pins total – six on each side. We can divide them into groups of three to more clearly define how they relate:
The middle section of the board is where the reference supply for your high and low voltages should go. Supplying voltage to all four of these pins is required. If you’re converting 3.3V to 5V (and vice-versa), for example, you’d run 5V into the “HV” side, and 3.3V into the “LV” input. Make sure each is grounded too!
The outer pins correspond to inputs and outputs for channels 1 and 2. Each channel has one voltage divider and one MOSFET shifter.
The labels on these pins – “RXI”, “RXO”, “TXI”, and “TXO” – help describe what each pins does:

  • RXI – High voltage input to voltage divider from high-voltage device. Signal will be shifted down and sent to low-voltage device on “RXO” pin.
  • RXO – Low voltage output from voltage divider to low-voltage device. Signal is shifted down from “RXI” input.
  • TXI – Low voltage input/output of MOSFET circuit. This pin interacts with “TXO” on the high side. Bi-directional, but this is the only shifter that will shift from low to high.
  • TXO – High voltage input/output of MOSFET circuit. This pin interacts with “TXI” on the low side. Bi-directional, but this is the only shifter that will shift from low to high.

To send a signal from the low-voltage side to the high-voltage side (e.g. from 3.3V to 5V), the signal must be input at “TXI”. It’ll pass through the converter and come out as a higher voltage on the “TXO” (transmit output) pin.
On the other hand, a signal that strictly travels from high to low-voltage should pass from “RXI” to “RXO”.
Sending a signal from the high side to the low side is less restricted. We can use either the bi-directional channel or the voltage divider, but we may need to leave the bi-directional channel for converting from low-to-high.

 

 

Example Wiring of 3.3v and 5v I2C devices together.


Here, we have an Arduino UNO, an Accellerometer, a Compass, a Barometric Pressure Sensor, and a Raspberry PI all on the same I2C channel.  The neat thing is that with the UNO, as it has a 3.3v regulator on board, you can power  both 3.3v and 5v devices.

 

 

 


References:

Arduino Forum : I2C Bus with 3.3v and 5.0v Device

Raspberry Pi and Arduino linked via I2C

Sparkfun: Using the Logic Level Converter

https://www.sparkfun.com/products/11978

 

 

 

Sparkfun,

Adafruit,

SeeedStudio,

Parallax,

Pololu,


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I always use a logic level converter to connect a 3V3 I2C device to a 5V Arduino. http://letsmakerobots.com/node/34444

That said, I've not seen anyone saying theyve actually fried something from tieing 3.v and 5v devices to the same I2C.  Lots (*LOTS*) of articles on why you shouldn't.  I guess the best reason is the unpredictability of a 5v device (accellerometer, etc) actually reading 3.3v as a high.  The Spec  is .7 x 5v  or 3.5v

 

It's not that 5v device won't sense 3.3v, but rather a 3.3v device will not last for any great length of time on a 5v bus.

If, like me, you have chosen for one reason or another to purchase the lowly Arduino UNO, this becomes important...  When using the UNO as an I2C Master, it drives the bus to 5v, even though it has a 3.3v regulator onboard. 

*most* I2C devices are hearty enough to endure over voltage for a period of time, but early failure is definately a concern. 

In the common case of  I2C between Raspberry Pi and Arduino, it is typical that the PI (a 3.3v device) is master, and therefore drives the bus at 3.3v.  This is a high enough signal that the 5v Arduino Slave device can read as a high.   No harm, no foul.

 

In my particular case, I'm attempting to run my I2C bus in Multi-Master mode.   A series of I2C devices, MOST are capable of 5v as they are either highly tolerant, or have a 3.3v regulator onboard...  BUT, in this case, I now have a 3.3v PI as Master, collecting data for logistics and mapping, and a 5v Arduino as Master, collecting from these devices for trajectory and envirnment info.

 

This *could* possibly make the case for a second I2C bus, but I've chosen to use a single bus as both masters need the same info.

 

Does the Arduino really drive the I2C bus high? I2C lines are only supposed to be driven low. The pull-ups resistors bring the line high again.

Neither the Arduino nor the Pi should be driving the I2C lines high if they are complying with the I2C standard (at least that's what I've read many times).

Or does the Arduino's I2C bus rely on the internal pull-up resistors for I2C communication. As I think about it, this seems likely. If this is the case then what about disabling the internal pull-ups and use external 3.3V pull-ups? Of course the I2C library may need to be modified to do this which probably isn't very appealing.

Being open drain by design, I2C expects the SDA and SCL to be pulled up to VDD and sinks to ground for low. 

So I concede you are correct on the bus SPEC.  The Arduino (UNO) uses it's Analog lines A4 and A5 for SDA and SCL respectively and actually does have weak internal pullups on these lines to the 5v rail.  if you use stronger pullups (eg 4.7k) to the 3.3v then the potential damage issue goes away.  

(can anyone verify whether the internal I2C pullups on the Arduino can be disabled?)

That reduces the concern for the OVERVOLTAGE side of things... there's still the UNDERVOLTAGE side of the issue with mixxing voltages in I2C. 

SDA and SCL logic levels

Due to the variety of different technology devices (CMOS, NMOS, bipolar) that can be connected to the I2C-bus, the levels of the logical ‘0’ (LOW) and ‘1’ (HIGH) are not fixed and depend on the associated level of VDD. Input reference levels are set as 30 % and 70 % of VDD; VIL is 0.3VDD and VIHis 0.7VDD. See Figure 38, timing diagram. Some legacy device input levels were fixed at VIL = 1.5 V and VIH= 3.0 V, but all new devices require this 30 %/70 % specification. See Section 6 for electrical specifications

Philips - The author of the I2C Spec recommends bidirectional level shifter to ensure proper signal tolerances.

http://www.nxp.com/documents/application_note/AN10441.pdf

Different voltage devices could be connected to the same bus by using pull-up resistors to the supply voltage line. Although this is the simplest solution, the lower voltage devices must be 5 V tolerant, which can make them more expensive to manufacture. By using a bidirectional level shifter, however, it is possible to interconnect two sections of an I2C-bus system, with each section having a different supply voltage and different logic levels. Such a configuration is shown in Figure 1 . The left ‘low-voltage’ section has pull-up resistors and devices connected to a 3.3 V supply voltage; the right ‘high-voltage’ section has pull-up resistors and devices connected to a 5 V supply voltage. The devices of each section have I/Os with supply voltage related logic input levels and an open-drain output configuration.
Which is all a lot of words for "It will *probably* work, but we won't gaurantee it". 
My train of thought is still along the lines of   "If the Spec sheet says it's needed, and the product vendors say they wont gaurantee their products outside of the spec, and the fix is just a few dollars... "
The official I2C Spec.

According to this website the internal pull-up can (and they think should) be disabled. There was an interesting comment about the Mega 2560 also having external pull-ups would need to be removed in order to use the I2C line at 3.3V.

Pulling the bus to 5V if the 3.3V devices which are 5V tolerant isn't really a solution either since the 3.3V devices' clamping diodes will pull the line back down close to 3.3V.

You've almost got me convinced to use level shifters, and I would if I were making a board for someone else, but I've never had a problem using 5V I2C devices on a 3.3V bus.

It's good to know about the Arduino's internal pull-ups. Thanks for information and answering my questions.

 

I appreciate the challenge.  I learned a bit more in this conversation.  Always a good thing.

 

In my case, I *do* plan on manufacturing a control board that marries the Raspberry Pi, an ATmega328 (? or Mega?) a couple H bridges, PWM controllers, and I2C connectors for several standard devices.  So it makes sense to me, to do it such that I don't worry about returns...

 

But as a one off... I probably wont be as concerned anymore. 

 

So why not just pull the I2C line to 3.3V? I haven't found any 5V I2C devices which won't work on a 3.3V bus.

Have any of you come across 5V I2C devices which don't sense 3.3V as logic high?

 

My favorite microcontroller is the 3.3V Propeller. I've used it with lots of different 5V devices. The only 5V device I've found which doesn't work with 3.3V logic is the WS2812 LED (NeoPixel). The NeoPixel needs a level shifter to work well with the Propeller (though these aren't I2C devices).


There will certainly be times when an I2C level shifter will be a good thing to use. For one thing it could increase the rise time on the 5V bus side allowing for faster I2C communication rates (if the level translators don't slow the rates down).

I wonder how often a level shifter will really be needed. I personally haven't ever used one for I2C devices.

.