Help with sequential LED push button and potentiometer

Hi, I have just started using Arduino and want to make a project. This project involves 4 LED's which light up sequentially and using a potentiometer to define the speed with which the LED's turn on and off one by one. Now I want the pushbutton for beginning and stopping of the loop at the LED whose turn it is. But my pushbutton is acting as a push and release instead of a toggle. What changes should I apply to the code so that the pushbutton acts as toggle instead of push and release.
The code is;

#define LED_1_PIN 13
#define LED_2_PIN 12
#define LED_3_PIN 11
#define LED_4_PIN 10
#define BUTTON 2
#define LED_NUMBER 4
#define potPin A0
int val = 0;
int buttonState = 0;
int buttonPressCount = 0;
void setup() 
{
  pinMode(LED_1_PIN, OUTPUT);
  pinMode(LED_2_PIN, OUTPUT);
  pinMode(LED_3_PIN, OUTPUT);
  pinMode(LED_4_PIN, OUTPUT);
  Serial.begin(9600);

}

void loop() 
{
  int val = analogRead(0);
  val = map(val, 0, 1023, 0, 255);
  analogWrite(9, val);
  buttonState = digitalRead(BUTTON);
  if (buttonState == LOW) {
    if (buttonPressCount % LED_NUMBER == 0) {
      digitalWrite(LED_1_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_1_PIN, LOW);delay(val);
    }
    if (buttonPressCount % LED_NUMBER == 1) {
      digitalWrite(LED_2_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_2_PIN, LOW);delay(val);
    }
    if (buttonPressCount % LED_NUMBER == 2) {
      digitalWrite(LED_3_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_3_PIN, LOW);delay(val);
    }
    if (buttonPressCount % LED_NUMBER == 3) {
      digitalWrite(LED_4_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_4_PIN, LOW);delay(val);
    }
    buttonPressCount++;
    Serial.println(val);
  }
}

You need to detect when the button becomes pressed rather than when it is pressed
See the StateChangeDetection example in the IDE

I tried to implement the recommended example in my code, but now the button does not function at all. I can't understand what I did wrong, please help. Attaching the new code:

#define LED_1_PIN 13
#define LED_2_PIN 12
#define LED_3_PIN 11
#define LED_4_PIN 10
#define BUTTON 2
#define LED_NUMBER 4
#define potPin A0
int val = 0;
int buttonState = 0;
int buttonPressCount = 0;
int buttonPushCounter = 0;   
int lastButtonState = 0;
void setup() 
{
  pinMode(LED_1_PIN, OUTPUT);
  pinMode(LED_2_PIN, OUTPUT);
  pinMode(LED_3_PIN, OUTPUT);
  pinMode(LED_4_PIN, OUTPUT);
  Serial.begin(9600);

}

void loop() 
{
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      Serial.println("off");
    }
     delay(50);
  }
  lastButtonState = buttonState;
  int val = analogRead(0);
  val = map(val, 0, 1023, 0, 255);
  analogWrite(9, val);
  buttonState = digitalRead(BUTTON);
  
    if (buttonPushCounter % LED_NUMBER == 0) {
      digitalWrite(LED_1_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_1_PIN, LOW);delay(val);
    }
    if (buttonPushCounter % LED_NUMBER == 1) {
      digitalWrite(LED_2_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_2_PIN, LOW);delay(val);
    }
    if (buttonPushCounter % LED_NUMBER == 2) {
      digitalWrite(LED_3_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_3_PIN, LOW);delay(val);
    }
    if (buttonPushCounter % LED_NUMBER == 3) {
      digitalWrite(LED_4_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_4_PIN, LOW);delay(val);
    }
    buttonPushCounter++;
    Serial.println(val);
  
}
  buttonPushCounter++;

You are doing this unconditionally in loop() rather than when a change of button state is detected

So should I remove it or change the place it is written? because if I remove it the LED's are not lighting up sequentially but instead lighting after I press the button. I want them to light sequentially and when I press the button the LED to stop and when I press it again, it continues to light sequentially from where it was paused

