RGB LED Push Button

All,
I have searched the forums and online, but I can't seem to find exactly the help that I need. I am wanting to build where I can change 8 colors of an RGB LED using ONE push button. Every time I push the one button, I want it to change more than just red, green, and blue. I would like magenta, yellow, white, etc... I would also like it to debounce to ensure accuracy. I think I saw something about using a library, but I would like to try and avoid it if possible. I guess, how can I create a method or function that stores the different analog colors of the RGB (80,0,80)? I really appreciate the support. Below is my code, but it doesn't work so if someone could tinker then that would be great. Or maybe, it is just not possible outside of the main 3 colors.

// First we'll set up constants for the pin numbers.

 // pushbutton pin
 const int buttonPin = 3;

 //RGB LED pins
 const int redPin = 11;    
 const int greenPin = 10;
 const int bluePin = 9;


//create a variable to store a counter and set it to 0
int counter = 0;

long time = 0;         // the last time the output pin was toggled
long debounce = 200; 

void setup()
{
  // Set up the pushbutton pins to be an input:
  pinMode(buttonPin, INPUT);

  // Set up the RGB pins to be an outputs:
  pinMode(redPin, OUTPUT);  
  pinMode(greenPin,OUTPUT);
  pinMode(bluePin,OUTPUT);
}


void loop()
{
 // local variable to hold the pushbutton states
  int buttonState;  

  //read the digital state of buttonPin with digitalRead() function and store the           //value in buttonState variable
  buttonState = digitalRead(buttonPin);

  setColor(255, 0, 0);  // red
  delay(1000);
  setColor(0, 255, 0);  // green
  delay(1000);
  setColor(0, 0, 255);  // blue
  delay(1000);
  setColor(255, 255, 0);  // yellow
  delay(1000);  
  setColor(80, 0, 80);  // purple
  delay(1000);
  setColor(0, 255, 255);  // aqua
  delay(1000);
  
  //if the button is pressed increment counter and wait a tiny bit to give us some         
 //time to release the button
  if (buttonState == LOW && millis() - time > debounce) // light the LED
  {
    counter++;
    delay(150);
  }

  //use the if satement to check the value of counter. If counter is equal to 0 all         
//pins are off
  if(counter == 0)
  {
   digitalWrite(redPin,LOW);
   digitalWrite(greenPin,LOW);
   digitalWrite(bluePin,LOW);
  }

  //else if counter is equal to 1, redPin is HIGH
  else if(counter == 1)
  {
   digitalWrite(redPin,HIGH);
   digitalWrite(greenPin,LOW);
   digitalWrite(bluePin,LOW);
  }

  //else if counter is equal to 2 greenPin is HIGH
  else if(counter ==2)
  {
   digitalWrite(redPin,LOW);
   digitalWrite(greenPin,HIGH);
   digitalWrite(bluePin,LOW);
  }

  //else if counter is equal to 3 bluePin is HIGH
  else if(counter ==3)
  {
   digitalWrite(redPin,LOW);
   digitalWrite(greenPin,LOW);
   digitalWrite(bluePin,HIGH);
  }
 //else if counter is equal to 4 whitePin is HIGH
  else if(counter ==4)
  {
   digitalWrite(redPin,HIGH);
   digitalWrite(greenPin,HIGH);
   digitalWrite(bluePin,HIGH);
  }
  //else reset the counter to 0 (which turns all pins off)
  else
  {
   counter =0;
    time = millis(); 
  }


void setColor(int redValue, int greenValue, int blueValue) 
	{
  analogWrite(redPin, redValue);
  analogWrite(greenPin, greenValue);
  analogWrite(bluePin, blueValue);
	}
}

For a start you need to detect when the button becomes pressed rather than when it is pressed

See the StateChangeDetection example in the IDE

You could also put the 3 LED values in an array with one row per counter value and use the counter value to determine the values to be used. The code would then be considerably shorter

Something like this

const byte ledStates[][3] =
{
  {LOW, LOW, LOW},  //counter 0
  {HIGH, LOW, LOW}, //counter 1
  {LOW, HIGH, LOW}  //counter 2
  //etc
};

digitalWrite(redPin, ledStates[counter][0]);
digitalWrite(greenPin, ledStates[counter][1]);
digitalWrite(bluePin, ledStates[counter][2]);
  static byte buttonStateLst = HIGH;

  buttonState = digitalRead(buttonPin);

  if (buttonStateLst != buttonState)  {
      buttonStateLst = buttonState;

      if (LOW == buttonState)  {
        // button pressed
      }
      delay (10);     // debounce
  }

And you could loose the external pullup by using the internal pullup by setting the pinMode to INPUT_PULLUP.

 pinMode(buttonPin, INPUT_PULLUP);

I would also like it to debounce to ensure accuracy. I think I saw something about using a library, but I would like to try and avoid it if possible.

Add hardware debounce with a 0.1uF cap across the switch (input to ground).

Thank you for the help. I was able to get it to work, but how could I use an array on this code to simplify it or is an array just not necessary? Thanks.

long time = 0; //sets the time variable, and uses 'long' syntax as the time variable could be large.
int counter = 0; //counter to count how many times the button has been pressed
const int redPin = 11; 
const int greenPin = 10;
const int bluePin = 5; 
int buttonState = 0; //buttonState for either HIGH or LOW, depending on if the button is pressed. 
const int buttonPin = 8; 
int delayTime = 150; //variable for the time within the delay function (not needed)
long debounce = 200; //the time (in milliseconds) which is the minimum needed for the RGB LED to change colors

void setup() {
  pinMode(redPin, OUTPUT); 
  pinMode(greenPin, OUTPUT); 
  pinMode(bluePin, OUTPUT); 
  pinMode(buttonPin, INPUT); 
}

void loop() {
  buttonState = digitalRead(buttonPin); //reads the button 
  if (buttonState == LOW && millis() - time > debounce) //checks if the button has been pressed 
  //AND if the current milliseconds since the program has been initiated minus the milliseconds 
  //since the button has been pressed is greater than 200 milliseconds (debounce variable)
  {
  counter++; //increments the counter variable by one, button has been pressed
  time = millis(); //sets the time variable to however many milliseconds since the program began as that was when the button is pressed, when the time variable is being changed
  }

  if (counter == 0){ 
    setColor(0, 0, 0); 
  }
  else if (counter == 1) { 
    setColor(255, 0, 0); 
  }
  else if (counter == 2) { 
    setColor(0, 255, 0); 
  }
  else if (counter == 3) { 
    setColor(0, 0, 255); 
  }
  else if (counter == 4) { 
    setColor(255, 255, 0); 
  }
  else if (counter == 5){ 
    setColor(80, 0, 80); 
  }
  else if (counter == 6) {
    setColor(0, 255, 255); 
  }
  else if (counter == 7) {
    setColor(255, 105, 0); 
  }
  else if (counter == 8) { 
    setColor(255, 105, 185); 
  }
  else if (counter > 8){ //if there are no more colors to switch to, it resets to off and goes again
    counter = 0; //resets LED to off and restarts the 'loop'
  }
}

void setColor(int redValue, int greenValue, int blueValue){ 
  analogWrite(redPin, redValue); 
  analogWrite(greenPin, greenValue); 
  analogWrite(bluePin, blueValue); 
}```

here's one approach


#undef MyHW
#ifdef MyHW
byte butPin     = A1;
byte ledPins [] = { 10, 11, 12 };

#else
byte butPin     = 8;
byte ledPins [] = { 11, 10, 5 };
#endif

#define N_LEDS  sizeof(ledPins)

byte settings [][N_LEDS] = {
    { 0,    0,    0   },
    { 255,  0,    0   },
    { 0,    255,  0   },
    { 0,    0,    255 },

    { 255,  255,  0   },
    { 80,   0,    80, },
    { 0,    255,  255 },
    { 255,  105,  185 },
};

#define N_SETTINGS  (sizeof(settings)/(3*sizeof(byte)))

int count = 0;

void
setColor (
    int   idx )
{
    for (unsigned n = 0; n < N_LEDS; n++)
        analogWrite (ledPins [n], settings [idx][n]);
}

byte butLst = HIGH;

void
loop (void) {
    byte but = digitalRead (butPin);

    if (butLst != but)  {
        butLst = but;

        if (LOW == but)  {
            count = (count + 1) % N_SETTINGS;
            setColor (count);
            Serial.println (count);
        }

        delay (10);     // debounce
    }
}

void
setup (void) {
    Serial.begin (9600);
    Serial.println (N_SETTINGS);

    for (unsigned n = 0; n < N_LEDS; n++)
        pinMode (ledPins [n], OUTPUT);
}