changing led interval using one push button

Hello,

I'm a beginner in arduino and also in programming.

I'm trying to make 3 different led's blinking in 3 different intervals, each change when I push down a pushbutton using digitalRead.
In addition, I would like to return a random number each time the button is pushed.

Here is my code. It's based on another code I found on a different post on this forum.

/*This program is based on
*
* "Blink Multiple LEDs without Delay"
*
* which is a program I found on the arduino forum.
*
* It is basically a program that turns on and off several LEDs connected 
* to a digital pin, without using the delay() function.  This means that 
* other code can run at the same time without being interrupted by the 
* LED code.
* I added some lines in order to have arduino read an input from pin 2 and
* return a randome value, and assign some values based on that returned 
* value.
*/
int led1 = 13;                // LED connected to digital pin 13
int led2 = 12;                // LED connected to digital pin 12
int led3 = 11;                // LED connected to digital pin 11
int value1 = LOW;                // previous value of the LED
int value2 = LOW;                // previous value of the LED
int value3 = LOW;               // previous value of the LED
long time1 = millis();
long time2 = millis();
long time3 = millis();

long selectGroup1;
long selectGroup2;
long selectGroup3;

//group 1 of intervals at which to blink (milliseconds)
long interval1 = 50;           
long interval2 = 60;
long interval3 = 70;

//group 2 of intervals at which to blink (milliseconds)
long interval4 = 500;          
long interval5 = 600;
long interval6 = 700;

//group 3 of intervals at which to blink (milliseconds)

long interval7 = 5000;          
long interval8 = 6000;
long interval9 = 7000;

long rndNum;                  //stores the value of the returned random number

void setup()
{
  pinMode(2, INPUT);           // sets the digital pin as input
  
  pinMode(led1, OUTPUT);      // sets the digital pins as outputs
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop()
{
 
//retruns random number when HIGH 
  if (digitalRead(2) == HIGH){
    
     rndNum = random(1, 4);
     
  } else if (digitalRead(2) == LOW){
    
  rndNum = 1;
  
  }
  
 //choose the interval group based on the random number
  if (rndNum == 1){
    
    selectGroup1 = interval1;
    selectGroup2 = interval2;
    selectGroup3 = interval3;
    
  } else if (rndNum == 2){
    
    selectGroup1 = interval4;
    selectGroup2 = interval5;
    selectGroup3 = interval6;
    
  } else if (rndNum == 3) {
    
    selectGroup1 = interval7;
    selectGroup2 = interval8;
    selectGroup3 = interval9;
  }
  
  unsigned long m = millis();
  
//Interval for LED1

  if (m - time1 >  selectGroup1){
    time1 = m;

    if (value1 == LOW)
      value1 = HIGH;
    else
      value1 = LOW;

    digitalWrite(led1, value1);
  }
  

//Interval for LED2

  if (m - time2 > selectGroup2){
    time2 = m;

    if (value2 == LOW)
      value2 = HIGH;
    else
      value2 = LOW;

    digitalWrite(led2, value2);
  }

//Interval for LED3
  
  if (m - time3 > selectGroup3){
    time3 = m;

    if (value3 == LOW)
      value3 = HIGH;
    else
      value3 = LOW;

    digitalWrite(led3, value3);
  }
  
}

The problem I'm having is, that I want it to detect if the button is pushed, and if it is, I want it to assign a group of values to the selectGroup longs, and if it isn't, keep running on the previous values.
I understand that in my current code, my arduino will check if the button is on HIGH or LOW and re-assign the group of values each time the loop comes back to the beginning.

I simply just need the arduino to re-assign the values only when I push the button, and when I don't push the button, I want the arduino to continue the loop.

It would really be a lot of help if I could solve this problem.

Best,

mkto

You need to store the last value read, then only do new things when the last value was low and this one is high. This indicate a button transition, rather than the button being held down.

Thanks arduinodlb.

I got it working.

You need to store the last value read, then only do new things when the last value was low and this one is high.

So, if I do this in the program, I guess it will be something like my code below.
What I did was:

  • Add an int preveousButtonState, give it an initial value of LOW,
  • Changed the

if (digitalRead(2) == HIGH){

rndNum = random(1, 4);

} else if (digitalRead(2) == LOW){

rndNum = 1;

}

to

if (digitalRead(2) == HIGH && preveousButtonState == LOW){

rndNum = random(1, 4);
preveousButtonState = HIGH;

} else if (digitalRead(2) == LOW && preveousButtonState == HIGH){

preveousButtonState = LOW;

}

/*This program is based on
*
* "Blink Multiple LEDs without Delay"
*
* which is a program I found on this forum
*
* It is basically a program that turns on and off several LEDs connected 
* to a digital pin, without using the delay() function.  This means that 
* other code can run at the same time without being interrupted by the 
* LED code.
* I added some lines in order to have arduino read an input from pin 2 and
* return a randome value, and assign some values based on that returned 
* value.
*/
int led1 = 13;                // LED connected to digital pin 13
int led2 = 12;                // LED connected to digital pin 12
int led3 = 11;                // LED connected to digital pin 11
int value1 = LOW;                // previous value of the LED
int value2 = LOW;                // previous value of the LED
int value3 = LOW;               // previous value of the LED
long time1 = millis();
long time2 = millis();
long time3 = millis();

long selectGroup1;
long selectGroup2;
long selectGroup3;

//group 1 of intervals at which to blink (milliseconds)
long interval1 = 50;           
long interval2 = 60;
long interval3 = 70;

//group 2 of intervals at which to blink (milliseconds)
long interval4 = 200;          
long interval5 = 250;
long interval6 = 300;

//group 3 of intervals at which to blink (milliseconds)

long interval7 = 500;          
long interval8 = 550;
long interval9 = 600;

long rndNum = 3;                  //stores the value of the returned random number

int preveousButtonState = LOW;      //sets the button's preveous state

void setup()
{
  pinMode(2, INPUT);           // sets the digital pin as input
  
  pinMode(led1, OUTPUT);      // sets the digital pins as outputs
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

void loop()
{
 
//retruns random number when HIGH 
  if (digitalRead(2) == HIGH && preveousButtonState == LOW){
    
     rndNum = random(1, 4);
     preveousButtonState = HIGH;
     
  } else if (digitalRead(2) == LOW && preveousButtonState == HIGH){
    
  preveousButtonState = LOW;
  
  }
  
 //choose the interval group based on the random number
  if (rndNum == 1){
    
    selectGroup1 = interval1;
    selectGroup2 = interval2;
    selectGroup3 = interval3;
    
  } else if (rndNum == 2){
    
    selectGroup1 = interval4;
    selectGroup2 = interval5;
    selectGroup3 = interval6;
    
  } else if (rndNum == 3) {
    
    selectGroup1 = interval7;
    selectGroup2 = interval8;
    selectGroup3 = interval9;
  }
  
  unsigned long m = millis();
  
//Interval for LED1

  if (m - time1 >  selectGroup1){
    time1 = m;

    if (value1 == LOW)
      value1 = HIGH;
    else
      value1 = LOW;

    digitalWrite(led1, value1);
  }
  

//Interval for LED2

  if (m - time2 > selectGroup2){
    time2 = m;

    if (value2 == LOW)
      value2 = HIGH;
    else
      value2 = LOW;

    digitalWrite(led2, value2);
  }

//Interval for LED3
  
  if (m - time3 > selectGroup3){
    time3 = m;

    if (value3 == LOW)
      value3 = HIGH;
    else
      value3 = LOW;

    digitalWrite(led3, value3);
  }
  
}

That looks like the sort of thing you'd need to do, yep. Glad you got it working.