Home | Tutorials | Sensor Interfacing

Sensor Interfacing
by Nate | June 04, 2007 | 23 comments Skill Level: Beginner


If you've ever tried to hook up a 3.3V sensor to a 5V micro, you know what I'm talking about - connecting these two can be a problem! There are several ways in which a 3.3V device can be safely connected to a 5v microcontroller. This tutorial will detail a few ways in which this can be accomplished.

Below is an example of how NOT to connect a 3.3V device (like the SCP1000-D01 pressure sensor with SPI interface) to a 5V microcontroller (like a PIC or AVR running at 5V). Although you may experience normal operating conditions, the lifespan of your 3.3V device will be dramatically shortened.

Directly connecting the devices together (see above) will overstress the 3.3V device and eventually lead to device failure.

In general, there are many ways to interface these two SPI components together. There are many ICs available on the market that are specifically designed to translate between logic levels. We've never used any of them! Historically they've been very difficult to source and there are a few methods below that make interfacing logic levels fairly simple.



Inline Resistor -

This is the easiest and most rudimentary way to connect your devices together. Below is a generalized diagram using the inline resistor method.

R7 and R8 : 10K resistors are placed between the MOSI (Master Output Slave Input) line as well as the SCK (clock) line. These resistors will decrease the amount of current flowing into the 3.3V device. The internal clamping diodes within the 3.3V device will attempt to clamp the incoming signal to 3.3V thus protecting the rest of the 3.3V device. Clamping diodes are normally found on the input lines of low voltage devices.

A clamping diode is a diode used to limit the peak voltage on a line to a pre-determined maximum voltage. The resistor reduces the amount of current flowing through the diode by several orders of magnitude. Limiting the current will reduce the chances of the clamping diode being permanently damage. Without the resistors in place, much higher current will flow through the diode. These levels could destroy the clamping diode and in turn, damage the device.

Caution is needed with this approach as it is not guaranteed that your 3.3V device will contain clamping diodes. Although most devices have clamping diodes, if your device does not, then this inline resistor method will not work to reduce the voltage input.

MISO : You should notice that there is no resistor on the output of the 3.3V device (MISO). You shouldn’t need any circuitry between these lines to connect with your 5V device.

Here at the DC characteristics of the ATmega8. We need to check to see what the minimum voltage is for a digital '1', and the maximum voltage for a digital '0'.

If our micro is powered by 5V, we see that the max for VIL is 0.2*5V = 1V. So anything less than 1V the ATmega8 will consider a logic '0'.

5V * 0.6 = 3V. So anything about 3V the ATmega8 will consider a logic '1'. What happens when you're in between these two voltages? It's a bit unknown. When in doubt, test to see if your micro can correctly interpret the incoming signals. As long as the 3.3V device can output a 3.0V signal (for logic '1') the ATmega8 should be able to listen without any other circuitry.

You should check the datasheet for your given 5V device to ensure the digital threshold voltages are within a range your 3.3V device can output.

R5 : A 1K resistor can be seen on the CS line - this is intentional! These two resistors form a voltage divider on the CS line going into the 3.3V Device. Three cases are possible:

  1. The 5V device is in reset and CS will be pulled high through R4

  2. The 5V devise asserts CS, current is limited through R5, and the 3.3V device should see 3.3-3.8V on the CS pin

  3. The 5V device sets the CS line to low then the 3.3V device will see 0.33V on the CS line. (See voltage divider).

Say for sake of argument that R5 was 10k. If we re-work the voltage divider formula, we find that the 3.3V device would see (10k/20k) * 3.3V = 1.65V when CS line is pulled low by the 5V device. 1.65V is not a 0 or a 1 according to the 3.3V device. It's right in the middle! The 3.3V device would be completely confused! This is why we use a 1k inline and a 10k pull up.



Diode -

This method is considered a 'safer' solution than the inline resistor. This method will work regardless of whether the 3.3V device has clamping diodes or not.

