5

Edit for searches: This question is about using a 5v relay with Raspberry Pi GPIO pins that outputs 3.3v.

There are a number of great questions below, read them through to understand whats going on.

If you just need a tldr on what worked for me, these are what I find to work with mine:

  • a 3.3v relay, like the SRD-03VDC-SL-C as suggested by an answer below
  • a 5v solid-state-relay can work, provided the signal can work with 3.3v, e.g. high-state signal starts at 2.5v, such as this. I also find that the relay that comes with an optocoupler could work as well, provided that it has separate pins for the optocoupler vcc and coil vcc, and the optocoupler can be activated with 3.3v, such as this.

I'm trying to control a 5v relay with the GPIO pins.

The wiring are setup this way:

  • Relay's VCC connected to physical pin #4 (5v)
  • Relay's GND connected to physical pin #6 (GND)
  • Relay's Input / signal connected to physical pin #8 (GPIO 14)

For some reason, I found that the relay is activated when the pin is set to output mode, regardless if it is set to high or low, and it can be deactivated by setting it to input mode. Essentially making my "blink" code looks like this:

GPIO.setmode(GPIO.BCM)
while True:
  GPIO.setup(14, GPIO.OUT)
  time.sleep(1)
  GPIO.setup(14, GPIO.IN)

While this code that I used to blink LEDs does nothing (the relay is left in the "on" mode)

GPIO.setmode(GPIO.BCM)
GPIO.setup(14, GPIO.OUT)
while True:
  GPIO.output(14, GPIO.HIGH)
  time.sleep(1)
  GPIO.output(14, GPIO.LOW)

My questions are:

  • Why is this the case?
  • Is it because the "low" state of the output pin still puts out non-zero voltage that is high enough to activate the relay? Do I have to put some resistor in between?
  • Is this the expected behaviour?

Edit: So I've been doing some additional testing, and it appears that the relay also gets triggered when I connect the relay's input pin to one of the RPi's GND pin. From what I understand from reading this thread, I believe this means the relay has a low-level-trigger?

I'm still not sure how this explains the behaviour above though? Why is setting the GPIO pin to output mode makes it gives out the same behaviour as a GND pin?

