Light led 1-4 based on two buttons, how...?

Hi again Arduino forum :slight_smile:

I have the following diagram: (I know it isn't all right wired up, but you get the idea of how it should be)

in case the image doesn't show:

As you can see I have two buttons and four LEDS, and if the following conditions are met, i want this to happen:

button1 + button2 are both low = red led high
button1 + button2 are both high = yellow led high
button1 high + button 2 low = green led high
button 1 low + button 2 high = blue led high

I think this is very basic knowledge, but I am still not very good at this. I've looked through the Arduino page, and I think that I have to use: ifstatement or booleans but I don't know how to accomplish it. I hope you guys are willing to help me, that would be great!

Thank you very much :slight_smile:

best regards
JohannesTN

There's multiple ways of doing this - short and efficient, or long and understandable :wink:

What you have there is a simple binary value:

 2 | 1 | L
-----------
 L | L | 0
 L | H | 1
 H | L | 2
 H | H | 3

The efficient way would be to use bitshifting and OR to create a numeric value between 0 and 3 and use that to select an LED's pin number from an array.

The long-winded way would be to have 4 if() statements examining both buttons in different combinations and turning on/off LEDs accordingly.

I really have no idea of how much space such sketches for both ways of doing it would take up. I hope it's not too much to ask for, but do you have some examples on how it would look like?

I would like it to be as simple as possible as I could use it later on too

Both, on the scale of the amount of flash the Arduino has, are incredibly tiny.

The long-winded way would have 4 blocks of:

if ((digitalRead(button1) == LOW) && (digitalRead(button2) == LOW)) {
  digitalWrite(led1, HIGH);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);
}

but with each one having a different combination of LOWs and HIGHs.

The efficient, but somewhat cryptic way, would have an array of LED pins:

byte leds[4] = {3, 4, 5, 6};

and then a routine to select the LED:

byte lednum = digitalRead(button1) | (digitalRead(button2) << 1);
for (int i = 0; i < 4; i++) {
  digitalWrite(leds[i], i == lednum ? HIGH : LOW);
}

I'll just quickly describe what is going on there. First, the array is just a simple list of pins. Not mystery there.
Then there's the lednum bit. digitalRead returns either a 1 for HIGH or 0 for LOW. In binary these are 0b00000001 and 0b00000000 respecitvely. So, digitalRead(button1) and digitalRead(button2) would both return either 0b00000001 or 0b00000000. We shift the result of the second digitalRead 1 place to the left, though, so instead of 1 or 0 it returns 2 or 0 - in binary 0b00000010 or 0b00000000.

We then OR those together, which basically superimposes one over the other, which will give us 4 possible combinations:

0b00000000 - no buttons pressed
0b00000001 - button 1 pressed
0b00000010 - button 2 pressed
0b00000011 - both buttons pressed

These binary values, in decimal are 0 to 3. So we then have a little loop going from 0 to 3. In that loop we are turning each of the LEDs either on or off. The little bit of code

i == lednum ? HIGH : LOW

is a short-hand embedded if statememt. It's saying "Is i equal to lednum ? If so use the value HIGH : otherwise use the value LOW. So that is turning off all the LEDs that aren't the selected one, and turning on the one that is.

Thank you very much! - I'll go with the

if ((digitalRead(button1) == LOW) && (digitalRead(button2) == LOW)) {
  digitalWrite(led1, HIGH);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);
}

way of doing it :slight_smile:

I wan't to set the state on one of the buttons (true or false) and then read the state in one of the if-statements, and if "false" do this, if "true" do something other. What would be the easiest way of doing that?

  • my own thought was using Boolian or INT, but what would be the best for reading and writing these states?

thank you
best regards JohannesTN

I wan't to set the state on one of the buttons (true or false)

You can't set the state of an INPUT pin. You can only read it's state.

Sorry for making me unclear.. I meant set the state of a boolean (or an integer) I don't know which is the best?

JohannesTN:
Sorry for making me unclear.. I meant set the state of a boolean (or an integer) I don't know which is the best?

No difference between a boolean and a byte (or char), but an int takes twice as much memory, so don't use that.

So I guess I have to go with the boolean for that then? :slight_smile:

Thank you very much to all of you for helping me out on this one :slight_smile: