RGB/Edge Detection Help

I am relativity new to the world of digital electronics. I am trying to learn as fast as possible because I am about to be teaching it to High School Kids in a little more than a month. I am working on a project to use a push button to switch between multiple RGB LED Strip programs. I have pulled the majority of the code from different places as you will see in the notes. I had the Edge detection working great with a simple LED hooked up to pin 13, I was able to get it to flash at different rates, stay on, and then turn off. I can also get the RGB codes to work on their own. When I inserted the RGB code into the Edge Detection program it gets stuck in the first program. The button detection program does not recognize the push button after the first press. I have been messing with the program for hours now but I can not figure out what I am doing wrong. Please help me determine the problem.

Thanks,
Brian

/*
  Using a push button to switch between 3 differnt RGB Codes and turning the system off.
  
  This code is compiled from two sources.  First the edge detection program was written by Tom Igoe and can be found at http://arduino.cc/en/Tutorial/ButtonStateChange  
  Secondly, the RGB color code is found at http://www.ladyada.net/products/rgbledstrip/.  The Schemetic can be found there as well.
    
 The circuit:
 * pushbutton attached to pin 2 from +5V
 * 10K resistor attached to pin 2 from ground
 * LED attached from pin 13 to ground (or use the built-in LED on
   most Arduino boards)
 * 3 STP16NF06 MOSFETs are used.
   * MOSFET 1(Green) G-Digital Pin6  D-Green Input on RGB Strip S-Ground
   * MOSFET 2(Red)   G-Digital Pin5  D-Red Input on RGB Strip S-Ground
   * MOSFET 3(Blue)  G-Digital Pin3  D-Blue Input on RGB Strip S-Ground
  *LED Strip 12v source is attached to the 9v Arduino Supply

 
 */

// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED is attached to

#define REDPIN 5
#define GREENPIN 6
#define BLUEPIN 3
int r, g, b;
 
#define FADESPEED 5     // make this higher to slow down
// Variables will change:
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() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
   pinMode(REDPIN, OUTPUT);
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, 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
      // wend 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
      // wend from on to off:
      Serial.println("off"); 
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

  
//off
  if (buttonPushCounter == 0) {
    digitalWrite(ledPin, LOW);
  }
  //color fade
  if (buttonPushCounter==1){
    
 
  // fade from blue to violet
  for (r = 0; r < 256; r++) { 
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  } 
  // fade from violet to red
  for (b = 255; b > 0; b--) { 
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  } 
  // fade from red to yellow
  for (g = 0; g < 256; g++) { 
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  } 
  // fade from yellow to green
  for (r = 255; r > 0; r--) { 
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  } 
  // fade from green to teal
  for (b = 0; b < 256; b++) { 
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  } 
  // fade from teal to blue
  for (g = 255; g > 0; g--) { 
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  }
  
  //Pink to Orange Strobe
  if (buttonPushCounter==2){
{
  
  //pink
  analogWrite(REDPIN, 255);
  analogWrite(BLUEPIN, 80);
  analogWrite(GREENPIN,15);
  delay(250);

  //orange
  analogWrite(REDPIN, 255);
  analogWrite(BLUEPIN, 0);
  analogWrite(GREENPIN,35);
 delay(250);
  
}
 }
 }
  if (buttonPushCounter==3){
    //white-on
  analogWrite(REDPIN, 255);
  analogWrite(BLUEPIN, 255);
  analogWrite(GREENPIN,255);
  delay(100);

  //off
  analogWrite(REDPIN, 0);
  analogWrite(BLUEPIN, 0);
  analogWrite(GREENPIN,0);
 delay(100);
    
  }
    
 

  if (buttonPushCounter==4){
      analogWrite(REDPIN, 0);
      analogWrite(BLUEPIN, 0);
      analogWrite(GREENPIN,0);;
    buttonPushCounter = 0;
    
  }

  
  
}

What do the debug prints tell you (and us)?

AWOL: What do the debug prints tell you (and us)?

I don't get any error in the debug area. The program loads fine. When I turn Serial Monitor on and press the push button it starts the program and registers that the button has been pressed (in the serial monitor.) When I let the push button go the serial monitor should read "off" but it does not. If I run the attached code it works fine.

/*
  State change detection (edge detection)
    
 Often, you don't need to know the state of a digital input all the time,
 but you just need to know when the input changes from one state to another.
 For example, you want to know when a button goes from OFF to ON.  This is called
 state change detection, or edge detection.

 This example shows how to detect when a button or button changes from off to on
 and on to off.
    
 The circuit:
 * pushbutton attached to pin 2 from +5V
 * 10K resistor attached to pin 2 from ground
 * LED attached from pin 13 to ground (or use the built-in LED on
   most Arduino boards)

 created  27 Sep 2005
 modified 30 Aug 2011
 by Tom Igoe

This example code is in the public domain.
    
 http://arduino.cc/en/Tutorial/ButtonStateChange

 */

// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
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() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


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
      // wend 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
      // wend from on to off:
      Serial.println("off"); 
    }
  }
  // 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 == 0) {
    digitalWrite(ledPin, LOW);
  }
  if (buttonPushCounter==1){
    digitalWrite(ledPin, HIGH);
  }
  if (buttonPushCounter==2){
    digitalWrite(ledPin, HIGH);
   delay (100);
   digitalWrite (ledPin,LOW);
   delay(200);
   loop;
  }
  if (buttonPushCounter==3){
    digitalWrite (ledPin,LOW);
    buttonPushCounter = 0;}

   
   
  
  
}

You have lots of serial debug prints in that sketch.
What do they tell you, and us?
Hint: post the output from the serial monitor.

AWOL: You have lots of serial debug prints in that sketch. What do they tell you, and us? Hint: post the output from the serial monitor.

