Advice on multiple LEDs control. Help!

Arduino beginner and a noob in programing here. After searching for answers in a lot of forums, I'm out of ideas to solve my problem.
I'm using arduino UNO, trying to light 6 red leds in different combinations with 3 different pushbuttons (i.e. if I press button1 2 leds light up, if I press button2 3 leds light up, if I press buttons 2 and 3 other 2 leds light up).
With a basic set of if/else statements I managed to do this but, because I ended up with 6 more free pins (analog ones) and since originally I wanted to have another set of 6 green leds that are always on and only turn OFF when the respective red is ON I tried to incorporate that in my code and my problems started.
At first when I inserted digitalWrite for green leds they, at best, got less bright but stay on all the time, then I created arrays for the red and green leds and called red ones as input simultaneosly and made greens OFF when reds are ON and this is still my best result so far but still greens doesn´t work fine in all button presses.
Here is my code

const int green [] = {A0, A1, A2, A3, A4, A5}; 
int pinCount = 6;
int redState[6];
const int red [] = {2, 4, 6, 8, 10, 12};
const int button1 = 3;
const int button2 = 5;
const int button3 = 7;// the number of the pushbutton pin
const int led1 =  2;
const int led2 =  4;// the number of the LED pin
const int led3 =  6;
const int led4 =  8;
const int led5 =  10;
const int led6 =  12;
int button1State = 0;
int button2State = 0;
int button3State = 0;
void setup() {
  for (int i = 0; i < pinCount; i++) {
    pinMode(green[i], OUTPUT);
    pinMode(red[i], INPUT);
  }
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
}
void loop() {
  for (int i = 0; i < pinCount; i++) {
    redState[i] = digitalRead(red[i]);
    digitalWrite(green[i], !redState[i]);
  }
  button1State = digitalRead(button1);
  button2State = digitalRead(button2);
  button3State = digitalRead(button3);
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (button1State == HIGH & button2State == LOW & button3State == LOW) {
    // turn LED on:
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
  } else {
    // turn LED off:
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
  }
  if (button2State == HIGH & button1State == LOW & button3State == LOW) {
    // turn LED on:
    digitalWrite(led5, HIGH);
    digitalWrite(led6, HIGH);
  } else {
    // turn LED off:
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
  }
  if (button3State == HIGH & button1State == LOW & button2State == LOW) {
    // turn LED on:
    digitalWrite(led1, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(led6, HIGH);
  } else {
    // turn LED off:
    digitalWrite(led1, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
  }
  if (button1State == HIGH & button2State == HIGH & button3State == LOW) {
    // turn LED on:
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
  } else {
    // turn LED off:
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
  }
}

I'm well aware that this could be much more efficiently done with binary tactics but my efforts were fruitless (couldn't make it work). For extra info I used 220 ohm resistors for green LEDs and 560 ohm resistors for red LEDs (because they were presoldered and they worked fine)(I tried to change resistors of reds and results were the same. Push buttons are connected with 10K resistors.
PS: using bitwise or boolean AND in 'if conditions' gives me the same result

I found that I could work the red LEDs in this better packed way but the green LEDs work even worse. I was looking to take a decimal value of combinations of button presses to use a switch...case function but couldn't do it.

void loop() {
  for (int i = 0; i < pinCount; i++) {
    redState[i] = digitalRead(red[i]);
    digitalWrite(green[i], !redState[i]);
  }

  button1State = digitalRead(button1);
  button2State = digitalRead(button2);
  button3State = digitalRead(button3);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (button1State == HIGH & button2State == LOW & button3State == LOW) {
    // turn LED on:
    setMyLeds(1, 1, 0, 0, 0, 0);

  } else {
    // turn LED off:
    setMyLeds(0, 0, 0, 0, 0, 0);

  }
  if (button2State == HIGH & button1State == LOW & button3State == LOW) {
    // turn LED on:
    setMyLeds(0, 0, 0, 0, 1, 1);

  } else {
    // turn LED off:
    setMyLeds(0, 0, 0, 0, 0, 0);

  }
  if (button3State == HIGH & button1State == LOW & button2State == LOW) {
    // turn LED on:
    setMyLeds(1, 0, 0, 0, 1, 1);

  } else {
    // turn LED off:
    setMyLeds(0, 0, 0, 0, 0, 0);

  }
  if (button1State == HIGH & button2State == HIGH & button3State == LOW) {
    // turn LED on:
    setMyLeds(0, 0, 1, 1, 0, 0);

  } else {
    // turn LED off:
    setMyLeds(0, 0, 0, 0, 0, 0);
  }
}
void setMyLeds (byte l1, byte l2, byte l3, byte l4, byte l5, byte l6) {
  digitalWrite(led1, l1 == 0 ? LOW : HIGH);
  digitalWrite(led2, l2 == 0 ? LOW : HIGH);
  digitalWrite(led3, l3 == 0 ? LOW : HIGH);
  digitalWrite(led4, l4 == 0 ? LOW : HIGH);
  digitalWrite(led5, l5 == 0 ? LOW : HIGH);
  digitalWrite(led6, l6 == 0 ? LOW : HIGH);

}

2 Leds + 3 Leds + 2 Leds = 7 Leds. Not 6 Leds.

I can't give this the attention it needs, but you are fighting with yourself, I believe, that is to say the LEDs are actually being turned on and off more than you realize.

If you use the IPO model, you wouldn't have conflicting results, and I further suggest it is the else clauses that are messing you up.

Read about it in the abstract here:

The IPO Model

So.

First read the buttons. This you do, I'll check I checked.

Next, calculate, but do not write to the LEDs, the state they should be set to. Use the same logic, but write into variables, not the LEDs. You could write a function similar to the one that now does have that ability.

Lastly, actually write to the LEDs with the results.

Rinse and repeat.

If you sprinkle Serial.print statements liberally about your logic, I think you will see how this is malfunctioning.

Now you will be in a better position to fix the calculate part. Start by assuming the LEDs should be off, calculate which should actually be turned, or left, on.

HTH

a7

2 Likes

if I press button 1, leds 1 and 2 ON
if I press button 2, leds 1, 5 and 6 ON
if I press button 3, leds 3 and 4 ON

something like this, sorry if I was confusing

I think this code does what you need.
PS: Simulated at :
" Buttons - Wokwi ESP32, STM32, Arduino Simulator
Note: I used switches instead of buttons because I don't know how to press 2 buttons at the same time in the simulator.


const int button1 = 3;
const int button2 = 5;
const int button3 = 7;// the number of the pushbutton pin
const int led1 = 2;
const int led2 = 4;// the number of the LED pin
const int led3 = 6;
const int led4 = 8;
const int led5 = 10;
const int led6 = 12;
int button1State = 0;
int button2State = 0;
int button3State = 0;
void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
}
void loop() {
  button1State = digitalRead(button1);
  button2State = digitalRead(button2);
  button3State = digitalRead(button3);
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (button1State == HIGH & button2State == LOW & button3State == LOW) {
    // turn LED on:
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
  } else {
    // turn LED off:
    digitalWrite(led2, LOW);
  }
  if (button2State == HIGH & button1State == LOW & button3State == LOW) {
    // turn LED on:
    digitalWrite(led1, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(led6, HIGH);
  } else {
    // turn LED off:
    digitalWrite(led1, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
  }
  if (button1State == HIGH & button2State == HIGH & button3State == LOW) {
    // turn LED on:
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
  } else {
    // turn LED off:
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
  }
}

Consider turning that around and thinking of the outputs and what causes them to be on of off.

This is the "calculate" portion of:

1 Like

yes, my red leds set work fine in that way, which is my way of doing it (and I think is not very efficient but anyway...it works). My problem is when I try to have another 6 green leds and having them ON and only OFF when the corresponding red led is ON.

i.e.
press button 1 -> red led 1 is ON, green led 1 os OFF

PS: I've been using that simulator to ease my trials and test it on my phone or a tablet

I'll work on this then. But after so many disappointing experimenting and readings of multiple LEDs controls I decided to ask to see if I should work my code in a different way, that I don't know how (because I'm not a programing guy at all)

Hardware

  • As always, show us a good schematic of your proposed circuit. Hand drawn schematics are acceptable.
  • Show us good images of your ‘actual’ wiring.
  • Give WEB links to your major components.

I don' t have a circuit scheme but it is very straight forward.
Is a very standard led with pushbutton scheme and wiring but with 6 red LEDs (with 560 ohm resistors connected to grd and positive on digital pins) and 6 green LEDs (with 220 ohm resistors connected to grd and positive conected to analog pins) and 3 pushbuttons (with 10k resistors on grd, negative connected on digital pins and positive on 5V)

Turn reading three buttons

  button1State = digitalRead(button1);
  button2State = digitalRead(button2);
  button3State = digitalRead(button3);

into a number between 0 and 7

   int inputNumber = 4 * button3State + 2 * button2State + button1State;

Then use a switch/case to decide what to do for each possible combination of input buttons, viz:

  switch (inputNumber) {
  case 0 :

// code for all buttons pressed 

    break;

  case 1 :

// code for buttons 3 and 2 pressed

    break;

and so forth. Depends on how you wired the buttons; put print statements in all cases ans watch the output.

a7

2 Likes
  • Suggest you get into the habit of always making a schematic before wiring anything.

  • Please show us good images of your wiring.

1 Like

OK, with some printing

void setMyLeds (byte l1, byte l2, byte l3, byte l4, byte l5, byte l6) {

Serial.print("led3 ");
Serial.println(l3 ? "ON" : ".............OFF");

  digitalWrite(led1, l1 == 0 ? LOW : HIGH);
  digitalWrite(led2, l2 == 0 ? LOW : HIGH);
  digitalWrite(led3, l3 == 0 ? LOW : HIGH);
  digitalWrite(led4, l4 == 0 ? LOW : HIGH);
  digitalWrite(led5, l5 == 0 ? LOW : HIGH);
  digitalWrite(led6, l6 == 0 ? LOW : HIGH);

}

and pressing one of the buttons I see

led3 .............OFF
led3 .............OFF
led3 ON
led3 .............OFF
led3 .............OFF
led3 .............OFF
led3 ON
led3 .............OFF
led3 .............OFF
led3 .............OFF
led3 ON
led3

Which is where I have to leave it, but it confirms my suspicion.

HTH

a7

1 Like

well thanks a lot for your help. I understand the printing functions are really helpfull it just happens I'm a complete noob and even that can be confusing to me ahah.
ANYWAY...with your help on turning the 3 buttonstates into a decimal value of the 0's and 1's (which now looks ridiculously simple) I was able to make a switch...case statement and with my initial arrays I'm now able to do what I wanted Thank you very much.
I might now try to understand what is actually happening and try to optimize the code but I'm happy that is working now at least.

I know and did at first on a paper ahah. I just didn't bother in this case now to show because I thought it was very simple and understandable to people who use arduino

Hello chemguy_gaspar

Welcome to the best Arduino forum ever :slight_smile:

I have read your task describtion and some lines of code.

By this a question arose:

Do you want to design and programme a traffic light system?

If you're asking about my project, is a no. I'm trying to simulate a kind of brain surgery for a science activity.
Buuut I came across lots of similarities with traffic light control...do you have anything made?

CTRL-click "holds" a button in Wokwi.

1 Like

Another thing wokwi will do is simple electricity.

You can use slide switches or dip switches in combination with pushbuttons to make super pushbuttons that act like pressing multiple regular ones.

In a project relying on multiple buttons it can be handy.

It does, however, mean the pushbuttons go down exactly at the same instant; this highlights a problem with command-click, or whatever it is, as it is hard impossible to get two buttons to go down within what might be a programmed threshold even a generous one like 100 milliseconds.

But for this button while that button is being held, the command-click works OK.

a7