Help with switching from one loop to another

Hi

I'm working on my first arduino project and have got a bit stuck. Im starting with a simple rgb light controller, with 3 modes, white, colour swirl and single pot colour setting. I've got it working except I am having to use 3 switches, an input switch, an interrupt switch and the reset switch.
I would like to cut this down to just the one switch that will cycle through the 3 modes but cannot get it to work. below is my code so far, probably a lot of faults with it but I'm learning! :slight_smile: any help would be very appreciated!

const int  buttonPin = 4;                            // the pin that the pushbutton is attached to

int ledRedPWMPin   = 9; //red RGB                     // naming and placing the pin that the red LED is attached to
int ledGreenPWMPin = 10; //green RGB                 // the pin that the green LED is attached to
int ledBluePWMPin  = 11; //blue RGB                   // the pin that the blue LED is attached to

int potPin= 0;                                        // the pin that the 10k pot is attached to


float h;
int h_int;
int red=0, green=0, blue=0;
int FADESPEED=500;                                  // higher number for longer fade in fade mode
int HOLD = 1;                                        // hold fade colour 1 millis can be adjusted higher to have short fades and long holds 
int val=0;
int val2=0;

void h2rgb(float h, int &RED, int &GREEN, int &BLUE);



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

void setDisplayRGB(int r, int g, int b)
{
  analogWrite(ledRedPWMPin,   r); //using PWM pins means any shade
  analogWrite(ledGreenPWMPin, g); // of red,green,blue
  analogWrite(ledBluePWMPin,  b); // 2^24 combinations
}


void setup() {
  
  pinMode(buttonPin, INPUT);                // initialize the button pin as a input:
  pinMode(ledRedPWMPin, OUTPUT);            // initialize the LED pin assigned earlier as an output:
  pinMode(ledGreenPWMPin, OUTPUT);
  pinMode(ledBluePWMPin, OUTPUT);
  setDisplayRGB(0,0,0);
    attachInterrupt(1, cancel, HIGH);
  
  Serial.begin(9600);                      // initialize serial communication:

}

void cancel () {
  buttonPushCounter=15

    ;delay,50;
}

void loop() {


  
  
  buttonState = digitalRead(buttonPin);                        // read the pushbutton input pin:
  delay(50);
  if (buttonState != lastButtonState) {                        // compare the buttonState to its previous state          
    if (buttonState == HIGH) {                                 // if the state has changed, increment the counter
                                                               // if the current state is HIGH then the button
                                                               // went from off to on:
      buttonPushCounter++;                                     // add 1 to counter

    } 
    else {

    }
  }
  
  lastButtonState = buttonState;                              // save the current state as the last state, 
                                                              //for next time through the loop


  
  if (buttonPushCounter == 0) {                               // selections
    setDisplayRGB(0,0,0);                                    // sets leds to off
    Serial.println("OFF");                                    //Prints Off
  } 


  if (buttonPushCounter == 1) {
    setDisplayRGB(255,255,255);                                // Sets to White if push counter is 1
    Serial.println("White");
  } 


  

  if (buttonPushCounter == 2) 

  {


    Serial.println("Fader");
    int rd, gr, bl;
   
    val2 = analogRead(potPin);            // reads the value of the potentiometer (value between 0 and 1023) 
    val2 = map(val2, 0, 1023, 5, 1000);
    FADESPEED=(val2);
    
 setDisplayRGB(0,0,255);                                        // Start with Blue 
 
    for (rd = 0; rd < 256; rd++) {                             // fade from blue to violet if red is between 0 and 255 add 1 each time around,end loop at 256 red
      analogWrite(ledRedPWMPin, rd);                            // write above value to the blue LED
    val2 = analogRead(potPin);                                  // reads the value of the potentiometer (value between 0 and 1023) 
    val2 = map(val2, 0, 1023, 5, 1000);                          // converts to value between 5 and 1000 milliseconds; approx between 9 seconds and 25mins for complete cycle
    FADESPEED=(val2);                                          // gradually write in Red LED
      delay(FADESPEED);                                        // each step (255) delayed by FADESPEED amount set above Pot read/map setting
    }
    delay(HOLD);                                                // Hold on Violet if wanted

    
    for (bl = 255; bl > 0; bl--) {                             // fade from violet to red if blue is between 255 and 0 take off 1 each time around, end loop at 0 blue
      analogWrite(ledBluePWMPin, bl);                          // write above value to the blue LED
val2 = analogRead(potPin);                                      // reads the value of the potentiometer (value between 0 and 1023) 
  val2 = map(val2, 0, 1023, 5, 1000);                            // converts to value between 5 and 1000 milliseconds; approx between 9 seconds and 25mins for complete cycle
  FADESPEED=(val2);                                              // gradually write out Blue LED
      delay(FADESPEED);                                        // each step (255) delayed by FADESPEED amount set above Pot read/map setting
    }
    delay(HOLD);                                              // Hold on Red if wanted                                            
    
    for (gr = 0; gr < 256; gr++) {                             // fade from red to yellow if green is between 0 and 255 add 1 each time around, end loop at 256 green
      analogWrite(ledGreenPWMPin, gr);                         // write above value to the green LED   
    val2 = analogRead(potPin);                                  // reads the value of the potentiometer (value between 0 and 1023) 
    val2 = map(val2, 0, 1023, 5, 1000);                         // converts to value between 5 and 1000 milliseconds approx between 9 seconds and 25mins for complete cycle
    FADESPEED=(val2);                                            // gradually write in Green LED
      delay(FADESPEED);                                         // each step (255) delayed by FADESPEED amount set above Pot read/map setting
    }
    delay(HOLD);                                                // Hold on Yellow if wanted
    
    for (rd = 255; rd > 0; rd--) {                             // fade from yellow to green if red is between 355 and 0 take off 1 each time around, end loop at 0 red
      analogWrite(ledRedPWMPin, rd);                            // write above value to the red LED
val2 = analogRead(potPin);                                      // reads the value of the potentiometer (value between 0 and 1023) 
  val2 = map(val2, 0, 1023, 5, 1000);                            // converts to value between 5 and 1000 milliseconds; approx between 9 seconds and 25mins for complete cycle
  FADESPEED=(val2);                                             // gradually write out Red LED
      delay(FADESPEED);                                        // each step (255) delayed by FADESPEED amount set above Pot read/map setting
    }
    delay(HOLD);                                                // Hold on Green if wanted
    
    for (bl = 0; bl < 256; bl++) {                             // fade from green to teal if blue is between 0 and 256 add 1 each time around, end loop at 256 blue
      analogWrite(ledBluePWMPin, bl);                          // write above value to the blue LED
val2 = analogRead(potPin);                                      // reads the value of the potentiometer (value between 0 and 1023) 
  val2 = map(val2, 0, 1023, 5, 1000);                            // converts to value between 5 and 1000 milliseconds; approx between 9 seconds and 25mins for complete cycle
  FADESPEED=(val2);                                             // gradually write in Blue LED
      delay(FADESPEED);                                        // each step (255) delayed by FADESPEED amount set above Pot read/map setting
    }

continued...

delay(HOLD);                                                // Hold on Teal if wanted
    
    for (gr = 255; gr > 0; gr--) {                             // fade from teal to blue if green is between 255 and 0 take off 1 each time around, end loop at 0 green
      analogWrite(ledGreenPWMPin, gr);                         // write above value to the green LED
val2 = analogRead(potPin);                                      // reads the value of the potentiometer (value between 0 and 1023) 
  val2 = map(val2, 0, 1023, 5, 1000);                            // converts to value between 5 and 1000 milliseconds; approx between 9 seconds and 25mins for complete cycle
  FADESPEED=(val2);                                            // gradually write out Green LED
      delay(FADESPEED);                                        //each step (255) delayed by FADESPEED amount set above Pot read/map setting
    }


    delay(HOLD);                                              // Hold on Blue if wanted
  }

  else

      if (buttonPushCounter == 3) {

      val=analogRead(potPin);    // Read the pin and display the value
      
      h = ((float)val)/1024;    //Serial.println(val);
      h_int = (int) 360*h;
      h2rgb(h,red,green,blue);
      Serial.print("Potentiometer value: ");
      Serial.print(val);
      Serial.print(" = Hue of ");
      Serial.print(h_int);
      Serial.print("degrees. In RGB this is: ");
      Serial.print(red);
      Serial.print(" ");
      Serial.print(green);
      Serial.print(" ");
      Serial.println(blue);

      analogWrite(ledRedPWMPin, red);
      analogWrite(ledGreenPWMPin, green);
      analogWrite(ledBluePWMPin, blue);
    }
    
    
}
void h2rgb(float H, int& RED, int& GREEN, int& BLUE) {

  int var_i;
  float S=1, V=1, var_1, var_2, var_3, var_h, var_red, var_green, var_blue;

  if ( S == 0 )                       //HSV values = 0 ÷ 1
  {
    RED = V * 255;
    GREEN = V * 255;
    BLUE = V * 255;
  }
  else
  {
    var_h = H * 6;
    if ( var_h == 6 ) var_h = 0;      //H must be < 1
    var_i = int( var_h ) ;            //Or ... var_i = floor( var_h )
    var_1 = V * ( 1 - S );
    var_2 = V * ( 1 - S * ( var_h - var_i ) );
    var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) );

    if      ( var_i == 0 ) {
      var_red = V     ;
      var_green = var_3 ;
      var_blue = var_1 ;
    }
    else if ( var_i == 1 ) {
      var_red = var_2 ;
      var_green = V     ;
      var_blue = var_1 ;
    }
    else if ( var_i == 2 ) {
      var_red = var_1 ;
      var_green = V     ;
      var_blue = var_3 ;
    }
    else if ( var_i == 3 ) {
      var_red = var_1 ;
      var_green = var_2 ;
      var_blue = V     ;
    }
    else if ( var_i == 4 ) {
      var_red = var_3 ;
      var_green = var_1 ;
      var_blue = V     ;
    }
    else                   {
      var_red = V     ;
      var_green = var_1 ;
      var_blue = var_2 ;
    }

    RED = (1-var_red) * 255;                  //RGB results = 0 ÷ 255
    GREEN = (1-var_green) * 255;
    BLUE = (1-var_blue) * 255;

  }








  //resets after 15 options to 1st option

  if (buttonPushCounter >3) {
    buttonPushCounter = 0;
  }

}