When the 5V device transmits a digital high the diode blocks any current flowing through to the 3.3V device. The 3.3V device sees no change and therefore will still be pulled up to 3.3V through the 10k resistor.

When the 5V device transmits a digital low the diode will be tied to ground. This will allow current to flow through the diode from the 3.3V line. The input line into the 3.3V device will see the forward voltage drop across the diode - instead of a solid 0V on the MOSI pin, the 3.3V device would have 0.6V applied to MOSI pin. 0.6V is low enough to be considered a digital '0' on many devices.

Standard silicon diodes have a forward voltage drop of around 0.6V. The lower the forward voltage drop the better for this application therefore you may want to consider using a Schottky diode. These diodes have forward voltage drops of around 0.2V.



MOSFET -

This is a more complex solution but it will allow you to interface a lower voltage signal pin to a high voltage signal pin. If 3V is too low of a voltage to register as a digital '1' into the 5V device, this MOSFET configuration will help.

In this schematic, the 3.3V device is transmitting into the 5V device. When the 3.3V device transmits a '1' (3V), the MOSFET is tied high, and the TX-5V pin sees 5V through the R3 pull-up resistor. When the 3.3V device transmits a '0' (0V), the MOSFET is grounded and the TX-5V pin sees 0V. This circuit is a great way to interface a low voltage to a high voltage. Just be sure that the lower voltage device is on the left side of the MOSFET. This circuit will not work the other direction (high voltage to low voltage) because of the internal diode within the MOSFET will forward bias.

Here are some links to additional documents that show how this MOSFET circuit can be used to interface different voltage devices on an I2C bus:


I would first recommend trying to get all your devices onto the same power bus. If you've got a 3.3V sensor, can you get your micro to run at 3.3V as well? If not, for prototyping purposes, a resistor inline or a diode should be all you need!

June 4th, 2007