OK. If I am running the edge detection by itself this is what I get in the serial monitor.

" on number of button pushes: 1 off on number of button pushes: 2 off on number of button pushes: 3 off on number of button pushes: 1 off "

If I run the serial monitor with the RGB Code this is what I get... " on number of button pushes: 1 "

So that is telling me that once the Color Swirl program starts running the Arduino stops checking Digital I/O 2. So how can I make the microcontroller check the IO again?

After hitting the button the first time, are you waiting for all the fading to occur before you expect to see "off"? The way your program is written, all of your fades will have to occur before the buttonPin is read again. ie. gets back to the start of the loop) If you expect to be able to let go of the button and instantly the serial displays "off", then you will need to change your program completely.

carlito: After hitting the button the first time, are you waiting for all the fading to occur before you expect to see "off"? The way your program is written, all of your fades will have to occur before the buttonPin is read again. ie. gets back to the start of the loop) If you expect to be able to let go of the button and instantly the serial displays "off", then you will need to change your program completely.

Ok that makes since. Can the Arduino run two parts of a program simultaneously? If so do you know of a good example?

Can the Arduino run two parts of a program simultaneously?

No, it can't. It can only execute one statement at a time.

   loop;

What do you think this is doing? It is NOT calling loop(), which is a good thing, as loop() should NEVER call loop().

There are a couple of ways that spring to mind to achieve what you want. One dirty way is simply to scatter reads of the button through the rest of your code & break out of your fading loops if it's changed again - not recommended. The other way is to use a state variable to keep track of what led function you're performing and do the next step of it each time round the loop if it is time. That way you're using millis to tell you when next to act and checking the button very frequently. Search for state machine in the forums to find examples. You have the classic issue that your use of delay is making your code unresponsive to inputs. Therefore, look at the blink without delay example - it'll show you how to use millis.

Your application will be a little complex to build as your first state machine - consider just making it flip between two or three states - your fades would be fine. Just remember that while you're fading, you change r (for example) by one each time it's time to do so so it will only change zero or one times on each iteration of loop.

Finally, you have some braces misplaced in your code that mean that the pink orange strobe will never happen - the check for buttonPushCounter==2 is inside the check for buttonPushCounter==1, so it can't be true. Consider putting some of this code into their own functions to shorten loop and make such things easier to see.

Ash4004: I am relativity new to the world of digital electronics. I am trying to learn as fast as possible because I am about to be teaching it to High School Kids in a little more than a month.

That sounds pretty extraordinary. If you don't know the subject yourself, then how can you be qualified to teach it?

I am trying to update my code to include State Variables. I am trying to change the way it works slightly. I want to push the button between 1 and 3 times within 2000ms to select different LED programs. After the 2000ms has past I want the push button to turn the system off if it is pushed again. It Compiles and loads, but the Serial Monitor repeats One push… example

on
number of button pushes: 1
on
number of button pushes: 1
on
number of button pushes: 1
on
number of button pushes: 1

Here is the code.

const int ledPin=11;
const int pushButton=2;

//variable

int ledState=LOW;
long previousMillis=0; //will store the lasttime the Button was pushed
long interval=2000;
int pushCounter = 0;
int buttonState= 0;
int lastButtonState=0;

void setup(){
  pinMode (ledPin, OUTPUT);
  pinMode (pushButton, INPUT);
  pinMode (pushButton, 0);
  Serial.begin(9600);
  
}


void loop ()

{

   buttonState=digitalRead (pushButton);
   unsigned long currentMillis=millis();
    if (buttonState!= lastButtonState  &&  currentMillis-previousMillis<interval) 
      {
        if (buttonState == HIGH)//pushbuttion went from off to on
       { 
          previousMillis=currentMillis; //reset previousMillis
          pushCounter++; //increase counter
          Serial.println ("on");
          Serial.print("number of button pushes: ");
          Serial.println(pushCounter);
       }
       else {
         Serial.println("off");
       }
      if (pushCounter ==1)  //fade w/o delay
      {
       for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);          
    } 

  // fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);         
                            
    }
    }

        
      if (pushCounter ==2) //slow blink (1000ms)
     
         {
     
        int ledState = LOW;                 // ledState used to set the LED
        long previousSlowMillis = 0;        // will store last time LED was updated
        long slowInterval = 1000;           // interval at which to blink (milliseconds)
        
        unsigned long currentMillis = millis();
 
  if(currentMillis - previousSlowMillis > slowInterval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
         }   
      if (pushCounter ==3) //fast blink (100ms)
       {
     
        int ledState = LOW;             // ledState used to set the LED
        long previousFastMillis = 0;        // will store last time LED was updated
        long fastInterval = 100;           // interval at which to blink (milliseconds)
        
        unsigned long currentMillis = millis();
 
  if(currentMillis - previousFastMillis > fastInterval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
       }
  if (pushCounter=4)
  {
    pushCounter=0;
   }
      }

            
 if (buttonState!= lastButtonState && currentMillis-previousMillis>interval)
      {
          digitalWrite(ledPin, LOW);
          pushCounter=0;
      
       }
      }

How have you got the button wired up? It is not floating is it, from your comments it sounds like it. This bit in setup()

  pinMode (pushButton, INPUT);
  pinMode (pushButton, 0);

What do you think the second statement is doing?

  pinMode (pushButton, INPUT);
  pinMode (pushButton, 0);

What do you think the second statement is doing?

I have a pull down button connected to IO 2. I have The pushbutton at 0 to tell the program that it is off. Now that I think of it more though, the pull down is sending 0v. So it already knows that it is off.

The second pinMode call is wrong it should be removed.

If the button is pulling down then you need either a pull up resistor or you need to enable the internal pull up. I don't see this being enabled in your code.