# $I^2C$ 3.3 to 5.0 V conversion

I'm trying to interface a 3.3V $I^2C$ device to a 5V Arduino.

I don't have any problem with SCL line. I can use a simple voltage divider but I have an issue with the SDA line as this is bi-directional.

I'm not at all sure how to handle this. I have though of adding a pair of diodes, with a voltage divider on the slave input side and nothing extra on the master input.

Are there any other solutions?

-

Good document about the subject is Bi-directional level shifter for I2C-bus and other systems which uses a single mosfet as a bi-directional level shifter.

-
I like the Philips circuit. Clever. It might in some ways be better if the I2C outputs didn't have to sink all the current from all the pull-ups, but designing an active I2C repeater is hard; I don't think it can be done with normal logic, since the repeater must be able to detect a rising edge and react to it before any I2C devices can. –  supercat May 14 '11 at 5:48

To expand upon sivu's answer, this is a common use for so-called "bus switches" which are basically logic-controlled MOSFETs. Using discrete MOSFETs has some drawbacks (parasitic capacitance / capacitive coupling being one) and it can be tricky to choose a good MOSFET. The bus switches are optimized for use in high-speed logic circuits.

Several manufacturers make them, including Fairchild, TI, IDT, and Pericom. Take a look at the NC7SZ384.

See the following appnotes, among others:

-

Many Arduino's have onboard support to run at 3.3 V. Actually, all can run at 3.3 V and the FTDI chip schematic explains how in an example. Paul, who made the Teensy USB Arduino, had suggested that I could splice the USB cable open and supply a 3.3 V voltage in place of the VCC line of the cable. You could try this. But there are also other options.

1. Check the logic levels for the Arduino. I believe they support 3.3 V as logic HIGH even on a 5 V sourced Atmel. A SparkFun article states: "*Connecting a 3.3 V digital output pin to a 5 V input pin is often straightforward. Most devices are fairly tolerant to the minimum voltage that they will accept as a digital high value. Most Atmel microcontrollers, for example, accept anything above 0.6*VCC as high, so the 3.3 V device must output a level above 3 V (0.6*5 V).*"
2. Purchase one of the Arduino clones that has jumpered 3.3 V and 5 V selectors. I use the RBBB cloan which I have set the supply cables FTDI chip to 3.3 V. But there are many others that have actual 3.3 V configuration options, including one of the recent official Arduinos if I remember correctly. You could also use the Teensy USB with his Arduino plugin and follow the directions on his site to install a 3.3 V regulator.
3. Splice the USB cable and provide a laboratory power supply quality 3.3 V source in place of the VCC line of the USB cable. It should be low current, as Paul has suggested. Hence, either a good quality voltage source. You could also just put a couple of batteries in series to get the desired voltage.
4. If you are interested, I can try to examine the schematic of your Arduino and perhaps it is possible to make a change to the FTDI configuration that would allow for 3.3 V.

Lastly, we have a discussion that might interest you about this over here on Chiphacker about uni-directional and bi-directional solutions for voltage step down. This article on SparkFun mentioned by todbot is useful, as is the discussion on bidrectional MOSFET article linked from SparkFun. To summarize the SparkFun article:

• Inline resistor. Uni-directional. Step-down only -- reduces current, ICs I/O clamping diodes can limit max input.
• Series resistors. Uni-directional. Step-down only, but granular.
• Diode. Uni-directional. Step-down. Safer. High from 5 V blocks diode; the 3.3 V side then ties to high. But, if you reverse the diode configuration, couldn't you also step-up?
• MOSFET. Bi-directional. Step-down or step-up.
• In comments: Optical isolation example: 4N25. High current.
• In comments: Zener diode example: 1N4728A