Create Targets with LEDs and Push Buttons

Hello everyone !

I started to learn how Arduino works some weeks ago and I'm stuck in the writing of my program. I have six LEDs and six push buttons for each of them. My goal is that a LED lights up randomly and when you press the push button associated with this LED, it turns off. Then, when you stop holding the press button another LED lights up randomly as well. Then, you press the push button associated with the LED and it turns off. Then, when we stop holding the puss button, another LED lights up randomly and so on. I need this kind of program to create targets for trainings of karate. When a LED turn on randomly, you press the button and then this one will turn off and a new one will turn on. The program I have right now can turn on a LED randomly but when we press the push button, we need to press it for at least five seconds (because this is the delay I put) before it changes of LED but it needs to change right when we press the push button. Can someone help me please ?

PS : English is not my mother tongue so maybe some mistakes are in this text :wink:

Thank you !

Here's my program :

int randomNumber;

void setup() {
// put your setup code here, to run once:

Serial.begin (9600);

Serial.println("Start a new sequence of Random Number");

pinMode (8, OUTPUT);
pinMode (9, OUTPUT);
pinMode (10, OUTPUT);
pinMode (11, OUTPUT);
pinMode (12, OUTPUT);
pinMode (13, OUTPUT);

pinMode (7, INPUT_PULLUP);

randomSeed( analogRead(0) );

}

void loop() {
// put your main code here, to run repeatedly:

int n = 1;
int k = 5;
int a = 5;

for(n = 1; n < 2; n++)

{

digitalWrite (8, HIGH);
digitalWrite (9, HIGH);
digitalWrite (10, HIGH);
digitalWrite (11, HIGH);
digitalWrite (12, HIGH);
digitalWrite (13, HIGH);

delay(750);

digitalWrite (8, LOW);
digitalWrite (9, LOW);
digitalWrite (10, LOW);
digitalWrite (11, LOW);
digitalWrite (12, LOW);
digitalWrite (13, LOW);

delay(750);

}

while(k == a)

{

randomNumber = random(8,14);

Serial.print("The Random Number is");
Serial.println(randomNumber);

int pusshedA = digitalRead(7);

if(pusshedA == HIGH){

digitalWrite(randomNumber, HIGH);
delay(5000);

}else{

digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
digitalWrite(13, LOW);

}

}

}

Programme_Audrey_3.ino (1.56 KB)

You need to post your code with code tags </>.

The 'delay' function stops your sketch doing anything for the duration of the delay, so you want to get rid of them in this application. See how this is done by looking at the Blink Without Delay tutorial;

If this is for karate training your switches are going to need to be pretty robust.

Thank you very much for helping me ! The result of my program progressed a lot without using the function delay. The only small problem is that if we don't press the push button right away, then, the other LEDs turn on and then many LEDs lights up at the same time. For the targets, it would be better if one LED lights up and before a new one lights up, we need to press the push button. I can still increase the delay for the "const long interval" but the delay after we pressed the push button is also longer so the time before another LED lights up is also longer. Do you have some tips for me ? It would be very appreciated !

Thank you !

This is my program with the modifications :

<

int randomNumber;

const int ledPin = LED_BUILTIN;

int ledState = HIGH;

unsigned long previousMillis = 0;

const long interval = 750;

void setup() {
// put your setup code here, to run once:

Serial.begin (9600);

Serial.println("Start a new sequence of Random Number");

pinMode (8, OUTPUT);
pinMode (9, OUTPUT);
pinMode (10, OUTPUT);
pinMode (11, OUTPUT);
pinMode (12, OUTPUT);
pinMode (13, OUTPUT);

pinMode (7, INPUT_PULLUP);

randomSeed( analogRead(0) );

}

void loop() {
// put your main code here, to run repeatedly:

int n = 1;
int k = 5;
int a = 5;

for(n = 1; n < 4; n++)

{

digitalWrite (8, HIGH);
digitalWrite (9, HIGH);
digitalWrite (10, HIGH);
digitalWrite (11, HIGH);
digitalWrite (12, HIGH);
digitalWrite (13, HIGH);

delay(350);

digitalWrite (8, LOW);
digitalWrite (9, LOW);
digitalWrite (10, LOW);
digitalWrite (11, LOW);
digitalWrite (12, LOW);
digitalWrite (13, LOW);

delay(350);

}

while(k == a)

{

randomNumber = random(8,14);

Serial.print("The Random Number is");
Serial.println(randomNumber);

int pusshedA = digitalRead (7);

if(pusshedA == HIGH){

unsigned long currentMillis = millis();

if(currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;

// set the LED with the ledState of the variable:
digitalWrite(randomNumber, ledState);

}

}else{

digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
digitalWrite(13, LOW);

}
}

}

