Electronic – Connecting 3v digital output to Arduino using bi-directional level shifting (mosfet)


I have a digital output from a 3.3v device that I would like to make 5v tolerant – i.e be able to connect it to either a 3.3v OR 5v MCU.

I could technically connect the output directly to the Arduino Uno (or a 3.3v MCU) without any problems. The problem with the output is that the VOH minimum is 3v, while the VIH for the Arduino Uno is 3v – so there is no margin for error.

So I will need to shift this output up to 5v (if so required). I have considered 3 options:

1) a part like this – MC74VHC1GT125 – would do the trick.
2) Use an optocoupler – like the HCPL-181
3) Use a bi-directional level shifter using a MOSFET and 2 resistors – like in this Philips AN97055 note

  1. Takes a wide variety of input voltages (3v in our case), and translates it to the Vcc reference voltage (which may be 3.3v or 5v depending on our MCU of choice)

  2. The output from the optocoupler can be tied to the Vcc reference voltage, so it will work with either 3.3v or 5v MCU

  3. The output side of this (connected to the MCU input) can be pulled up to the Vcc reference voltage, and so is again tolerant of 3.3v or 5v MCU and will pull up to the appropriate level

3 looks very attractive as I am already using a couple of MOSFETs (BSS138) in my design (for the I2C lines), for simplifying the BOM.

However, I see that it seems to be mainly used for open drain/collector configurations like I2C pins – a digital output pin is not an open drain/collector type.

My question is – can the bi-directional level shifter shown in the Philips note above be used in the uni-directional case of a digital output pin with no ill-effects?

If so, what does say, the MC74VHC1GT125 or another specifically designed level shifter IC, offer in terms of advantages over this approach? And how does the optocoupler approach compare?

I have scoured the internet quite a bit, but am left deeply yearning for more clarity and understanding!


Best Answer

The bidirectional MOSFET level shifter automatically detects when one side is pulled down, and then pulls the other side down. So it will still work if only one side is ever pulled down.

The pull-up resistors are needed to get a defined high level when no device is pulling the line down. When you have a push/pull output, you do not need the resistor on that side.

A pull-up resistor combines with any parasitic capacitances in the circuit to form an RC low-pass filter, i.e., the rising edge of the output signal is slowed down. This is typically not yet a problem at the 100 kHz of I²C, but might become one at higher frequencies.

The MC74VHC1GT125, or actual level shifters like the SN74LVC1T45, have push/pull outputs, so they can reach higher frequencies.

An optocoupler is used if you need galvanic isolation. When you connect the grounds of the two devices together, it is not needed (but would still work).