Comments 23 comments

  • Thanks for writing this. Are these precautions necessary if you are just reading from a sensor and not writing anything to it?
    i.e I have the analogue output of a 3.3V maxbotix proximity sensor (thanks sparkfun!) connected directly to a PIC analog input. Is this a bad idea? The only other thing connected to the sensor is power.

    • I don’t think so. As long as you are using the 3.3V pin to power it, you’ll be fine.

  • Thanks for this great article.

  • What is the best way to interface a I2C device with a 5V device? I don’t think the device is 5V tolerant.

    • What about optical isolation? I’d try an 4N25 if the device isn’t 5V tolerant. The only problem is that the 4N25 needs something like 50mA to work and maybe you’d need a transistor before to get that much current. Anyway, I don’t know if it will work for I2C, I made it work with serial communication.

    • I just pull both lines to 3.3V and that’s it. As in I2C floating is 1 and pulling it low is 0. PICs are happy working with 3.3v logic.
      I know it’s been more than a year…

      • When interfacing 3.3 to 5 I always use a voltage divider on lines going form high (5) to low (3.3) voltage and a series resistor on the opposite direction when I cannot guarantee high impedance (eg. on some MCUs after reset). It’s cheap and as far as I know safe.

  • Hi,
    You are saying:
    This circuit will not work the other direction (high voltage to low voltage) because of the internal diode within the MOSFET will forward bias.
    But the AppNote you are pointing too explain in chapter 2.3.1 that the circuitry can be used as a bidirectional shifter… They are saying that a level 0 on the TX-5V side will forward conduct the internal diode, and this will start to raise Vgs to the point it will start to conduct and drive the TX-3.3V node to 0V.
    Could you comment?
    Thanks

  • Is there any reason for not simply using a 3.3V Zener diode? I’m interfacing a XBee to an AVR, and I simply put a 3.3V Zener diode on all the signal lines between the two, I can’t think of any reasons why this wouldn’t be enough, but please correct me if I’m wrong.

  • Hi there! I’d go with the MOSFET. In a recent project I used a BJT in a similar configuration and worked perfectly fine.

  • You can also use any logic chip from the 74HC series, such as the 74HC244 octal buffer. Just power the chip with 3.3v and use a 1K resistor on each of its inputs. It is not bidirectional, but usually connecting a 3.3v output to a 5v input is not a problem anyway.

  • Regarding using a 74HC125 for 5->3.3V transition: do you really need any serial resisters on the 125’s inputs?

  • Regarding the second schematic “Inline Resistor”:

    1. The 5V devise asserts CS, current is limited through R5, and the
      3.3V device should see 3.3-3.8V on the CS pin
    2. The 5V device sets the CS line to low then the 3.3V device will see 0.33V on the CS line. (See voltage divider).
      To #2: Don’t we also have a voltage divider?
      3.3v —— 10K (R4) —— CS-Pin —— 1K (R5) —— 5V (powered on by 5V Device)
      Voltage difference between 3.3 and 5.0 of 1.7 Volt:
      Voltage over both contacts of the 10K resistor is
      1.7V10K/(10K+1K) = 1.55
      1K resistor:
      1.7V
      1K/(10K+1K) = 0.15
      Now stack this additional Voltage at the 10K resistor (1.55V) on top of the 3.3V:
      3.3V + 1.55V = 4.85V
      This 4.85V are at “3.3V Device” CS input in my opinion.
      To #3:
      3.3v —— 10K —— 1K —— 0V
      Voltage over both contacts of the 1K resistor is
      3.3V*1K/(10K+1K) = 0.30V
      So at the “3.3V Device” CS input in my opinion lie 3.0V instead of 3.3
      I could be terribly wrong with all that, please let me know.
  • So at the “3.3V Device” CS input in my
    opinion lie 3.0V instead of 3.3
    Sorry! I meant:
    So at the “3.3V Device” CS input in my opinion lie 0.30V instead of 0.33V.

  • @Ad
    I don’t see any problem with your setup at all.
    But i would like to point out that if you use a SPI connection, you are always “writing” something to the sensor(the clock line of course) so the precautions are needed.

  • I used the inline resistor method and I’ve found that at least with one sensor (ADNS3080) and using an Arduino ATMeg1280, that the 10k resistors on the SCK and MOSI pins were too large. This sensor I was using apparently had internal pull-up resistors (also of 10k) and it meant that the arduino was unable to properly control the voltage. To fix the problem I had to use 1K resistors on SCK and MOSI pins and then it all worked great!

  • Could the OP please fix the image file permissions on this tutorial? I am getting 403’s for all the image links.

  • Hello!
    One question and it’s kind of urgent.
    The diode should be inserted also on SCK and CS line or only in MOSI line?
    Thanks! ;)

    • You should put diodes + pull ups on all High to Low lines. (High to Low lines are all lines in which the 5V part sends a signal to the 3V3 part) In your case, yes, SCK, CS, and MOSI should have diodes + pull ups.

  • There’s no protection on the MISO pin of the 3.3V device, unnecessary when only 3.3V slave devices are used. However, when mixing 3.3V SPI slave devices with 5V slave devices there will be 5V signals on MISO. What is the best way to protect the 3.3V devices in this case?

    • I’m now using a 74LVC244 to translate the MOSI, SCK and CS signals to 3.3V levels. The 75LVC244 is powered from 3.3V with the output enable pins permanently grounded. I chose this device because the data sheet states its inputs allow 5V logic levels when powered from 3.3V, and it is also available in a DIP package.
      For each 3.3V SPI slave I’m using one gate from a 74HCT125 quad buffer to protect MISO from 5V SPI slaves. The buffer’s output enable pin is connected to the slave’s (active-low) CS input. The 74HCT125 is powered from 5V.
      This set up properly protects both inputs and outputs of 3.3V devices. It still works if the 5V logic levels are replaced by 3.3V ones, allowing custom Arduino shields to be used on both 5V and 3.3V Arduinos.

  • Good article, it worked on my sensor interface. I have done something similar to this with AC line. I used 3 high valued resistors to reduce current and then clamp the voltage to logic levels via internal clamp diodes. With three resistors, one capacitor, and a microcontroller I made a basic touch interface.