Power Flowing from an Arduino Pin

Hi all,

I've written some simple code to blink one of two leds depending on the postion of a SPDT switch. I also connected two push switches to one of the leds loop to see if I could control a relay with it when that light is blinking.

My diagram is something like this:

There's a few things to note:

  • I'm not sure of that is the right icon for a spdt switch. In real life, I have one pin in 3.3v, one in GND and the middle one in ~3 which reads a value, 0 or 1 depending on the position of the switch
  • I've not shown power going to the relay, as I'm not sure how that is displayed with that icon, I've a two channel relay, one with GND, IN1, IN2 and VCC.
  • I plan to replace the two push buttons with a three way switch (middle off, up and down) as I don't want someone to be able to push both buttons at the same time.

My main question is one of understanding how power goes through an arduino. Regardless of which position the switch is in, the push buttons can activate the relay to make it go CW or CCW. I thought a signal would only flow through the the relay inputs when the upper LED is activated (HIGH). When the lower one is activated, I can still control the relay.

So is there usually some small residual power flowing to the first LED when it is on LOW, just not enough to power the led very dimly, but if I close the circuit by pushing one of the buttons, it is enough to give a signal to the relay?

My sketch code is:

const int switchPin = 3;
const int redLed = 12;
const int greenLed = 13;

void setup() {
  pinMode(switchPin, INPUT);
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int switchValue = digitalRead(switchPin);
  Serial.println(switchValue);

  if (switchValue == HIGH) {
    // manual mode
    blink(redLed);
  } else {
    // sensor mode
    blink(greenLed);
  }
}

void blink(int ledPin) {
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  delay(500);
}

Please complete all circuit connections in your schematic and sow it again.

1 Like

Purchase a few spare Arduinos as you will probably blow them with your circuit. Why are the relay coils connected to the motor.

I don't see any power for the arduino.
D3 is connected either directly to GND or 3.3v
What is D12 supposed to be doing? It is connected to ground through your ?resistor and LED and ?also connected to D3??
Your relays are a mess with an unpowered motor connected through 2 coils and a momentary button on both sides directly to GND
You have power connected to a relay switch side which if the relay could activate would be a short.

Well I obviously don't understand yet how to draw a full circuit diagram. I'm more interested in understanding why it seems like power still flows through a pin (13) when I've set the pin to low in my code.

“Well I obviously don't understand yet how to draw a full circuit diagram.”
You did a good job but we are not there where you are.

  • We need to be shown in a complete schematic with all your connections before we can fully help out.
  • Fact, if the pin 13 output pin is made HIGH the LED on that pin will turn ON.
    If pin 13 output pin is made LOW the LED on that pin will turn OFF.
    There is no leakage current (unless you have damaged something).

“I'm more interested in understanding why it seems like power still flows through a pin (13) when I've set the pin to low in my code.”

  • Explain what it seems means ?

That is a disaster. Please post the correct schematic.

If you don't know how to draw one, this tutorial is a good place to start.

1 Like

For me the basic language for electronics is a properly drawn annotated schematic. One schematic can tell an engineer more in a few moments then hours spend in questions and answers. Electronics although a lot of fun is not that simple. It is a language in itself.

3 Likes

Possibly because that is a very bad way to connect the switch?

I'd recommend you disconnect the relays and motors from your circuit until you get the leds working correctly.

Then provide LINKS to your motors and relays.

2 Likes

Yes, disconnect anything that uses more than an LED! Replace anything else with an LED to act as an indicator. That way you are less likely to burn anything, although still possible. Work on 1 bit at a time

Ok, so I've dropped the relays for now and replaced them with lights, and I've downloaded and used Fritzing for the first time. It's a bit easier for a beginner to understand as it's physically similar to what I see in front of me! Here's what I have:

This seems to work fine for me. The idea is that the SPDT switch changes my system from manual to sensor driven. At the start of loop, I read what it is set at to determine that. When it is manual, I set the two pins for the push buttons (D6 and D7) to HIGH.

When it is sensor driven, those pins are set to low, and pins D2 and D3 are set to HIGH (they are set to LOW when it is manual). Is it bad practice to have those to sets of pins (D3/D6 or D2/D7) connected to one LED? The LEDs are illuminated to the same level whether it is manual or sensor mode.

You can mostly ignore the buzzer, that just sounds when either of the green or yellow LEDs come on in sensor mode so that I notice it (I can keep an eye on LEDs all the time!).

My next step is to replace the LEDs with the relay, but from my previous test, pins D2 and D3 were able to activate the relay, but pins D6 and D7 would only power the IN1 or IN2 LED very faintly, and the relay didn't sound as if it was activated. If I removed pins D2 and D3, then D6 and D7 would power the relay as expected.

I'm not sure why the LEDs seemed to have the same result when in manual or sensor mode, but the relay doesn't, so I guess there is something else that I need to work out.

Remove the connection from the +3V3 line to the switch.

Change this:

 pinMode(switchPin, INPUT);

to

 pinMode(switchPin, INPUT_PULLUP);

Fritzing may be fine for you but the pictures are quite useless for others. Even a hand drawn circuit diagram is easier to decipher.

1 Like

Thanks @johnerrington - I did that, and it still works as expected. Have been reading a bit more about INPUT_PULLUP to try to understand it a bit more.

@DrDiettrich - I've redone the circuit diagram, and hope it is understandable now. I'm still a noob at all this and trying to learn more, and hopefully I'll get better at them

A couple of things to note on the diagram. I didn't know how to show the arduino being powered, but for now it is just plugged into my laptop via USB. I didn't include the rain sensor, as I've no idea how to incorporate that in a circuit diagram, just assume that the arduino is taking readings from it. I also forgot to include resistors just before the two LEDs at the bottom.

LedControlCircuitDiagram

Also, contrary to what I said before, the amount of light given off by the LEDs is lower when using the push buttons over D2/D3, similar to what I noticed before with the relay.

Here's the code if you're interested:

/*
Take 10 readings and use the average to work out how wet it is.  If it is above a certain threshold
open the door if it is closed, and below a certain threshhold, close the door if it is open.

There is a manual override switch that allows us to control the door and not take any sensor readings.
*/
#define sensorPower 8
#define sensorAnalogPin A0
int relay1 = 2;
int relay2 = 3;
int buzzer = 9;

const int switchPin = 4;
const int ledPin = 12;
const int push1 = 6;
const int push2 = 7;

const String OPEN = "OPEN";
const String CLOSED = "CLOSED";

int analogAverage[10];  // Store the most recent 10 readings
int arrayCount = 0;  // use this to loop over the array above
int previousValue;

String state = OPEN;
boolean manualMode;

