toggling between LED patterns

hey guys. first post. i'm an electronics (mainly music gear) repair technician by day so i know my way around hardware but when it comes to code i'm a little rusty. i'm trying to put together a test circuit for a RGB LED where it toggles through different patterns at the push of a button. heres my code thus far. i've been trying to just hammer out the communication specifics before jumping into intricate patterns and fades and such so the patterns/color schemes are really of no consequence right now-

const int redpin = 9;
const int bluepin = 10;
const int greenpin = 11;
const int switchpin = 2;   
int currentpatterncount = 1;
int newpatterncount = 1;
int redfade = 0;
int bluefade = 0;
int greenfade = 0;

void setup()                   
{
  Serial.begin(9600);           
  pinMode(switchpin, INPUT);   
  analogWrite(redpin, redfade);
  analogWrite(bluepin, bluefade);
  analogWrite(greenpin, greenfade);
}


void loop()                     
{

  if (currentpatterncount = 1){    
      //red down
      for(; redfade <= 250; redfade +=5){
        analogWrite(redpin, redfade);
        delay(5);
       }
      //blue up
      for(; bluefade >= 5; bluefade -=5){
        analogWrite(bluepin, bluefade);
        delay(5);
      }
      //blue down
      for(; bluefade <= 250; bluefade +=5){
        analogWrite(bluepin, bluefade);
        delay(5);
      }
      //green up
      for(; greenfade >= 5; greenfade -=5){
        analogWrite(greenpin, greenfade);
        delay(5);
      }
      //green down
      for(; greenfade <= 250; greenfade +=5){
        analogWrite(greenpin, greenfade);
        delay(5);
      }
  }
   if (currentpatterncount = 2){
      analogWrite(redpin, 255);
      analogWrite(greenpin, 255);
      analogWrite(bluepin, 255);
      delay(500);
      analogWrite(greenpin, 0);
      delay(500);
      analogWrite(bluepin, 0);
      analogWrite(greenpin, 100);
      analogWrite(redpin, 150);
      delay(500);
    } 

  Serial.println(currentpatterncount);
  delay(100);
  
    if (digitalRead(switchpin) == HIGH){
  newpatterncount++;
  currentpatterncount = newpatterncount;
  if (currentpatterncount > 2){
    currentpatterncount = 1;
    }
  }
  }

so far all i've gotten is it loading the script then getting stuck on pattern 2 (both in LED function and with the serial monitor) though the LED does flash Red at the VERY beginning of the arduino booting up. i'm sure this is a really n00btastic mistake but hey... thats what the internet is for right?
any help is appreciated.
looking forward to giving back to the community in my own (limited) manner.
oh and my arduino is duemilanove

Abraxas

Moderator edit: [code] [/code] tags added

   if (currentpatterncount = 2){

This is assigning 2 to currentpatterncount, not testing if it is 2.

You mean:

   if (currentpatterncount == 2){

Ditto for the other places.

      for(; redfade <= 250; redfade +=5){

That should probably be:

      for(redfade = 0; redfade <= 250; redfade +=5){

It will work the first time, but after that redfade will be 250 next time around the loop.

and once you fix what Nick Gammon told you it will get stuck on pattern one...but why???

if (digitalRead(switchpin) == HIGH){
newpatterncount++;
currentpatterncount = newpatterncount;
if (currentpatterncount > 2){
currentpatterncount = 1;
}
}

if the newPattern is grater then 2 you reset your currentPattern but you never reset you newpattern so your new pattern keeps adding up 2 ,3 ,4 ,5 ,6 and since you always set currentPattern to newPattern it will always be grater then 2 so this is what will happen
lets follow newPattern here
newPattern will be 1
then the second time around newPattern will be 2
then it will run the 3rd time and new pattern will be 3 and since 3 is grater then 2 it will set currentPattern to 1,
so when it runs the forth time newPattern will be 4 and since its greater then 2 it will set currentPattern back to 1 and keep setting it back to one since it is always greater then 2...so when you check if new pattern is > then 2 and it IS grater then 2 then rest both new and current pattern back to 1

thanks guys... i knew this was the right place to ask!

one more question (for now):
what do i need to do to make it so that no matter when the button is pressed it will change pattern? as i have it now i kinda have to hit the button at the right time but once i add more patterns i'd like to be able to toggle through them quickly without having to wait for each individual pattern to play out

Now it's time for blink without delay and a state machine - search for both in the forums. Ideally, you do away with calls to delay and make loop quick enough that a button press can be picked up instantly, or apparently so for human reaction time. Use millis and some state variables to keep track of where you are in the current pattern and when it's time to do something new. If you notice a button press, new pattern. The difficulty is that you will need some heavy restructuring of your code to do this.

wouldnt attatching an intterupt to the button also do the trick? of course removing delay functions as well

Yes, assuming you debounce it somewhere, but if you remove the delays, there would be no need.

@wildbill what do you think about using micros() in place of millis for delays? ...accurate not accurate? not necessarily in this example but in general ..

I've never had occasion to use micros or delaymicroseconds, milis has been enough for any human interaction, so what I know comes from reading the site and the forums. It's clearly crucial in some instances - the code for ultrasonic ping sensors uses delaymicroseconds. The timer doesn't actually give microsecond precision though, the micros return value is a multiple of four. Obviously it rolls over frequently (~70 minutes) but use of it with events that span the rollover are ok if your test is subtractive.

hey guys. took your advice and found the FiniteStateMachine library. reallly handy resource for this project
i went thru and updated the code and i've been playing around with it

#include <FiniteStateMachine.h>
#include <Button.h>
#include <LED.h>

const byte NUMBER_OF_STATES = 9;
long previoustime = 0; 
long interval = 1000; 

State purpleon = State(purpleledon);
State purpleoff = State(purpleledoff);
State purplefadein = State(purpleledfadein);
State purplefadeout = State(purpleledfadeout);

State redon = State(redledon);
State redoff = State(redledoff); 
State redfadein = State(redledfadein);
State redfadeout = State(redledfadeout); 

State blueon = State(blueledon);
State blueoff = State(blueledoff); 
State bluefadein = State(blueledfadein);
State bluefadeout = State(blueledfadeout); 

State greenon = State(greenledon);
State greenoff = State(greenledoff); 
State greenfadein = State(greenledfadein);
State greenfadeout = State(greenledfadeout); 

FSM redstatemachine = FSM(redoff);
FSM bluestatemachine = FSM(blueoff);
FSM greenstatemachine = FSM(greenoff);
FSM purplestatemachine = FSM(purpleoff);

Button button = Button(12,PULLUP); 
LED redled = LED(9);
LED blueled = LED(10);
LED greenled = LED(11);
byte buttonPresses = 0;          

void setup(){ 
  Serial.begin(9600);
}

void loop(){
  if (button.uniquePress()){
    buttonPresses = ++buttonPresses % NUMBER_OF_STATES; 
    switch (buttonPresses){
      case 0: 
        bluestatemachine.immediateTransitionTo(blueoff);
        greenstatemachine.immediateTransitionTo(greenoff);
        redstatemachine.immediateTransitionTo(redon); 
        Serial.println("red on");
        break;
      case 1: 
        bluestatemachine.immediateTransitionTo(blueoff);
        greenstatemachine.immediateTransitionTo(greenoff);
        redstatemachine.immediateTransitionTo(redoff);
        Serial.println("red off");
        break;
      case 2:
        greenstatemachine.immediateTransitionTo(greenoff);
        redstatemachine.immediateTransitionTo(redoff);
        bluestatemachine.immediateTransitionTo(blueon);
        Serial.println("blue on");
        break;
      case 3:
        greenstatemachine.immediateTransitionTo(greenoff);
        redstatemachine.immediateTransitionTo(redoff);
        bluestatemachine.immediateTransitionTo(blueoff);
        Serial.println("blue off");
        break;
      case 4:
        greenstatemachine.immediateTransitionTo(greenon);
        redstatemachine.immediateTransitionTo(redoff);
        bluestatemachine.immediateTransitionTo(blueoff);
        Serial.println("green on");
        break;
      case 5:
        greenstatemachine.immediateTransitionTo(greenoff);
        redstatemachine.immediateTransitionTo(redoff);
        bluestatemachine.immediateTransitionTo(blueoff);
        Serial.println("green off");
        break;
      case 6:
        Serial.println("purple on");
        purplestatemachine.immediateTransitionTo(purpleon);
        break;
      case 7:
        Serial.println("purple off");
        purplestatemachine.immediateTransitionTo(purpleoff);
        break;
      case 8:
        Serial.println("purple fade hopefully");
        purplestatemachine.transitionTo(purplefadein);
        break;

        
    }
  }
  redstatemachine.update();
  bluestatemachine.update();
  greenstatemachine.update();
  purplestatemachine.update();
}


void purpleledon(){ redled.on(); blueled.on();}
void purpleledoff(){ redled.off(); blueled.off();}
void purpleledfadein(){ purpleon.fadeIn(2000);}
void purpleledfadeout(){ redled.fadeOut(2000); blueled.fadeOut(2000);}

void redledon(){ redled.on(); }
void redledoff(){ redled.off(); }
void redledfadein(){ redled.fadeIn(2000); }
void redledfadeout(){ redled.fadeOut(2000); }

void blueledon(){ blueled.on(); }
void blueledoff(){ blueled.off(); }
void blueledfadein(){ blueled.fadeIn(2000); }
void blueledfadeout(){ blueled.fadeOut(2000); }

void greenledon(){ greenled.on(); }
void greenledoff(){ greenled.off(); }
void greenledfadein(){ greenled.fadeIn(2000); }
void greenledfadeout(){ greenled.fadeOut(2000); }

so far i have it toggling through the ON/OFF state with the standard RGB colors but now i want to make a fade for the in between colors (purple, yellow, green/blue, white). i started with just purple to get the idea down. it all works great except for the "purplefadein" function its fading in red THEN blue. is there anyway that you know of to make it so it fades red and blue in at the same time?

Moderator edit: [code] [/code] tags added

the third line in the void statements for purple
"void purpleledfadein(){ purpleon.fadeIn(2000);}"
that was something i'd been tinkering with trying to get it to treat the fade as a fade for purpleOn as opposed to two separate fades for red and blue but its not working like that

I'd get rid of the LED class. It is not doing anything that you can't do yourself. Instead of calling the fadeIn() function, which fades the one LED, write code that fades more than one LED in a loop.

yeah like paul said it would be much simpler and more fun to just write your own functions which you can change accordingly to however you would like

void fadeInPurpple()
{

    for(int  i = 0 ; i <255; i++);
    analogWrite(blueCathode,i);
    analogWrite(redCathode,i);
   //some sort of delay or millis here to make it a visible transition
}

for(int i = 0 ; i <255; i++); // You really want this here?
analogWrite(blueCathode,i);
analogWrite(redCathode,i);

typos typos typos :blush:

typos typos typos

The missing curly braces are typos, too?

i thought that is what you where referring to a ";" where the curly would go which also made obvious there was no closing curly