# Computing stuff tied to the physical world

## Level translation

What if your circuits have to run from different supply voltages? Sometimes, you have no choice – a µC running at 5V may need to be interfaced to a 3.3V sensor, or vice versa.

First of all, this is not the same as dealing with voltage differences in power sources: in this case, it’s about the signals running between the different chips being incompatible. There is hardly any current involved, but all voltages do still need to be in their allowed ranges.

There are many different cases – here are a few examples:

• 3.3V signal out to 5V signal in: this is the simplest of all, since such connections will usually work just fine without having to adjust anything. A 3.3V level is seen as a “1”.
• 5V signal out to 3.3V signal in: if the receiver is “5V tolerant”, as on most ARM µC’s, then again a straight wire is all that’s needed – the 5V won’t damage the input pin.

The only tricky case for these voltage levels is 5V out to a non-5V-tolerant 3.3V input pin. There are a number of simple solutions for this specific problem:

• Insert a resistor (4.7..22 kΩ will do) and let the excess voltage off through the built-in protection diodes on most input pins. This will cause up to 0.5 mA current, which most protection diodes can handle without any trouble (check the datasheet!).
• Use a voltage divider of say 10+10 kΩ to drop the 5V to a more usable 2.5V.

These solutions tend to work just fine in all but high-speed signalling situations. The reason is that these resistors add time delays due to stray capacitance, which is always present. The higher the signalling speed, the more a purely resistive solution is likely to cause problems – above 1 MHz or so, e.g. a fast SPI bus, other solutions may be needed.

## Level shifting

Fast signalling, or voltage conversions beyond 3.3V <=> 5V can be done with special-purpose “level conversion” chips, but often a single transistor will also do the trick:

(the above image was found on www.siongboon.com)

It’s a very simple circuit, which can be used to convert just about any level (over 1V) to any other signal level (up to at least 30V), but it has one key property which must be taken into account: this is an inverting circuit: a high input produces a low output, and vice versa!

The other point to note, is that this is not an ultra low-power solution: when the input is high, a certain amount of current will be wasted in this circuit (≈ 1 mA for this example).

Note that level conversion is a special case of switching, closely related to circuits which amplify the signal to switch higher currents. Replacing the 10 kΩ resistor by a 12V relay (plus protection diode) would turn this level shifter into a relay driver, for example.

## I2C

The I2C bus is worth some extra attention, since it has in fact a certain amount of level shifting built-in. Here is an example of a bus with 2 I2C devices attached to it:

(image taken from the lammertbies.nl site)

Each I2C output is an “open collector” configuration (or rather “open drain” in this case), which means the circuit can only pull the signal line down. The pull-up is created by a resistor tied to the high voltage.

The trick here is that I2C signal levels are not set by any device, since they can only force a pin low, i.e. close to 0V. The high value is completely determined by the “+VDD” level in the image above, and can be either 3.3V or 5V. As long as both devices tolerate 5V on the input side of their I2C logic, chips can be mixed and matched as needed. No voltage issues!

## Bidirectional conversion

Level converters for signals going from A to B are one case – but what do you do when the signal is actually a bus and can have signals going either way?

Here is a widely-used trick which uses a MOSFET to create a bidirectional level shifter:

The point here is that inputs and output can be on either side of the MOSFET. When the 3.3V side is pulled low, so will the 5V side be, but if it is used as input and the 5V side is pulled low, then the 3.3V side will follow (and similarly for high values). For details about this elegant but surprisingly sophisticated trick, see the App Note 10441 (PDF) from NXP.

[Back to article index]