I2C level converter

You’ve got several devices which communicate via the I2C protocol, but some of them can only operate at 3.3V while the rest are hungry for a 5V connection. What to do? [Linux-works] built this I2C level converter to solve the problem.

The circuit comes from an NXP app note (PDF) on the issue. You can take a quick peek at the suggested schematic from that document. The design uses two MOSFETS for each side of the adaptor. Perhaps a better way to explain this is that you need one for the higher voltage and one for the lower voltage on each of the two data lines for a total of four parts. This allows for both of the buses to communicate as one, while still having their own 3.3V and 5V pull-up resistors.

[Linux-works] concedes that there are chips designed to do this for you, but he was able to source the BSS138 MOSFETs locally and for about ten cents a piece. Not a bad alternative to putting in a parts order.

Comments

  1. Bill says:

    Haha, I mentioned this trick in my upcoming EEWeb interview. Pretty handy, and I haven’t seen it in many places around the web.

  2. 3.3v ttl and 5v ttl use the same switching levels, so no conversion needing for “5v tolerant” 3.3v logic. The PDF mentioned is for level conversion with power down isolation…

    • drew says:

      but if you have a 3v3 and 5V part talking then at some point you could be shooting 5V into a 3v3 part… that’s bad

    • Nova says:

      A useful scenario might occur if you’re trying to interface a 3.3v only part on a board you’re unwilling or unable to modify that’s running at 5v. perhaps it doesn’t even have a 3.3v supply or something? I think that’s where this circuit really shines. because now the supplies don’t even have to come up at the same time.

  3. If the 5V side is never powered down while the 3.3V side is powered, then you only need one transistor per I2C line, so two transistors total. That’s how I’ve used this circuit.

    The second transistor is to prevent the body diode passing current from the powered 3.3v side into an unpowered 5v side.

    This is explained in the app note.

  4. space says:

    SMD components have notoriously fragile leads. If there is any chance they should be soldered to the PCB. I’d use #32 AWG enameled wire rather than anything with PVC insulation.

  5. ftorama says:

    Simply place your pull-ups on 3,3V

    All 5V logic should switch with 3,3V and given that I2C is an open-collector topology, no 5V will travel on lines.

  6. tutnixzursache1 says:

    some (all?) chinese/hk products have this crudely levelshifter for 5V TTL output/input. But if you need another level you cant use this “levelshifter” on your side. You have to use a real levelshifterchip.

  7. BD says:

    Be careful using this circuit when the higher voltage right hand side can be in a situation where its power rail is removed. I used this circuit on a project wherein the higher voltage right side was not necessarily always powered and in this situation the body diodes of the MOSFETs allow the lower voltage side to sink current into an unpowered higher voltage side.

  8. tugboat says:

    SparkFun has been selling this for years. It’s their Logic Level Converter board.

    • bryan says:

      the sparkfun unit still uses a resistor voltage divider for one side (receive side, I think). many people have had problems with that.

      I used the NXP dual transistor method since it allowed hot-swap and that seemed like a useful enough thing to have for only 2 extra discretes.

      fwiw, this was not meant to be production; it was a midnight hack that I put together since I did not want to wait for a proper (and easier) chip and needed to get some i2c comms going that day.

      comments regarding ‘yeah, but a chip could do it’ entirely miss the point.

  9. adam says:

    I’ve done this with regular UART serial, I built my own for an arduino to iPod converter based on the sparkfun level shifter boards. I ordered a bunch of those BSS138 and use them for everything.

  10. slincolne says:

    I think NXP have a dedicated chip that does just this. Why mess with discretes when the problem has been solved already?

  11. Springuin says:

    @slincolne: simple mosfets are easier to get, may be cheaper and do not consume any power when the bus is high.

    You do not need two mosfets! See figure 2 in the NXP application note. This works fine as long as you use pullups on both sides and make sure the diode in the mosfet points the right way.

  12. slincolne says:

    Just got home and checked – I can get a PCA9306DCUR Dual Bidirectional I2C and SMBus voltage level translator from Element14 for $1.50. It covers all the ranges, and is just 1 package to deal with. Sorry, but I’d rather work with a purpose built chip than faff around with all those discretes.

  13. compukidmike says:

    I use an SN74LVC244. It’s a logic buffer that runs on 3.3v and has 5v tolerant inputs. Works great, and it’s only $0.48 in single quantities at digikey. It comes in both DIP and SOIC packages, which is great for moving from prototype to a real product.
    However, I do agree that this hack works in a pinch.

  14. Jakke says:
  15. David Cox says:

    Can anyone explain to me why you need the pull ups on the lower voltage level? It seems that its working for me even when there is no pull up and the devices on the lower levels are all on High impedance (ie: all inputs, no internal pull-ups).

    b.t.w. the origional Philips (who invented i2c) document for this exact thing is: AN97055

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 96,670 other followers