Put it in the right place, ie when a change of state is detected. The example code shows you how

After doing it the LED's are not lighting up sequentially, but each of them is lighting after I press the button. Whereas I want that when I press the button the LED to stop and when I press it again, it continues to light sequentially from where it was paused

The code:

#define LED_1_PIN 13
#define LED_2_PIN 12
#define LED_3_PIN 11
#define LED_4_PIN 10
#define BUTTON 2
#define LED_NUMBER 4
#define potPin A0
int val = 0;
int buttonState = 0;
int buttonPressCount = 0;
int buttonPushCounter = 0;   
int lastButtonState = 0;
void setup() 
{
  pinMode(LED_1_PIN, OUTPUT);
  pinMode(LED_2_PIN, OUTPUT);
  pinMode(LED_3_PIN, OUTPUT);
  pinMode(LED_4_PIN, OUTPUT);
  Serial.begin(9600);

}

void loop() 
{
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      Serial.println("off");
    }
     delay(50);
  }
  lastButtonState = buttonState;
  int val = analogRead(0);
  val = map(val, 0, 1023, 0, 255);
  analogWrite(9, val);
  buttonState = digitalRead(BUTTON);
  
    if (buttonPushCounter % LED_NUMBER == 0) {
      digitalWrite(LED_1_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_1_PIN, LOW);delay(val);
    }
    if (buttonPushCounter % LED_NUMBER == 1) {
      digitalWrite(LED_2_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_2_PIN, LOW);delay(val);
    }
    if (buttonPushCounter % LED_NUMBER == 2) {
      digitalWrite(LED_3_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_3_PIN, LOW);delay(val);
    }
    if (buttonPushCounter % LED_NUMBER == 3) {
      digitalWrite(LED_4_PIN, HIGH);delay(val);
    }
    else
    {
      digitalWrite(LED_4_PIN, LOW);delay(val);
    }
    Serial.println(val);
  
}

As a starting point I would suggest putting the LED pin numbers in an array and using the value of buttonPushCounter as the index to the array. This will avoid the need for multiple if/else

I was able to put LED PIN numbers in an array, but can't understand how to get the function I wanted for my pushbutton.
The code is:

#define LED_NUMBER 4
#define potPin A0
#define BUTTON 2
int val = 0;
int buttonPushCounter = 0;   
int buttonState = 0;         
int lastButtonState = 0; 
void setup() 
{
  for (int thisPin = 9; thisPin < 13; thisPin++)
  pinMode(thisPin, OUTPUT);
  pinMode(BUTTON, INPUT);
  Serial.begin(9600);

}

void loop() 
{
  int val = analogRead(0);
  val = map(val, 0, 1023, 0, 255);
  
  for (int thisPin = 9; thisPin < 13; thisPin++) {		
	    digitalWrite(thisPin, HIGH);		
	    delay(val);			
	    digitalWrite(thisPin, LOW);
}
}

There is no array in the code in your reply

Sorry for that, I got a bit confused.

#define LED_NUMBER 4
#define potPin A0
#define BUTTON 2
int ledPins[] = {
  9, 12, 11, 10
};
int val = 0;
int buttonPushCounter = 0;   
int buttonState = 0;         
int lastButtonState = 0; 
void setup() 
{
  for (int thisPin = 9; thisPin < 13; thisPin++)
  pinMode(thisPin, OUTPUT);
  pinMode(BUTTON, INPUT);
  Serial.begin(9600);

}

void loop() 
{
  int val = analogRead(0);
  val = map(val, 0, 1023, 0, 255);
  
  for (int thisPin = 9; thisPin < 13; thisPin++) {		
	    digitalWrite(thisPin, HIGH);		
	    delay(val);			
	    digitalWrite(thisPin, LOW);
}
}

OK, the LED pins are in an array but you don't use it

Re-reading your original post I see that the value of buttonPressCount simply starts/stops the LED sequence rather than being an index to the LED array

