Starting and Stopping Loop with Pushbutton

This is assuredly super basic.
I know that there are several topics related to this and I've tried the info in them and am not getting my code to work the way I want. I am almost completely new to programming and electronics in general.

I'm trying to merge the concepts from the following two posts:

Button to start/stop program - General Electronics - Arduino Forum (Specifically the code from response #3 by wes000000)

Currently, when I load or reset the program the LEDs don't blink until I push my button. This is exactly what I intended. They begin blinking randomly when I press the button which is also as intended. However, an additional press of the button does not stop the blinking.

I'm hoping this is an easy fix. I am really struggling to get my head around IF statements.

Thanks in advance!

// LED Fire Effect

int ledPin1 = 10;
int ledPin2 = 9;
int ledPin3 = 11;
int ledPin4 = 3;
int ledPin5 = 5;
int ledPin6 = 6;
int run;
int buttonPin;

void setup()
{
run = 0; //starts stopped
buttonPin = 2; //whatever pin your button is plugged into

pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);
pinMode(ledPin6, OUTPUT);
}

void loop() {

  if(digitalRead(buttonPin) == LOW) //funcitons based off of button pulling input pin LOW
  {
     if(run == 0)
     {
         run = 255;
     }
     else
     {
         run = 0;
     }
  }

  if(run > 0)
  {
    analogWrite(ledPin1, random(225)+30);
analogWrite(ledPin2, random(225)+30);
analogWrite(ledPin3, random(225)+30);
analogWrite(ledPin4, random(225)+30);
analogWrite(ledPin5, random(225)+30);
analogWrite(ledPin6, random(225)+30);
delay(random(100)); 
//code you only run if button was pressed, stops running when button pressed again, so forth...
  }
}

Or perhaps they do stop flashing but only for a very very short time. Then the next time round the loop the button is still pressed so on they go again.

Ideally you want to work on the button becoming pressed rather than being pressed.

Steve

However, an additional press of the button does not stop the blinking.

Never? Or does it work occasionally?

If it works sometimes, you may need to detect the button becoming pressed, as slipstick suggests, and also debounce your button.

PaulRB:
Never? Or does it work occasionally?

If it works sometimes, you may need to detect the button becoming pressed, as slipstick suggests, and also debounce your button.

As far as I can tell, it never works. A short press produces no visible change and neither does a long press.

slipstick:
Or perhaps they do stop flashing but only for a very very short time. Then the next time round the loop the button is still pressed so on they go again.

Ideally you want to work on the button becoming pressed rather than being pressed.

Steve

I think I understand conceptually what you are getting at. Since I am dealing with something that works at PWM speeds, so fast that I can't notice the shifts, I may be starting and stopping the program so quickly that I can't notice that the program is functioning as intended. Can you elaborate on how I could potential make the the button "become" depressed?

What you, as a human, consider a short press or a long press, are both very long indeed to an Arduino! Your "short" press is probably around 100ms. During that time the Arduino will have checked the button at least a thousand times.

You make the button "become depressed" with your finger. What you need to get the code to do is detect when the button first becomes depressed, not simply whether it is depressed or not at the point in time that it performs the check. In other words you need to spot the moment when the button changes from not being depressed to being depressed. One of the basic Arduino tutorials covers this. I think it is called the "state change" tutorial.

PaulRB:
You make the button "become depressed" with your finger. What you need to get the code to do is detect when the button first becomes depressed, not simply whether it is depressed or not at the point in time that it performs the check. In other words you need to spot the moment when the button changes from not being depressed to being depressed. One of the basic Arduino tutorials covers this. I think it is called the "state change" tutorial.

I think I am getting closer. I found the tutorial you mentioned and merged my codes again. Now I have something that works very closely to what I had envisioned. Upon resetting I have no LEDs on. One button press begins the random blinking and an additional press will leave the LEDs on. I can then alternate between blinking and on forever. I think that my problem is that I don't have anything defined in the "else" section at the bottom of the code. I tried defining a "Low" state for each LED after the else but got error messages.

Thanks again!

const int  buttonPin = 2;
int ledPin1 = 10;
int ledPin2 = 9;
int ledPin3 = 11;
int ledPin4 = 3;
int ledPin5 = 5;
int ledPin6 = 6;
int run;

int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  // put your setup code here, to run once:
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);
pinMode(ledPin6, OUTPUT);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;


  // turns on the LED every four button pushes by checking the modulo of the
  // button push counter. the modulo function gives you the remainder of the
  // division of two numbers:
  if (buttonPushCounter % 2 == 0) {
    analogWrite(ledPin1, random(225)+30);
analogWrite(ledPin2, random(225)+30);
analogWrite(ledPin3, random(225)+30);
analogWrite(ledPin4, random(225)+30);
analogWrite(ledPin5, random(225)+30);
analogWrite(ledPin6, random(225)+30);
delay(random(100));
  } else {

  }

}

Well done, almost there...

So... some code you haven't shared with us gives some error messages you haven't shared with us?

PaulRB:
So... some code you haven't shared with us gives some error messages you haven't shared with us?

Oops.

const int  buttonPin = 2;
int ledPin1 = 10;
int ledPin2 = 9;
int ledPin3 = 11;
int ledPin4 = 3;
int ledPin5 = 5;
int ledPin6 = 6;
int run;

int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  // put your setup code here, to run once:
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);
pinMode(ledPin6, OUTPUT);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;


  // turns on the LED every four button pushes by checking the modulo of the
  // button push counter. the modulo function gives you the remainder of the
  // division of two numbers:
  if (buttonPushCounter % 2 == 0) {
    analogWrite(ledPin1, random(225)+30);
analogWrite(ledPin2, random(225)+30);
analogWrite(ledPin3, random(225)+30);
analogWrite(ledPin4, random(225)+30);
analogWrite(ledPin5, random(225)+30);
analogWrite(ledPin6, random(225)+30);
delay(random(100));
  } else {
analogWrite(ledPin1, low);
analogWrite(ledPin2, low);
analogWrite(ledPin3, low);
analogWrite(ledPin4, low);
analogWrite(ledPin5, low);
analogWrite(ledPin6, low);
  }

}
/Users/West/Documents/Arduino/Fire_Effect_2/Fire_Effect_2.ino: In function 'void loop()':
Fire_Effect_2:61: error: 'low' was not declared in this scope
 analogWrite(ledPin1, low);
                      ^
exit status 1
'low' was not declared in this scope

Capitalization counts in C++.

C++ is case sensitive. In other words, uppercase and lowercase letters are considered to be different. A variable named low is different from Low, which is different from LOW. LOW is defined, the other variations are not.

low is not the same as LOW

What he said. Plus, HIGH and LOW are for digitalWrite(), not really for analogWrite() which expects a number between 0 and 255. But it so happens that LOW is equivalent to 0, so LOW will also work. It would be more correct to use 0.

Well I feel dumb. That totally fixed it. The first thing I said in this thread was that this was going to super basic. Everything is working the way I wanted it to. Thanks to everyone who wasted part of their Sunday helping me figure this out!