Please use code tags, as clearly described in the forum sticky. That also gives you more idea on the info you have to provide to get help.

You originally said that "My goal is that a LED lights up randomly and when you press the push button associated with this LED, it turns off. Then, when you stop holding the press button another LED lights up randomly as well".

If you think about it you don't need to use time at all for what you have described;

Turn a random LED on.
Wait until the switch for that LED is pressed
Turn the LED off.
Wait until the switch for that LED is released
Repeat.

In the above "Wait" has nothing to do with time, your sketch just sits in a while loop looking at the input from the switch.

If you want to the LEDs to turn on and off even the user has not hit the switch then you need to use the time obtained from millis() , but you would not use delay() at all.

Hi ! I tried to extract the millis() as you told me, but it doesn't work. I understand that I shouldn't use any function to control the time but I don't know how one LED can lights up and stay like that until we press the push button. I would like to know if you could help me directly with my program ? How would you modify the void loop part so it can work like I want ?

Thank you !

That's the code I have right now... with the function millis(), but if we wait too much time, the other LED lights up even if we did not press the push button.

int randomNumber;

const int ledPin = LED_BUILTIN;

int ledState = HIGH;

unsigned long previousMillis = 0;

const long interval = 750;


void setup() {
  // put your setup code here, to run once:

 Serial.begin (9600);

 Serial.println("Start a new sequence of Random Number");

 pinMode (8, OUTPUT);
 pinMode (9, OUTPUT);
 pinMode (10, OUTPUT);
 pinMode (11, OUTPUT);
 pinMode (12, OUTPUT);
 pinMode (13, OUTPUT);

 
 pinMode (7, INPUT_PULLUP);

 randomSeed( analogRead(0) );

  }

void loop() {
  // put your main code here, to run repeatedly:

  int n = 1;
  int k = 5;
  int a = 5;

for(n = 1; n < 4; n++)

  {

  digitalWrite (8, HIGH);
  digitalWrite (9, HIGH);
  digitalWrite (10, HIGH);
  digitalWrite (11, HIGH);
  digitalWrite (12, HIGH);
  digitalWrite (13, HIGH); 

  delay(350);

  digitalWrite (8, LOW);
  digitalWrite (9, LOW);
  digitalWrite (10, LOW);
  digitalWrite (11, LOW);
  digitalWrite (12, LOW);
  digitalWrite (13, LOW);

 delay(350);

  }

 
  
 while(k == a)

  {

randomNumber = random(8,14);

Serial.print("The Random Number is");
Serial.println(randomNumber);

int pusshedA = digitalRead (7);


if(pusshedA == HIGH){

  unsigned long currentMillis = millis();
  
  if(currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // set the LED with the ledState of the variable:
    digitalWrite(randomNumber, ledState);
  
  }

}else{

  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);

}
}
  
}

Those two delay(350) calls are almost certainly a major problem. It seems you're blinking all your LEDs four times before doing something else, right?

Also please format your code properly (use the IDEs autoformat function to help you out) so it's readable. Now it's too hard to follow. Also please describe in detail what your program does and how this is different from what you want it to do.

If it comes to key events, I like to use the small Bounce2 library that makes it very easy.

#include <Bounce2.h>

const uint8_t keyPins[] = { 37, 36, 35, 34, 33, 32 };
const uint8_t ledPins[] = { 49, 48, 47, 46, 45, 44 };

Bounce key[sizeof(keyPins)];

uint8_t currentTarget;

void setup() {
  for (uint8_t x : ledPins) {
    pinMode(x, OUTPUT);
  }
  uint8_t i = 0;
  for (auto& k : key) {
    k.attach(keyPins[i++], INPUT_PULLUP);
  }
  currentTarget = random(sizeof(keyPins));
  digitalWrite(ledPins[currentTarget], HIGH);
}

void loop() {
  for (auto& k : key) {
    k.update();
  }
  if (key[currentTarget].fell()) {
    digitalWrite(ledPins[currentTarget], LOW);
  }
  if (key[currentTarget].rose()) {
    currentTarget = random(sizeof(keyPins));
    digitalWrite(ledPins[currentTarget], HIGH);
  }
}

If the buttons are to be in targets that get hit, look into piezo disks like those used as acoustic instrument audio pickups. They get used for door knock sensor projects.