Activating 2 sets of LEDs with 2 Buttons

Hi, Im making turn counter for a 2 player game(BloodBowl)

My intention is that every time the player hits the button an LED will turn on.

I have this working for Red Player

Im not sure how to program the second button (ButtonBlueTurn) to control a 2nd set of LEDs, as the different integer states are already controlled by the first player (ButtonRedTurn and red LEDs)

#define ButtonRedTurn 40      //Red players Turn button
#define ButtonBlueTurn 30      //Blue Players Turn Button
#define redT1 41          //
#define redT2 42        //
#define redT3 43       //
#define redT4 44       // 
#define blueT1 31

int state = 0;    //integer to hold current state
int old = 0;      //integer to hold last state
int ButtonRedTurnPoll = 0;   //integer to hold button state



void setup() {
 pinMode(ButtonRedTurn,INPUT); // button set as input 
 pinMode(redT1,OUTPUT);  //LEDs set as outputs
 pinMode(redT2,OUTPUT);
 pinMode(redT3,OUTPUT);
 pinMode(redT4,OUTPUT);
 pinMode(blueT1,OUTPUT);

 digitalWrite(redT1,LOW);            //set initial state as off
  digitalWrite(redT2,LOW);
   digitalWrite(redT3,LOW);
      digitalWrite(redT4,LOW);
digitalWrite(blueT1,LOW);   
}

void loop() {
                       //debouncing routine to read button
ButtonRedTurnPoll = digitalRead(ButtonRedTurn);   //poll state of button
if(ButtonRedTurnPoll == 1) {            
  delay(50);                          //wait 50ms
 ButtonRedTurnPoll = digitalRead(ButtonRedTurn); //poll button again
  if(ButtonRedTurnPoll == 0) {
    state = old + 1;
  } }
else {
  delay(100);
}
switch (state) {               //react to button press and state
case 1:
  digitalWrite(redT1,HIGH);
  digitalWrite(blueT1,HIGH);
  old = state;
  break;
case 2:
  digitalWrite(redT2,HIGH);
  old = state;
  break;
case 3:
  digitalWrite(redT3,HIGH);
  old = state;
  break;
case 4:

  digitalWrite(redT4,HIGH);
  old = state;
  break;  

default:   //if state not 1 2 or 3
 digitalWrite(redT1,LOW);
  digitalWrite(redT2,LOW);
  digitalWrite(redT3,LOW);
  digitalWrite(redT4,LOW);
  digitalWrite(blueT1,LOW);

  old = 0;
  break;  
}}

LightsSequence_Red_TurnCounter_Add_Second_B_copy_20230930171528.ino (1.6 KB)

use a button library like Toggle from @dlloyd. That will make your code so much easier...

1 Like

Welcome to the forum

The simple but clumsy way to implement a second control would be to copy the code for the first one and change the names of the variables so that there is no clash between those for player one and those for player two

You should also think about what happens if either button is held down for a period of time, say 1 second or longer

There is a much neater way to do it which involves less code but I suggest that you try the simple version first

PREDICTION :
I see you using arrays in the near future once the simple version works and you want to tidy it up

1 Like

Thanks Ill check it out!

Hello mckinleyjohn

Welcome to the worldbest Arduino forum ever.

I´v made a small code review.

In general - Arrays and structs are your friends.
Don't duplicate code in your sketch. Write code once - use it multiple times.
You should not use magic numbers. The I/O pins love to have a functional name.

Do you have experience with programming in C++?

The task can easily be realised with an object.
A structured array contains all information, such as pin addresses for the I/O devices, as well as the information for the timing.
A single service takes care of this information and initiates the intended action.
The structured array makes the sketch scalable until all I/O pins are used up without having to adapt the code for the service.
It is cool stuff, isn´t it?

Have a nice day and enjoy coding in C++.

Thanks, you are right I am attempting to do it the clumsy way now,

Nothing happens if I hold the button down for a long time, it still works correctly

Ill have to find out what an array is!

Hi, thanks for your review.

Ive been using C++ for about 3 days now so as you can imagine I have not heard of Arrays, structures, objects, magic numbers etc.

I have some googling to do now!

If you had advice on good place to learn info specific to triggering sets of LEDs with buttons that would be awesome,

cheers

I guess I have some googling to do!

To the begining the IDE provides a lot basic examples.
Give them a try to gain the knowledge.

Use this textbook as knowlwdge base.

https://www.learncpp.com/

Once you have done the basic examples from Arduino's Built-in Examples and understand the basic structure of a sketch, how to wire a LED with its current resistor and a button with INPUT_PULLUP and deal with bouncing, then you can move to the next stage using a third party library to handle the buttons .

here is a little example with LEDs and buttons