hndr
  • 153
  • 1
  • 6
  • What kind of relay are using? Which model and do you have the datasheet? ... Most general purpose relays have a coil connection, which would seem to be your VCC and GND ... and then three "output" terminals labeled Normally Open (NO), Normally Closed (NC), and Common (C) ... if you are connecting 5V directly across the coil, then the relay is always active and the RPi is not controlling it. – RubberStamp Nov 18 '17 at 14:07
  • @RubberStamp I don't have the datasheet, its a relay board I got from a local shop. It looks like this: https://www.ebay.com/itm/Relay-5V-Channel-NEW-Expansion-Low-Level-Trigger-Module-Relay-For-Arduino-Board-/262500451836.

    It has 3 "outputs" that you mentioned, and 3 "inputs", the GND, the 5V power to drive the coil, and an input signal to trigger the coil.

    – hndr Nov 18 '17 at 14:13
  • and fwiw, I am able to control the relay even with the 5V constantly connected to relay power, just that I'm doing that by toggling between Input/Output mode instead of High/Low output that I would expect. I just would like to understand why. – hndr Nov 18 '17 at 14:19
  • what language and GPIO interface library are you using? – Richard Chambers Nov 18 '17 at 14:30
  • @RichardChambers Python / RPi.GPIO – hndr Nov 18 '17 at 14:34
  • 1
    Here is information, reverse engineered so not canonical, about the Raspberry Pi GPIO interface that may be helpful, GPIO Electrical Specifications and this article has links to other references, Raspberry Pi – Driving a Relay using GPIO. – Richard Chambers Nov 18 '17 at 14:41
  • So.. I have been doing some testing again.. and it appears the relay also gets triggered when I connect the relay's input pin to the RPi's ground pin. – hndr Nov 18 '17 at 15:28
  • My relay board is on when GPIO is low, off when GPIO is high : https://raspberrypi.stackexchange.com/questions/73552/cant-set-gpio-to-low-trying-to-control-single-channel-relay-raspberry-pi-b/73568#73568 – CoderMike Nov 18 '17 at 15:43
  • @CoderMike Indeed I'm having the exact same issue as the thread that you linked. I'm still not sure whats going on here though. My relay board is ON when GPIO is set to OUTPUT mode, off when set to INPUT mode. – hndr Nov 18 '17 at 15:49
  • Also as mentioned in my edit, the relay is also on when I connect the relay's input pin directly to the GND pin on the Pi.

    I suspect I might have a case of bad grounding here.. but I'm not sure how to check..

    – hndr Nov 18 '17 at 15:51
  • Without a definitive description of the relay module, this question is unanswerable, although a great source of speculation. There DO exist shoddy relay boards with PNP transistors (suggested by one answer), presumably designed by someone with no Electrical Engineering experience. Connecting one of these to the Pi risks destroying the Pi. – Milliways Nov 19 '17 at 00:10
  • In fairness to those who designed the relay board, it's clearly marked and sold as a 5V device (e.g. for Arduino). It's only the misapplication to a 3.3V device (e.g. the Pi) that causes a problem. – Edward Nov 19 '17 at 16:30
  • @Edward is correct. Even though I'm aware that 5V is needed to power the coil, I made the incorrect assumption that 3.3V would be enough to trigger the high state. I'll be updating the question with some of my learnings in a few days for future searches as I found there are similar questions on the RPi.SE where voltage requirement didn't come into the discussion. – hndr Nov 20 '17 at 01:22
  • Even though the device may be marked 5V, it is still POOR design; it MAY be OK if it was CLEARLY marked that the relay board and driving circuit SHARE A COMMON 5V RAIL. – Milliways Nov 20 '17 at 02:22

4 Answers4

5

The problem

The problem is that your relay board is designed to run at 5V, but your Pi's GPIO is 3.3V. The relay is a 5V relay, so the power supply needs to be 5V, but you can alter the design of the driver board slightly to make it work at 3.3V input. Looking at this image, we can clearly see the transistor is marked 2TY which means it's an S8550 PNP transistor, and the resistors are all marked "102" which means they're 1K ohm resistors. Also, although I don't read Chinese, Google translate helpfully tells me that 开关 near the green LED means "switch" and 电源 near the red LED means "power supply" so we can infer that the red LED will be on whenever this board is powered, and the green LED will probably toggle with the state of the input pin.

5V relay board

From that, it's pretty simple to draw a schematic:

schematic

simulate this circuit – Schematic created using CircuitLab

Note that without R4 (which is what you have), we get a voltage output like this: enter image description here

As you can see, nothing happens until the input voltage rises above 4.1V which is higher than your Pi can manage. The PNP transistor is only forward biased (conducting) when the base voltage is around 0.7V lower than the emitter voltage, or about 4.3V. The Pi's GPIO is only 3.3V.

A bad solution (do NOT do this!)

If you add the 470 ohm resistor R4, and you'll get a voltage plot like this instead: enter image description here

Now the relay's state changes when the output voltage rises above about 2.6V. Problem solved? No! I'm embarrassed to say that was the "solution" I had originally posted, because I was only thinking about properly biasing the PNP transistor, but as @Milliways correctly pointed out, this will likely be fatal to the Pi. Let's analyze why and come up with a real solution.

Pi GPIO

The GPIO pins on the Pi, like most processors, can be thought of as a pair of FETs and a pair of diodes something like this:

schematic

simulate this circuit

The complementary FETs M1 and M2 provide the 0 or 3.3V output and protection diodes D1 and D2 protect against brief excursions on the pin of less than 0V or greater than 3.3V. However, these protection diodes are not terribly robust and are not intended to remain on (forward biased) and conducting for any length of time (think milliseconds). If they are forward biased for a longer period, with a current of, say 1mA or more, the device will overheat and be destroyed, rendering your Pi partially non-functional at best, or completely dead at worst.

If we look at the relay circuit above we see that from +5V through resistor R4 (470 ohms) and R1 (1k ohm) goes straight into the pin. Because 5V > 3.3V the protection diode will be forward biased and will be conducting and heating the part. The current would be about (5 - 3.3)/(470 + 1000) = 1.2mA which is higher than would be safe. The other suggestion originally posted was replace R1 with a 2.2K part and apply R4 with 680 ohms. That would result in (5 - 3.3)/(680 + 2200) = 0.6mA which might be low enough to be safe, but it's not the best possible design.

A real solution

There are a number of safer alternatives. The simplest would be to simply replace the relay, which is an SRD-05VDC-SL-C with a drop-in replacement SRD-03VDC-SL-C (see http://www.mouser.com/ds/2/321/27115-Single-Relay-Board-Datasheet-709206.pdf for datasheet). Then use 3.3V supply as Vcc for the relay board.

Another is to use a different transistor. Recall that using a PNP transistor means that to turn the transistor on, we need to have a VBE (voltage from base to emitter) of around -0.7V. With an NPN transistor, it's the same but with the polarity reversed, so around +0.7V. This brings the voltage well within the 3.3V range of the Pi and could be done like this:

schematic

simulate this circuit

About current

With this circuit, GPIO pin current will be about 2mA. If I'm not mistaken, the GPIO pins are set by default to source 2mA, so no change is required using the latter circuit. The Pi's GPIO pins can source up to 16mA, but they should not be asked to source more current than they're programmed for to avoid damage.

Also, the entire relay circuit will draw about 80mA from the 5V power supply. The onboard 5V supply should be more than adequate for this.

Acknowledgement

First, apologies for my original answer which was not good. Second, thanks to @Milliways for pointing that out. I'm hoping that by showing both the bad solution, analyzing it, and showing real solutions, that others may learn from my error.

Edward
  • 961
  • 1
  • 6
  • 24
  • It's a great analysis... it might be a good idea, for completeness, to give the reason why the 470 ohm resistor is needed and what it's doing as a voltage divider. Of course, it only works if the pictured relay board is the same as the OP's board. It may be something different. – RubberStamp Nov 18 '17 at 18:47
  • Describing the theory and operation of transistor biasing for use as a switch (which is what this is doing) would require a much longer answer that might be more suited to another site. See http://www.electronics-tutorials.ws/transistor/tran_4.html for a start. As for working only if it's the same as the board pictured, that's somewhat true, but a cursory look at various results when searching for "5V relay module" seems to indicate that 99% of them use a nearly identical design. The only other common variant I've seen uses optocouplers which would generally work with either 5V or 3.3V in. – Edward Nov 18 '17 at 20:36
  • Noted. I have ordered a level shifter and a SSR that works with 3.3V to experiment with.

    @Miliways to clarify on your edit, you're referring to the solution posted here?

    – hndr Nov 19 '17 at 07:00
2

I'm still not sure how this explains the behaviour above though?

Because the Pi GPIOs only output 3.3V, and presumably this is not enough to trigger high on the 5V relay control circuit.

The that reason that using it set to input works is the relay input is probably pulled high so that it's default state is off. An input GPIO is in a high impedance state (aka high-Z), which is different from an output driven high or driven low; hence the GPIOs really operate in terms of three state logic. The high-Z state is much the same as a piece of wire that is not connected to anything, including ground. It has very high impedance and will take on the voltage of anything with less impedance attached to it -- meaning it is probably not a good idea for you to do this, since you are effectively driving the Pi input high with 5V, over the 3.3V tolerance of the pin.

You can double check the state of the input to confirm this (if you want to keep gambling...).

Milliways
  • 59,890
  • 31
  • 101
  • 209
goldilocks
  • 58,859
  • 17
  • 112
  • 227
  • I think this is the most likely explanation. Basically, if I understand this, whether the pin outputs HIGH or LOW (0V or 3.3V), neither are high enough to trigger the relay, hence it stays in the LOW state, and activates the coil?

    I'll have to dig up my arduino to verify this, but I think this is the right answer.

    – hndr Nov 18 '17 at 16:20
  • BTW, if this is the case, how do you suggest I proceed? Do I need a boost converter / level shifter? Or am I better of finding another relay that works with 3.3v? – hndr Nov 18 '17 at 16:21
  • It's cheaper to get a pack of level shifters (unless you want to try Edward's suggestion). – goldilocks Nov 18 '17 at 18:35
1

Does your relay board have the circled component on it?

Relay board with transistor coil control

If so, then you'll need to find the datasheet for the board. The transistor can be setup to activate the coil on a low input... i.e. Ground the input terminal. Or it can be setup to activate the coil on a high input... i.e. 5V applied to the input. If you can't find more information online about that particular board, try asking your local shop for more information. Most electronics shop people will talk your ears off if you ask a question or two... I know, because I was one once.


If you are looking at the guide linked to by @RichardChambers then the relay board has the transistor and the diode (the orange component with the clear packaging) listed in the relay control circuit. However, it's important to note that the transistor could be setup to follow reverse logic. The type of transistor will determine how the input functions. An NPN BJT configured as in the above guide, will follow normal logic. However, some other transistor might be used to change the input voltage sensitivity or perhaps the logic applied.

RubberStamp
  • 1,399
  • 1
  • 10
  • 16
  • It does have that circled component. I'll see what I can find on the datasheet or if I can contact the shop when its open again next Monday.

    Would this explain the behaviour I described though (INPUT/OUTPUT instead of HIGH?LOW)?

    – hndr Nov 18 '17 at 14:43
  • @hndr: Yes. The transistor is probably causing the unexpected behavior. It's best to find the datasheet, but if you can't find it, you could try both logic levels and see which works. – RubberStamp Nov 18 '17 at 14:47
1

I believe your relay board works like mine so the relay is on when the output is low, the relay is off when the output is high.

Change your code accordingly:

GPIO.setmode(GPIO.BCM)
GPIO.setup(14, GPIO.OUT)
while True:

  # relay on
  GPIO.output(14, GPIO.LOW)
  time.sleep(1)

  # relay off
  GPIO.output(14, GPIO.HIGH)
  time.sleep(1)

Similar post: can't set gpio to low, trying to control single channel relay (raspberry pi b+)

For reference the spec on my relay module states:

IN1 - Controls relay 1, active Low! Relay will turn on when this input goes below about 2.0V

http://modtronix.com/mod-rly2-5v.html

CoderMike
  • 6,982
  • 1
  • 10
  • 15
  • This is exactly the same as the second example in the question, which the OP has said explicitly "does nothing (the relay is left in the "on" mode)". – goldilocks Nov 18 '17 at 16:12
  • Unfortunately, as mentioned previously, this is the first thing I tried, and it doesn't work. – hndr Nov 18 '17 at 16:14
  • 1
    This is not the same as the second example in the question - if there was a 2nd sleep statement it would be closer with the LOW and HIGH on different lines of code. The second example immediately goes from LOW to HIGH with no sleep when it loops. – CoderMike Nov 18 '17 at 16:22
  • My bad, I forgot the second sleep statement. Wouldn't have changed a thing though, it is still performing the same operation. I knew that its not that I missed the toggle because its too fast because I tested the individual operation one by one without a loop. – hndr Nov 18 '17 at 16:31
  • Have you tried this with the 2nd sleep ? – CoderMike Nov 18 '17 at 16:45