Switch relay by connecting pin to ground

Hi Guys,

I have a 120/240V relay which is powered by 5V, it has 3 PINs (GND, IN1, VCC)

Now the basics are simple, connect VCC to VIN, GND to GND…

With IN1 I would expect to set the pin to HIGH(5v) or LOW (0v) to switch it, however IN1 actually outputs 5V and needs to be connected to GND to switch

I have managed to make the relay work by using an optocoupler to connect the IN1 to GND, however I was wondering if there is a more efficient way to complete the task

Any ideas? :smile:

Do you have a reference for the relay that you are using? If you are buying some off the shelve solution, there might be some additional circuit on board and knowing that would help :wink:

Unfortunately there is no references except some pictures :frowning: hopefully this will help? It has two LEDs, one to indicate the relay is powered, the other to indicate its switched.

So it seems like they are using a transistor to on/off the relay coil. That’s good.

I would simply connect the IN1 directly to a digital pin and control accordingly. Don’t think IN1 actually OUTPUTS a voltage like you mentioned since it is probably connected to the base of the transistor.

I used a multimeter to check, when I connect IN1 to GND, it is reporting 4.3V, if I connect it to the 5V line it does nothing

Sounds like they have a pull-up resistor there for it to be high by default. Place maybe 1k resistor from the digital pin to IN1 and test it out :smiley:

I think what @kennethlimcp actually meant with

is, that IN1 will not really output any considerable amount of electric power (voltage x current).
The reading your Volt meter gives you is only half of the truth. More interesting would be if there is actually any current sourced via IN1.
If the max. current sourced is less than 20mA (which I’d expect to be faaaar less then that) you’d be safe to directly connect it to any 5V tolerant pin on the Core.

As a background info and test for your DMM reading, attach a very high impedance (e.g >1M Ohm resistor) to Vin and measure between the other side and GND. Your reading should be near 5V again, but the current would by no means be worth mentioning - I’d guess your DMM wouldn’t even give you a reading.
And the 0.7V difference between 5V and your reading would well fit to Kenneth’s suggestion that this voltage comes across the transistors EB diode (unless your Vcc already is reduced via the Cores protective diode, but this should only have 0.2 to 0.3V forward drop)

If outputting HIGH (3.3V) on one of the 5V tolerant Digital Outputs (all besides D2), if the relay still turns on… then you are getting current flow from the 5V of the relay board and the 3.3V of the digital output.

You can try this scheme then:

// relay on
void relayOn() {
  pinMode(D6, OUTPUT);
  digitalWrite(D6, LOW);

// relay off
void relayOff() {
  pinMode(D6, INPUT);

Ok so some results, using a 1K ohm resistor didn’t help unfortunately, however @BDub idea worked, when switches to input it works, I assume because it is drawing current?

When I put the DMM onto the IN1 and GND it picked up 4.3mA, using a 1M ohm nothing showed up

Would using BDub’s code be the most elegant way to deal with this, or was I stuffing up the resistors?

PS. I was testing this on my $3 Arduino Mini clone which is 5V, just incase I burned something out

Just skimmed this so apologies if I’ve missed anything, but it sounds like IN1 is just a straight forward input with pull-up?

Have you tried simply attaching it to a 5v tolerant pin (via the resistor), setting pin mode to output, and outputting HIGH for on, and LOW for off? I don’t think you should need to change the pin mode from output. Setting the output low should be equivalent to pulling it to ground, which you say works. The only issue would be the amount of current that can be safely sunk by the Spark/Arduino’s output pin, but the 1k resistor would limit it to 5mA which is fine.

The eBay posting specifically states 5V 1-Channel Relay interface board, and each one needs 15-20mA Driver Current so, assuming that can be trusted, the microcontroller on the SparkCore can sink/source up to 20mA of current so you should be good to go.

What people on here are trying to say is that the IN1 pin has a resistor betweeen it and VCC (on the relay board itself). This keeps the IN1 pin “high” (~5V) when not in use. When you want to switch the relay you just have to bring the IN1 pin “low” (~0V). I imagine there are two advantages of this:

  1. The relay is automatically turned “off” if the IN1 line gets disconnected
  2. A 3.3V device can easily control the relay because, while it can’t drive to 5v, it can easily sink to 0v. If the board had a pull down (ie, pulled the IN1 pin to 0v) and instead required 5v to turn the relay on the 3.3v the SparkCore puts out might not be enough to activate the transistor and turn the relay on.

Feel free to correct me on the above anyone.

We are going a bit around in circles without ironing down some truths about this relay board.

Please correct me if this is wrong, but the way it’s supposed to be used in a 5V system is to:

  • tie IN1 to 0V to turn the relay ON
  • tie IN1 to 5V (or open) to turn the relay OFF

If that’s true, then I would imagine the circuit looks a bit like this with a PNP transistor driving the relay coil:

There is at least one LED and resistor missing from this schematic that I see on the relay board, if not two of them. @semaja2 can you confirm how the board operates and how many LEDs are on it. If you take a close up picture of the board on both sides, we could probably generate a very accurate schematic.

If you look at the schematic above, you can see how it works when you set IN1 to 0V. Current flows through the Emitter-Base junction and is amplified in proportion to the Emitter-Collector junction. All that is required is to pull the Base 0.7V lower than the Emitter voltage and the PNP transistor will start to turn on.

If you set IN1 to 5V, there will be 0V between Emitter and Collector and the PNP will be off.

If you set IN1 to 3.3V, depending on the series resistor… SOME current will flow. There is definitely enough voltage across the Emitter-Base junction to turn ON the PNP. The amount of Base current would be (5V - 3.3V)/R. The proportional Collector current would then be Ib * Hfe (the gain) of that transistor.

So driving IN1 with an output LOW for ON, and setting that output to an input (high impedance/open) for OFF hopefully makes more sense now :smile:

Now if you can just tell me why they didn’t use an NPN transistor to pull the relay coil to GND, and make driving it make more sense (High = ON, Low/Open = OFF) and universally work from 3.3V and 5V systems…

1 Like

I just put your schematic into a circuit simulator and you are correct. A high impedence input is required!

You and I can continue speculating how this works, but I’m pretty sure we’re both slightly wrong and need @semaja2 to confirm some truths about his relay board :smile:

See my edit. I accidentally make it a 47ohm and not a 47kohm. You were correct!

Yeah but I’m still just guessing… :slight_smile: Like an electronic fortune teller… :crystal_ball:

I actually can’t find the INPUT impedance (without pullup/pulldown) spec for the STM32. Any ideas?

[Edit] Looks like it might be around 40k-50k ohm.

It’s 40k ohms… although they document it as a “weak” pullup… I measured it one time by applying a decade box as a pull down and dialed in the resistance until the voltage on the pin was 3.3V/2.

Wow guys some really in depth discussion going on here, hopefully these pictures/code/videos will help satisfy everyones curiosity :smile:

Attached are two pictures of the front and back of the relay, then 2x code examples using the above suggestions, then a video of the code in action between a 5V Arduino and a 3.3V Spark

Code 1

// PIN2 = D7 and PIN3 = D0 on Spark        
void setup() {
  // put your setup code here, to run once:
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);

Code 2

void setup() {
  // put your setup code here, to run once:
  //pinMode(D0, OUTPUT);
  pinMode(D7, OUTPUT);
void loop() {
  pinMode(D0, OUTPUT);
  digitalWrite(D0, HIGH);
  digitalWrite(D7, HIGH);
  //digitalWrite(D0, LOW);
  pinMode(D0, INPUT);
  digitalWrite(D7, LOW);



@semaja2, where have you got this info from

// PIN2 = D7 and PIN3 = D0 on Spark        

Acutally D7 = 7 and D0 = 0 - but best would be to stick to the D0/D7 notation anyway.
Or have you replaced 2 and 3 in Core Code 1 with D0 and D7?

And for the top view photo, could you post a brighter version?
The traces are not recognizable on this one.