## How to sense a 5v input with GPIO

11 posts
Hi there

Only a fast question. I would like to sense a 5v input with my pi using the GPIO. I know that I need to limit the current and drop down the volts to 3.3v. And my question is:

Is enought with a simple resistive divisor like this one (see test1.png)

Or I need to put some additional resistor-zener to protect GPIO (see test2.png)

Any tip would be will be welcome,

many thanks
Attachments
circuit
test1.png (2.84 KiB) Viewed 5471 times
test2.png (2.91 KiB) Viewed 5471 times
Posts: 2
Joined: Tue Nov 13, 2012 10:32 pm
Yes, this would work fine, and R3 isn't needed!

I myself, would use 2K2 and 3K3 resistors for an exact 2:3 ratio, for a three-fifth attenuation, that is a conversion from 5.0 to 3.0 volt, but that is simply a question of taste.

This attenuation would be even suitable for high speed signals (like a high UART baudrate) as the input capacitance of a GPIO is very low.

In fact all, that is needed to safely connect a 5V signal into a (3V3) GPIO is some kind of current limiter to avoid putting massive amounts of current through the GPIO's inherent diode to 3V3 to the 3,3V power supply. Just putting an 1K resistor in series would also do that!

Moderator
Posts: 4349
Joined: Sun Mar 11, 2012 12:19 am
So any 5v signal to the GPIO's need just a 1k resistor...is level shifting overkill(like in attached pic)?
Attachments
overkill?
pilvshifter.jpeg (8.22 KiB) Viewed 5458 times
Posts: 55
Joined: Sat Aug 04, 2012 5:19 am
Many thanks for the answers,

Its only a unidirectional input signal. A simple movement sensor.

5v --> movement detected
0V --> No movement detected

I think I will keep the first circuit, that I hope is safe enough

Thanks for the answers again
Posts: 2
Joined: Tue Nov 13, 2012 10:32 pm
Pijus_magnificus wrote:I think I will keep the first circuit, that I hope is safe enough

Thanks for the answers again

As a general rule, a voltage divider such as you have drawn appears as a source of voltage V0 in series with a resistance R0 such that:
V0=V*R1/(R1+R2)
and
R0=(R1*R2)/(R1+R2)

So in your case V0=~3v and R0=~6kΩ
That means you're safe

Posts: 2278
Joined: Thu Sep 29, 2011 4:34 pm
Location: Berkshire UK
Metatronin wrote:So any 5v signal to the GPIO's need just a 1k resistor...is level shifting overkill(like in attached pic)?

Yes level shifting is generally overkill!
Also the left picture doesn't accomplish any level shifting, as its output to the Arduino is still 3V3 (actually its even a little bit less, as the base diode drop of the transistor is subtracted, so output will be 3.3- ca 0.5 = 2.8 Volt).
Generally no level shifting from 3V3 to most 5V devices is necessary, as the minimum voltage that is acceptable as high is often just 2.0 Volt.

adding an 1K series resistor before the GPIO isn't technically level shifting, it just prevents large currents entering the 3V3 supply through the GPIO's protection diodes. In that sense it prevents damaging the PI, but a much better solution would be a simple resistor divider, with a 2K2, and a 3K3 resistor.

Moderator
Posts: 4349
Joined: Sun Mar 11, 2012 12:19 am
Thanks, very helpful info. Is there anytime level shifting would be preferred over the resistor divider?
Posts: 55
Joined: Sat Aug 04, 2012 5:19 am
There might be some situations where you want the GPIO to act as a bidirectional port, but actually the voltage divider as described would work in that situation too.
In "receiver mode" the voltage would be divided as described, and in transmitter mode the PI would simply push 3V3 on top of the bottom resistor of the resistor divider, and if the load after the "top resistor" isn't too great the paired device would still see 3V3.

The trouble begins when you have a bidirectional bust with many slave devices, some of which attempting to put 5V levels on the bus, and others 3V3 levels, the 3V3 levels would also be divided to a level below the "minimum high" that the PI will accept.

But as you can see this is quite an "exotic situation", but can happen sometimes, some people who use multiple I2C devices connected to the PI want "high" levels appropriate to each slave device, and there a simple level converter, consisting of two FETs, and four pullups (to different VCC levels) are used.

see http://ics.nxp.com/support/documents/interface/pdf/an97055.pdf

Moderator
Posts: 4349
Joined: Sun Mar 11, 2012 12:19 am
The circuit posted by Metatronin is no level shifter, as the transistor works as emitter follower (common collector). If input from PI is 3.3V, output will never exceed 2.8V. The transistor needs to work in common emitter mode to get a 5V output. In this case the signal is inverted, so you may need two transistors.
Posts: 1
Joined: Wed Jan 30, 2013 4:11 pm
Hi all,

I have a question in line with this one. I want to use a 5V PIR sensor on a GPIO pin... so the output of the PIR is a 5V pulse.

I tried connecting a 10k resistor in line with the output and connect this to the GPIO. This works, but I feel it is not the safest way to deliver this input to the Raspberry.
From this topic I tried applying a 2k2 and 3k3 voltage divider, but now the Raspberry does not see the input.
Thinking the output might be too low I also tried a 10k and 20k voltage divider, but no luck either.

Any thought how I can safely use the 5v input?
Thanks!

edit: this is the sensor circuit I'm talking about, maybe it helps to understand how to connect it: http://www.produktinfo.conrad.com/daten ... 12V_FG.pdf
Posts: 1
Joined: Mon Mar 04, 2013 2:08 pm
so if i have a 16x2 lcd being driven from the 5v output gpio pin, i can't have a switch feed that same 5v as an input back into a gpio pin (with 10k pull down resistor, 1k series protection)?

ok, i've modified my circuit to this now, so instead of the 10k pull down i've got a 330/470 ohm divider, does this look right - it does seem to detect high when the button is pressed and its not blown up yet!? the +volts comes via the push-switch

hd44780-divider_bb.png (39.72 KiB) Viewed 4209 times

Code: Select all
`#!/usr/bin/env pythonfrom time import sleepimport RPi.GPIO as GPIOGPIO.setmode(GPIO.BOARD)GPIO.setup(7, GPIO.IN)while 1:    print GPIO.input(7)    if GPIO.input(7):        print "BUTTON PRESSED"    sleep(0.2)`
Posts: 230
Joined: Tue Jan 22, 2013 6:43 pm