void setup() {
  pinMode(sensorPower, OUTPUT);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(buzzer, OUTPUT);

  pinMode(switchPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  pinMode(push1, OUTPUT);
  pinMode(push2, OUTPUT);

	// Initially keep the sensor OFF
	digitalWrite(sensorPower, LOW);
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
  digitalWrite(push1, HIGH);
  digitalWrite(push2, HIGH);

	Serial.begin(9600);
  
  // play tone just to check it is working
  tone(buzzer, 400, 500);

  resetArrays();
}

void loop() {
  int switchValue = digitalRead(switchPin);
  Serial.println(switchValue);

  if (switchValue == HIGH) {
    // manual mode, so switch on push buttons and turn on light
    if (!manualMode) {
      digitalWrite(push1, HIGH);
      digitalWrite(push2, HIGH);
      digitalWrite(ledPin, HIGH);
    }
    manualMode = true;
  } else {
    // sensor mode
    if (manualMode) {
      // was manual mode, now going to sensor mode, so switch off push buttons and turn off light
      digitalWrite(push1, LOW);
      digitalWrite(push2, LOW);
      digitalWrite(ledPin, LOW);
      
      resetArrays();
    }
    manualMode = false;

    analogAverage[arrayCount] = readSensor();  // read sensor value into array
    int valAverage = arrayAverage(analogAverage, 10);

    shouldDoorOpenOrClose(valAverage);
    // increment, and if needed reset, the array counter
    incrementAndResetArrayCount();
  }
	delay(5000);
}

void resetArrays() {
  // fill average array with current reading over 5 seconds
  for (int i = 0; i < 10; i++) {
    analogAverage[i] = readSensor();
    delay(500);
  }
}

/**
return false to close the door, true to open. 
*/
void shouldDoorOpenOrClose(int valAverage) {
  // is the value on an upwards or downwards trend?
  Serial.print("valAverage = ");
  Serial.print(valAverage);
  Serial.println("");

  if (valAverage > 850) {
    // almost certainly quite dry even if the sensor is getting a bit moister
    controlShutterDoor(true);
  } else if (valAverage < 500) {
    // almost certainly quite wet even if the sensor is getting a bit dryer
    controlShutterDoor(false);
  }
}

void controlShutterDoor(bool shouldOpen) {
	if (shouldOpen) {
		Serial.print(" Status: Clear   ");
    if (CLOSED == state) {
      Serial.println("                                                                                          Opening the door");
      buzzAndTurnMotor(400, relay1);
      state = OPEN;
      onStateChange(30000);  // change to 5 minutes IRL on opening
    } 
	} else { // should close
		Serial.print(" Status: Raining ");
    if (OPEN == state) {
      // close the door, takes about 20 seconds
      Serial.println("                                                                                          Closing the door");
      buzzAndTurnMotor(4000, relay2);
      state = CLOSED;
      onStateChange(30000); // change to 30 minutes IRL on closing
    }
	}
}

void onStateChange(int delayMS) {
  delay(delayMS);
  resetArrays();
}

int readSensor() {
  //get the reading from the sensor and print it
  digitalWrite(sensorPower, HIGH);	// Turn the sensor ON
	delay(40);							// Allow power to settle
  int valAnalog = analogRead(sensorAnalogPin);
	digitalWrite(sensorPower, LOW);		// Turn the sensor OFF
	Serial.print(" Analog Output: ");
	Serial.print(valAnalog);
  return valAnalog;
}

int arrayAverage(int values[], int size) {
  int total = 0;
  Serial.print(" - ");
  for ( int k = 0 ; k < size ; ++k ) {
    total += values[k];
    Serial.print(values[k]);
    Serial.print(", ");
  }
  return total / size;
}

void incrementAndResetArrayCount() {
  arrayCount++;
  if (arrayCount > 9) {
    arrayCount = 0;
  }
}

void buzzAndTurnMotor(int buzzFrequency, int relayPin) {
  digitalWrite(relayPin, HIGH);
  for (int i = 0; i < 10; i++) {
    tone(buzzer, buzzFrequency, 500);
    delay(1000);
  }
  digitalWrite(relayPin, LOW);
}

Still a disaster.

Among other problems, you fail to show current limiting resistors in series with two of the LEDs, which will burn out the port pins.

Connecting outputs together, such as D7 and D2, can burn out both pins.

Ok, I did mention that I forgot to put them in the diagram in my previous comment, so I've added them in now.

image

Please let me know what other problems apart from the issue with having D2/D7 and D3/D6 connected together. I did ask previously if it is bad practice, but I don't know how to get around the fact that I want to power the LEDs (eventually the IN1 and IN2 on a relay) from two different pins depending on the switch reading in D4 (for manual and sensor operation).

Thanks,
Stephen

It's still not clear to me why

I want to power the LEDs (eventually the IN1 and IN2 on a relay) from two different pins depending on the switch reading in D4 (for manual and sensor operation).

That answer will, I think, clarify a lot.

There is the possibility that D6 D7 being HIGH and D2 or D3 could be be LOW then closing a switch will tie the outputs together and you will damage an output pin.

i.e. 5v connected to GND trough the switch :woozy_face:


Tell us, in point form, exactly what needs to happen in your circuit.

Look up the “xy problem” and then give a high level overview of what you are trying to achieve.

Sure.

I have a 2-channel relay that I would like to control a DC motor to go CW or CCW depending on a reading from a sensor.

I would also like to have a manual override to control the relay with a rocker switch (it should always sit in the middle, and you can press up to go CW and down to go CCW). The two push buttons mimic the rocker switch for now until it arrives in the mail. I guess I could/should update the diagrams to reflect that.

To achieve control of the two modes, I have a SPDT switch. If it is switched one way, that is sensor control, and if it is switched another way it is manual control.

When it is sensor controlled, currently I make one of the two pins D2 or D3 HIGH for a period of time depending on the direction I want the motor to run.

When it is manual controlled, I switch on the red LED (just as a notifier), and the user can use the push buttons on D6/D7 to turn the motor CW or CCW (obviously not together, hence the need for a rocker switch).

Hope that is clearer, and maybe there is a much better way of achieving this that I'm unaware of.