Start simple with something like this

  for (int p = 0; p < 4; p++)
  {
    pinMode(ledPins[p], OUTPUT);  //the pin numbers do not need to be contiguous
  }

Later in the code, you can use the value of ButtonPressCount to control whether the for loop runs

  if (buttonPressCount % 2) //odd or even ?
  {
    int val = analogRead(0);
    val = map(val, 0, 1023, 0, 255);
    for (int p = 0; p < 4; p++)
    {
      digitalWrite(ledPins[p], HIGH);
      delay(val);
      digitalWrite(ledPins[p], LOW);
    }
  }

NOTE : this is not the best way to do this but try it first

I did try it but now the LED's won't turn on itself. I also didn't understand what you meant by odd or even? @UKHeliBob
The code:

int pinCount = 4;
#define potPin A0
#define BUTTON 2
int ledPins[] = {
  9, 12, 11, 10
};
int val = 0;
int buttonPressCount = 0;
int buttonState = 0;
void setup() 
{
  for (int p = 9; p < 13; p++)
  {
    pinMode(ledPins[p], OUTPUT);  
  }
  Serial.begin(9600);

}

void loop() 
{
  buttonState = digitalRead(BUTTON);
  if (buttonPressCount % 2) 
  {
    int val = analogRead(0);
    val = map(val, 0, 1023, 0, 255);
    for (int p = 0; p < 4; p++)
    {
      digitalWrite(ledPins[p], HIGH);
      delay(val);
      digitalWrite(ledPins[p], LOW);
    }
  }
}
  for (int p = 9; p < 13; p++)
  {
    pinMode(ledPins[p], OUTPUT);  
  }

Start by using the correct values in the pinMode() for loop. Look at my code in reply #12

After doing it but removing{ if (buttonPressCount % 2) //odd or even ? }, the code works without doing the pushbutton functionality. Kindly advise what to do after.

The code is:

#define LED_NUMBER 4
#define potPin A0
#define BUTTON 2
int ledPins[] = {
  9, 12, 11, 10
};
int val = 0;
int buttonPressCount = 0;   
int buttonState = 0;         
int lastButtonState = 0; 
void setup() 
{
   for (int p = 0; p < 4; p++)
  {
    pinMode(ledPins[p], OUTPUT);  
  }
  pinMode(BUTTON, INPUT);
  Serial.begin(9600);

}

void loop() {

    int val = analogRead(0);
    val = map(val, 0, 1023, 0, 255);
    for (int p = 0; p < 4; p++)
    {
      digitalWrite(ledPins[p], HIGH);
      delay(val);
      digitalWrite(ledPins[p], LOW);
    }
  
}

Let's deal with the code as it is first. For instance, how long will the LED pin stay LOW ?

EDIT - ignore that question

How is the button wired ? Does the pin go HIGH or LOW when you press the button ? Do you have a pullup or pulldown resistor in place to keep it in a known state at all times ?

Hi,
Can you please post a circuit diagram of your project, a hand drawn image will be fine.

As I look through each edit of your code this line appears in one and not the other;

pinMode(BUTTON, INPUT);

You must have this in all your codes for your button to be read.

As @UKHeliBob has asked, how have you wired your button?

Tom... :grinning: :+1: :coffee: :australia:

Hello
Check this IDE Example to continue.

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


Hi, this is the project I am working on. In this version the potentiometer is working and the lights are lighting up sequentially. But the pushbutton is not working. I want the pushbutton to stop the sequence, when the pushbutton is pressed once and stop at whatever light the sequence is on, and when I press the pushbutton again I want the sequence to continue. Kindly help since I am not understanding how to add the IDE example to it.

Hi,
PLEASE draw your circuit, pen(cil) and paper.
You have a mass of green wires that form a tangled mess.

Have you got some simple code that JUST tests your buttons?
Do you have a DMM?

You need to connect your tactile button like this;

Use the diagonally opposite connections, to ensure you have the switch in circuit.

Tom... :grinning: :+1: :coffee: :australia: