Toggle two LEDs and one button via 3 Wires

Hi,

then, by chance, I found a wiring layout for my project.
I want toggle two LEDs with one button with a minimum of wires.
I can toggle the LEDs but how can I read out if the button is pressed?

Many thanks.

void setup(void)
{
   pinMode(10, OUTPUT);
   pinMode(11, OUTPUT);
   pinMode(12, OUTPUT);
}

void loop(void)
{
   static boolean ledState;

     digitalWrite(11, 1);
     digitalWrite(10, 0);
     //digitalWrite(12, 0);
     delay(1000);
     digitalWrite(11, 0);
     digitalWrite(10, 1);
     delay(1000);
}

Untitled.png

Untitled.png
So exactly what is wrong with providing a ground wire?

You said "toggle". Do both LEDs need to be illuminated at once?


OK, I'll do it for you!
If both LEDs do not need to be illuminated at once - which your present circuit does not permit in any case, connect the two LEDs back-to-back with a single 330 Ohm in series. Connect the switch from either of the two LED wires to the third pin.

When you need to check the switch, you ground both LED wires (so that it does not matter to which wire the switch is connected) and set the switch wire to INPUT_PULLUP, read the switch, set it to INPUT and then set the LED wires to whatever they were before.

If you really did not want to switch the current LED off for a few microseconds to read the switch - which is unlikely - you could connect the switch to the anodes of two diodes, one cathode to each LED line, one of which will always be LOW.

If perchance you want both LEDs illuminated 99%, then that can be done too. But that's a different question. :roll_eyes:

Hi Paul,

many thanks for your help. Did you mean the schematic like this?

I tried this code, but it doesnt work.

Many thanks.

int buttonState = LOW; //this variable tracks the state of the button, low if not pressed, high if pressed
int ledState = -1; //this variable tracks the state of the LED, negative if off, positive if on
int ledPin = 13;
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers
char buf[10];


void setup(void)
{
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  digitalWrite(11, 0);
  digitalWrite(10, 1);
  Serial.begin(9600);
}

void loop(void)
{
  static boolean ledState;
  int pin10 = digitalRead(10);
  int pin11 = digitalRead(11);

  if (pin10 == HIGH) {
    pinMode(12, INPUT_PULLUP);

    buttonState = digitalRead(12);
    digitalWrite(13, buttonState);
    if (buttonState == LOW) {
      ledState = -ledState;
    }
  } else {
    pinMode(12, INPUT);
    buttonState = digitalRead(12);
    if (buttonState == HIGH) {
      ledState = -ledState;
    }
  }
  sprintf(buf, "ledState=%d\n", ledState);
  //Serial.write(buf);
  //buttonState = digitalRead(12);


  //if the button has been pressed, lets toggle the LED from "off to on" or "on to off"
  if (  (ledState < 0) ) {
    //pinMode(12, OUTPUT);
    digitalWrite(10, HIGH); //turn LED on
    digitalWrite(11, LOW);

    //now the LED is on, we need to change the state

  }
  else if ( (ledState > 0) ) {
    //pinMode(12, OUTPUT);
    digitalWrite(11, HIGH); //turn LED on
    digitalWrite(10, LOW);

    //ledState = -ledState; //now the LED is off, we need to change the state

  }//close if/else

}

Capture.JPG
Yes, that is a good circuit for a start.

Code problems:

  • Pin 12 should never be an output.
  • You cannot read pin 12 unless there is a pull-up on it, so without INPUT_PULLUP in effect, it is meaningless. You perhaps thought there was some way of having a pull-down on it instead. In fact, there is - you can have a pull-up/ down to pin 10 which will always be (if any LED is lit, that is,) the opposite to Pin 11. Then just read it only ever as an INPUT. Your
if (  (ledState < 0) ) {
...
  else if ( (ledState > 0) ) {

is rather amusing, since ledState should be either 1 or -1, there should be no third or "middle" (zero) option! A simple "else" would suffice. :grinning:

Hello,

many thanks for the tips. Now it works, but i have to use the delay function, otherwise the LEDs in Pin11=High mode only glows slightly.
Is there a chance to get rid of the delay?

int buttonState = LOW; //this variable tracks the state of the button, low if not pressed, high if pressed
int buttonStatePrevious = LOW;
int state = HIGH; 
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 550;    // the debounce time; increase if the output flickers


void setup(void)
{
  pinMode(13, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, INPUT_PULLUP);
  digitalWrite(11, not state);
  digitalWrite(10, state);

}

void loop(void)
{
  static boolean ledState;
  int pin10 = digitalRead(10);
  int pin11 = digitalRead(11);

  if (pin10 == HIGH) {
    buttonState = digitalRead(12);
    digitalWrite(13, buttonState);
  } else if(pin11 == HIGH) {
    delay(10);
    digitalWrite(11, LOW);
    delay(10);
    digitalWrite(10, HIGH);
    buttonState = digitalRead(12);
    digitalWrite(13, buttonState);
  
  }
  if (buttonState == HIGH && buttonStatePrevious == LOW && millis() - lastDebounceTime > debounceDelay)
    {
      if (state == HIGH)
        state = LOW;
      else
        state = HIGH;
    
      lastDebounceTime = millis();
    }

  buttonStatePrevious=buttonState;
  digitalWrite(11, not state);
  digitalWrite(10, state);
}

ManuelFi: Now it works, but i have to use the delay function, otherwise the LEDs in Pin11=High mode only glows slightly. Is there a chance to get rid of the delay?

That would be because you failed to reset pins 10 and 11 to their former states immediately after reading pin 12. And there was no reason to set pin 10 HIGH while you read pin 12 anyway, that only activates the other LED!

Your code is very confused! If - as previously observed - there are only two possible states, then you only need one state variable and you set the pins according to it in every step. There is no need to read pins 10 and 11 as you obviously know what you wrote to them last. Haven't the time to write it for you just now, but it really should be very simple!