Please use "code" tags to make your code more readable.
And why not go down to 0 switches? Just use power cycling or the reset switch like I do:

Sorry I will use the code function in future, it did end up hard to read.

Thanks for the information, it looks just the kind of thing I need, so will try your method.

Sorry I will use the code function in future

You can do it retrospectively.
Go back to your posts, click on "modify", highlight the code, then click on the # icon on the editor's toolbar, then click on "save".

You can even use the "modify" function to fix your previous post.

post modified, lesson learnt!

  FADESPEED=(val2);                                            // gradually write out Green LED
      delay(FADESPEED);                                        //each step (255) delayed by FADESPEED amount set above Pot read/map setting

By convention, all capital letter names are reserved for constants. You should NOT be assigning a new value to a constant.

If it isn't meant to be a constant, don't use all capital letters,

void cancel () {
  buttonPushCounter=15

    ;delay,50;
}

Functions don't work like this. I notice it compiled though.

More like:

void cancel () 
  {
  buttonPushCounter = 15;
  delay (50);
  }

To call a function, like delay, you have to put arguments in brackets, like I did. What you did would have a somewhat different effect.

Thanks for your help, I'll alter the bits you've suggested.

I still cant get it to cycle through modes with one button, its fine changing through single colours it's when there is a loop like the colour fading that I can't move to the next 'mode'. Will keep trying though!

If I may suggest, without sounding snaky, you might want to spend some time reading some simple C tutorials (many are available online).

The time you invest will be well repaid. Also think about what you are writing. For example:

 float S=1, V=1, var_1, var_2, var_3, var_h, var_red, var_green, var_blue;

  if ( S == 0 )                       //HSV values = 0 ÷ 1

On the first line, you assign the value 1 to S, and on the very next line, you test if it is zero. How could it be zero?

You have a fair point, a lot of this code was copied and pasted and amalgamated to try make my project work as I wanted. Probably trying to run before I've learnt to walk!

Learn to write state machines. Then you can switch actions easily without a lot of structure.