-1

I want to control 4 digital outputs (d0, d1, d2, d3) with one switch. When the Arduino starts, they should all be in state LOW.

Now, after pressing the button once, d0 should get HIGH. Another push brings d0 to LOW and d1 to HIGH. So actually the 4 outputs shall behave like a bitmask. After every push the bitmask shall increment by one.

d0 LOW
d1 LOW
d2 LOW
d3 LOW

push

d0 HIGH
d1 LOW
d2 LOW
d3 LOW

push

d0 LOW
d1 HIGH
d2 LOW
d3 LOW

Is there an easy way to implement this, without typing every case in the code?

I am glad for any hints. Cheers and thanks.

1

As usual with programming, there are many solutions, for example:

  1. You can use a bitmask, put 4 variables in an array with binary values 1000, 0100, 0010 and 0001 and when the switch is pressed, you store the value into each LED pin by comparing the value.
  2. However, a more simpler solution is just use a counter from 0 to 4, if the value is 1, the first LED should be one, then after a switch increase the value, and use modulo 5 (% 5) to go back to 0.

To check if a button is clicked, use a boolean, which check against the previous value. Also implement the debounce algorithm which can be found at the Arduino site.

Without debouncing it could look like this:

#include "stdlib.h"

int buttonPin    =   7;
int buttonState  = LOW;

int led1Pin      =   8;
int led2Pin      =   9;
int led3Pin      =  10;
int led4Pin      =  11;
int ledMode      =   0; // All off, 1-4 means LED 1-4 is on


void setup()
{
}


void loop()
{
   // Add debouncing yourself
   if ((buttonState == LOW) && (digitalRead(buttonPin) == HIGH))
   {
      buttonState = HIGH;
      ledMode = (ledMode + 1) % 5;
   }
   else if ((buttonState == HIGH) && (digitalRead(buttonPin) == LOW))
   {
      buttonState = LOW;
   }

   digitalWrite(led1Pin, ledMode == 1 ? HIGH : LOW);
   digitalWrite(led2Pin, ledMode == 2 ? HIGH : LOW);
   digitalWrite(led3Pin, ledMode == 3 ? HIGH : LOW);
   digitalWrite(led4Pin, ledMode == 4 ? HIGH : LOW);
}

If you put the LEDs on subsequent pins, you can use the following code which is more simpler and works for any number of LEDs:

#include "stdlib.h"

int buttonPin    =   7;
int buttonState  = LOW;

int nrOfLeds     =   4;
int startLed     =   8;
int ledMode      =   0; // All off, 1 means led on pin startLed, 2 means led on pin startLed + 1 etc.


void setup()
{
}


void loop()
{
   // Add debouncing yourself
   if ((buttonState == LOW) && (digitalRead(buttonPin) == HIGH))
   {
      buttonState = HIGH;
      ledMode = (ledMode + 1) % (nrOfLeds + 1);
   }
   else if ((buttonState == HIGH) && (digitalRead(buttonPin) == LOW))
   {
      buttonState = LOW;
   }

   for (int led = 0; led < nrOfLeds; ledPin++)
   {
       digitalWrite(startLed + led, ledMode == led + 1 ? HIGH : LOW);
   }
}
  • 1
    Thank you very much for your detailed answer! – Philipp Oct 21 at 13:50
  • If it helps you, upvote the answer, if it is the correct answer for you, also make it as accepted. – Michel Keijzers Oct 21 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.