click to see the code and wiring
#include <Toggle.h>                 // https://github.com/Dlloydev/Toggle

const byte redButtonPin = A0;
const byte blueButtonPin = A1;

const byte redLedPins[] = {8, 9, 10, 11};
const byte redLedPinsCount = sizeof redLedPins / sizeof * redLedPins;
byte redIndex = 0;

const byte blueLedPins[] = {2, 3, 4, 5};
const byte blueLedPinsCount = sizeof blueLedPins / sizeof * blueLedPins;
byte blueIndex = 0;

Toggle redButton, blueButton;


void introAnimation() {
  // blue lights ON
  const unsigned long speed = 50;
  // red lights ON
  for (int8_t i = redLedPinsCount - 1; i >= 0 ; i--) {
    digitalWrite(redLedPins[i], HIGH);
    delay(speed);
  }
  for (int8_t i = blueLedPinsCount - 1; i >= 0 ; i--) {
    digitalWrite(blueLedPins[i], HIGH);
    delay(speed);
  }
  // blue lights OFF
  for (int8_t i = 0; i < blueLedPinsCount; i++) {
    digitalWrite(blueLedPins[i], LOW);
    delay(speed);
  }
  // red lights OFF
  for (int8_t i = 0; i < redLedPinsCount; i++) {
    digitalWrite(redLedPins[i], LOW);
    delay(speed);
  }
}

void setup() {
  for (byte i = 0; i < redLedPinsCount; i++) pinMode(redLedPins[i], OUTPUT);
  for (byte i = 0; i < blueLedPinsCount; i++) pinMode(blueLedPins[i], OUTPUT);
  redButton.begin(redButtonPin);
  blueButton.begin(blueButtonPin);

  introAnimation();
}

void loop() {
  redButton.poll();
  if (redButton.onPress()) { // red button pressed

    // flip state of the LED at the index
    if (digitalRead(redLedPins[redIndex]) == HIGH) {
      digitalWrite(redLedPins[redIndex], LOW);
    } else {
      digitalWrite(redLedPins[redIndex], HIGH);
    }

    // increase the index
    redIndex++;

    // don't overflow
    if (redIndex >= redLedPinsCount) redIndex = 0;
  }

  blueButton.poll();
  if (blueButton.onPress()) { // blue button pressed

    // flip state of the LED at the index
    if (digitalRead(blueLedPins[blueIndex]) == HIGH) {
      digitalWrite(blueLedPins[blueIndex], LOW);
    } else {
      digitalWrite(blueLedPins[blueIndex], HIGH);
    }

    // increase the index
    blueIndex++;

    // don't overflow
    if (blueIndex >= blueLedPinsCount) blueIndex = 0;
  }
}

2 Likes

Thanks so much for this, you've definitely put me on the right track!

Ill take some time to try to understand how this code works.

If I can figure it will be the solution for 90% of the project I am working on

Don’t take shortcuts / cut corners

Spending time on the basics (including a C++ tutorial) will be very beneficial in the long run and will help you understand the code I wrote

Success! I was able to modify the code you wrote so that when the Leds are all on, the next button push resets all LEDs to off. (its a turn counter for an 8 turn game)

thanks again for your help

Ive done the basic Arduino tutorials but I want to learn about the basic structure and theory of
how the programming works, ( ) { } ; what is byte etc.
There is so much out there I don't know where to start

`#include <Toggle.h>                 // https://github.com/Dlloydev/Toggle

const byte redButtonPin = A0;
const byte blueButtonPin = A1;

const byte redLedPins[] = {8, 9, 10, 11, 99}; //last pin is a fake to get the index count higher
const byte redLedPinsCount = sizeof redLedPins / sizeof * redLedPins;
byte redIndex = 0;

const byte blueLedPins[] = {2, 3, 4, 5, 88};
const byte blueLedPinsCount = sizeof blueLedPins / sizeof * blueLedPins;
byte blueIndex = 0;

Toggle redButton, blueButton;


void introAnimation() {
  // blue lights ON
  const unsigned long speed = 50;
  // red lights ON
  for (int8_t i = redLedPinsCount - 1; i >= 0 ; i--) {
    digitalWrite(redLedPins[i], HIGH);
    delay(speed);
  }
  for (int8_t i = blueLedPinsCount - 1; i >= 0 ; i--) {
    digitalWrite(blueLedPins[i], HIGH);
    delay(speed);
  }
  // blue lights OFF
  for (int8_t i = 0; i < blueLedPinsCount; i++) {
    digitalWrite(blueLedPins[i], LOW);
    delay(speed);
  }
  // red lights OFF
  for (int8_t i = 0; i < redLedPinsCount; i++) {
    digitalWrite(redLedPins[i], LOW);
    delay(speed);
  }
}

void setup() {
  for (byte i = 0; i < redLedPinsCount; i++) pinMode(redLedPins[i], OUTPUT);
  for (byte i = 0; i < blueLedPinsCount; i++) pinMode(blueLedPins[i], OUTPUT);
  redButton.begin(redButtonPin);
  blueButton.begin(blueButtonPin);

  introAnimation();
}

void loop()

{const unsigned long speed = 150; 
  redButton.poll();{                                           //Red Button score counter
  if (redButton.onPress()) { // red button pressed

    // flip state of the LED at the index
    if (digitalRead(redLedPins[redIndex]) == LOW) {
      digitalWrite(redLedPins[redIndex], HIGH);
    } else {                                                    
      digitalWrite(redLedPins[redIndex], HIGH);                   //This is not needed
    }

    // increase the index
    redIndex++;

    // don't overflow 
    if (redIndex >= redLedPinsCount)                             //if Index is more than LED count
    for (int8_t i = 0; i < redLedPinsCount; i++) {               // Turn off
    digitalWrite(redLedPins[i], LOW);                            //LEDs one by one
    delay(speed);                                                // at this speed
    
     redIndex = 0;                                               // then red index back to 0
  }
  }
  }
  
  blueButton.poll();
  if (blueButton.onPress()) { // blue button pressed

    // flip state of the LED at the index
    if (digitalRead(blueLedPins[blueIndex]) == LOW) {
      digitalWrite(blueLedPins[blueIndex], HIGH);
    } else {
      digitalWrite(blueLedPins[blueIndex], HIGH);               // not needed now
    }

    // increase the index
    blueIndex++;

    // don't overflow
    if (blueIndex >= blueLedPinsCount)                         //index more than LED count    
    for (int8_t i = 0; i < blueLedPinsCount; i++) {            //Turn off LEDs the fancy way
    digitalWrite(blueLedPins[i], LOW);                         
    delay(speed);  
     blueIndex = 0;                                            // blue index back to 0
  }
  }
  }



`

Good to hear it works!

There are on line C++ courses - you should follow one

1. Open the following blank sketch (without any instructions/codes) in the IDE.

void setup()
{

}

void loop()
{

}

2. Remember that a task that will be excuted only once will be within setup() function. For example:
Showing Hello! on Serial Monitor.

3. Remember that a task will be executed for a definite number of times will be within the setup() function. For example:
Showing Forum three time on Serial Monitor.

4. Remember that a task that will executed again and again will be within loop() function. For example:
Acquiring temperature signal from LM35 sensor and keep showing it on Serial Monitor at 1-sec interval.

5. A Program has the following components:
(1) Variable declaration (name of the variable with its size: 8 bit or 16 bit).
(2) Variable definition (value of the varaible: 0 to 255 will fit in 8-bit).
(3) Variable pocessing (adding two 8-bit variables/numbers: 25 and 37).
(4) Showing result on dsiplay unit (72 will appear on Serial Monitor).

6. Convert the tasks of Step-5 into executable codes using C++ language.The end of C++ code/statement is marked by semicolon (;).
(1) Variable declarartion

byte y1;  //y1 is variable name/identifier, byte is called "data type" = 8-bit size of y1
byte y2;

(2) Variable definition

y1 = 25;
y2 = 37;

(3) Variable processing
byte sum = y1 + y2; // + is called add operator, = is called assigment operator

(4) Show result
Seriial.print(sum, DEC); //DEC (decimal base) stands for base 10.

7. When the statements of Step-6 are inserted in the blank sketch of Step-1, we get the following:

void setup()
{
  Serial.begin(9600);  //this function allows sending result to the Serial Monitor

  byte y1;
  byte y2;

  y1 = 25;
  y2 = 37;

  byte sum = y1 + y2;

  Serial.print(sum, DEC);
}

void loop()
{

}

8. Compile and Upload the sketch of Step-7 in Arduino UNO. Observe that the Serial Monitor shows: 72.

9. Accept the sketch of Step-7 as a Building Block/Module and use it to create increasingly harder sketches/problems. For example:

Add a button with Arduino UNO and the given two numbers (-25 and +37) will be multiplied when the button is found closed. The negative result (-925 in decimal) will be showed on Serial Monitor.

10. There are many many online tutorials as mentioned in post #11 and post #13 @J-M-L. Find one tutoril that you like and practice its lessons regularly. There are also Examples in the IDE for practicing.

Hello mckinleyjohn

You can use the examples provided by the IDE to get started.
Play around with the examples, the compiler will help you get it right and find the syntax errors. You have to find and correct the logic errors in the program yourself.
These examples are known to the forum members and so a quick and easy help can be created for you.

This reading is a good textbook to get "online" with C++.

https://www.learncpp.com/

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.