Super Simple Bidirectional 5Volt & 3.3Volt Logic Level Converter Needed

I need a SUPER simple, Bidirectional, Logic Level Converter for one pair of I2C connections. ((( 2x 5V I2C master connections, with 1x Data & 1x CLK pins. As well as 2x 3.3V I2C slave connections, with 1x Data & 1x CLK pins. )))
However I have no idea how to do this, and that is why I'm here asking for help.

The only parts I have available during the vacation I'm on right now are are as follows:

Boards:

  • 1x Arduino Mega
  • 1x SparkFun 3Axis, 3.3V-Logic, I2C, Magnetometer Sensor-->( HMC5883L )
    Resistors:
  • 1x 150-Ohm resistor
  • 1x 220-Ohm resistor
  • 2x 510-Ohm resistors
  • ~40x 1k-Ohm resistors
  • 1x 8.1k-Ohm resistor
  • ~40x 10k-Ohm resistors
  • 2x 15k-Ohm resistors
  • 2x 22k-Ohm resistors
  • ~40x 100k-Ohm resistors
    Diodes:
  • 26x 1-Amp assorted Rectifier Diodes
    (May include these values: 1N4001, 1N4002, 1N4003, 1N4004, 1N4005, 1N4006 and/or 1N4007. Plus 1x MysterySurpriese-Diode-O-Annoyance)
    Capacitor:
  • 1x 130pF-ceramic capacitor(0.00013uF)
    Transistors:
  • 6x 2N3904 NPN bipolar transistors
  • 2x TIP120 NPN darlington pair transistors
  • 2x TIP41C NPN power transistors(Low gain, but also low current project)
    Other:
  • 2x Full++ Breadboards
  • 2x Mini Breadboards
  • 200x Feet of 22AWG wire
  • 1x 8-Ohm 0.5Watt Speeker
  • 1x Compass
    Tools:
  • Everything I might and might not need

I need a SUPER simple, Bidirectional, Logic Level Converter for one pair of I2C connections. ((( 2x 5V I2C master connections, with 1x Data & 1x CLK pins. As well as 2x 3.3V I2C slave connections, with 1x Data & 1x CLK pins. )))
However I have no idea how to do this, and that is why I'm here asking for help.

The Arduino board offers a +5V and a +3.3V supply pins, which can be used for your data voltage rails.

Use NPN transistors, and connect the collector(s) to the respective voltage level that you want to switch, via a pull-up resistor as shown in the pic. Connect the base(s) to the respective line that you want to switch(DATA and CLK) via a current limiting resistor, as shown in the pic. Connect the emitter to common ground of both the I2C devices and your arduino. Connect the receiving line of the I2C device(s) directly to the collector of the respective transistor switching either the 3.3V or 5V line. Keep in mind this will invert the signal, to which you will have to either correct in code or repeat the circuit to invert again, by connecting the base of the second transistor, to the collector of the first, then the receiving line to the collector of the second transistor. Kind of like the circuit in the pic below, without the extra caps and resistors, as this circuit is built for amplifying.

Good luck.

I2C interface should be using open-drain or open-collector drivers so the only problem is ensuring there is a high enough voltage from the pull-ups to register as logic high for the higher-voltage side (and simultaneously not damaging the low voltage side).

I would suggest using a pull-up network that is 1k to 3.3V, 10k to 5v (this provides passive pull up to 3.45V which won't damage 3.3V device but should register as logic high reliably on the Arduino pins - actually the 10k resistor probably isn't needed, it will make things go a little faster as the Arduino's high threshold isn't far below 3.3V.

The important thing is to never drive the SCL and SDA lines high from the higher voltage side. This means on the Arduino your code (or the I2C library code) must never simulateously set pinMode to OUTPUT while digitalWrite is HIGH.

void setup ()
{
  ...
  digitalWrite (pin, LOW) ; // never pull high actively, so this is the setup
  ...
}

  // then when toggling pins use this idiom
  pinMode (pin, OUTPUT) ; // drive line low
  pinMode (pin, INPUT) ; // let pull-ups pull line HIGH
  // and read the bus lines state
  x = digitalRead (pin) ;

I have bought a couple of these logic level converters. I haven't tested them yet but, they are really small easy to setup.


I found this but I don't have 4 caps, nor do I have 4.7k-Ohm resistors, but I assume I don't need 4.7k exactly and two 10k's in parallel will work... and I also assume I don't need the caps in order for this to work right?

one problem I face in using the design from the schematic above is I don't know how to use it... meaning how to wire it up to my Arduino and the slave I2C device, and how to use the "Enable <= Vcc**-**" / "Enable <= Vcc"


This is another idea I have, I need some opinions on.

Also @ MarkT I'm going to use the wire library as I don't have enough experience to do any thing more complicated than understanding hexadecimal to decimal conversion using just my brain and nothing else (not even paper and pencil)

Normally I2C drivers don't pull up - the pull-up resistors do that, so I'm not sure you need anything that complex. Using diodes that way I'd use 1N4148's just because they are fast (and cheap/small).

MarkT:
Normally I2C drivers don't pull up - the pull-up resistors do that, so I'm not sure you need anything that complex. Using diodes that way I'd use 1N4148's just because they are fast (and cheap/small).

But would the diode setup work at all and still be safe? All I got are 20x 1N400_'s (from 1 to 7)

Also in the data sheet it said that the voltage drop was 0.8? am i missing sumthin?

I don't think that diode setup will work as is.

I2C is an open-drain bus so it needs pullup resistors, that circuit doesn't have any.

Also, the 3v3 signal is being reduced to ~2v5 by the single diode, IIRC that is right on the edge of a valid logic high and will probably be unreliable.

I think something similar to what you have may work but without redrawing I can't get my head around it.

EDIT: I had a play with ideas but couldn't find anything that works with just diodes and resistors.


Rob

Graynomad:
I don't think that diode setup will work as is.

I2C is an open-drain bus so it needs pullup resistors, that circuit doesn't have any.

Also, the 3v3 signal is being reduced to ~2v5 by the single diode, IIRC that is right on the edge of a valid logic high and will probably be unreliable.

I think something similar to what you have may work but without redrawing I can't get my head around it.


Rob

what if i cut the wire between the single diode and 5v pin. Then add a 2n3904 and connect the base to a 10k then the 10k get connected to the diode. Then connect the collector to 5v supply pin, and emitter to the other wire that i cut that is now unconnected/the anode closet to the 5v i2c pin... I would have the 5v needed and no longer 2v5

Graynomad:
I had a play with ideas but couldn't find anything that works with just diodes and resistors.


Rob

I'm pritty sure that's what most if not all of what you can think of is essentially made of

aside from caps that is

Don't know if you guys were paying attention, but cyclegadget found the solution.

I have bought a couple of these logic level converters. I haven't tested them yet but, they are really small easy to setup.

http://www.sparkfun.com/products/8745

If you look at the schematic to the device, it uses a simple voltage divider to take 5 down to 3.3, and almost precisely illustrates the same scheme for stepping up the voltage as I suggested, but uses a JFET instead of a BJT. $2, done.

If you look at the schematic to the device, it uses a simple voltage divider to take 5 down to 3.3, and almost precisely illustrates the same scheme for stepping up the voltage as I suggested, but uses a JFET instead of a BJT. $2, done.

Except for bi-directional I2C data and clock applications.

Lefty