Author Topic: RGB pushbutton color change  (Read 6669 times)

Rythryn

  • Newbie
  • *
  • Posts: 4
RGB pushbutton color change
« on: October 07, 2016, 05:33:41 pm »
New to arduino coding.   I bought the digispark breakout board and trying to write a code to change the color, on a common Anode LED dies, with a single push button.
I have a 220 Ohm resistor for each output to the RGB.  However it isn't working, and I'm not sure if it is a hardware or a software problem.

My PWM is set to Pin 0, 1, and 4.  The issue I'm having is that it is starting with an initial color, but it will not increase the color index, or read the button state

int redPin = 0;
int greenPin = 1;
int bluePin = 4;

int buttonPin = 5;
int buttonState = 0;

// The "counter" variable is used to keep track of how many cycles
// the button has been held down for.
int counter = 0;

// The "colorIndex" variable is used to keep track of which color is
// currently selected.
int colorIndex = 0;

// The "numberOfColors" variable is used to tell the colorIndex when to
// loop back around.
int numberOfColors = 8;

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

  pinMode (buttonPin, INPUT);
  digitalWrite(buttonState, LOW);

  setColor(100, 0, 0);                       // set initial color to red
  Serial.begin(9600); // Use serial for debugging
}

void loop() {
  // Read the state of the button
     buttonState = digitalRead(buttonPin);

  // If the button is being pressed
  if (buttonState == HIGH) {
    // Increase the
       counter++;
  } else
   {
    // Otherwise the user has released or is not pressing the button and,
    // reset the counter
      counter = 0;
  }

  // If the button has been held down for 30 cycles
  if (counter > 30)
   {
    // If we haven't reached the maximum number of colors yet
    if (colorIndex <= numberOfColors - 1)
   {
      // Move on to the next color
      colorIndex++;
      } else
      {
      // Go back to the first color
      colorIndex = 0;
      }

    // A color change has been performed, reset the counter
      counter = 0;
   }

   
  switch (colorIndex) {
  case 0:
    // Red
    setColor(100, 0, 0);
    break;
  case 1:
    // Violet
    setColor(65, 0, 100);
    break;
  case 2:
    // Blue
    setColor(0, 0, 100);
    break;
  case 3:
    // Green
    setColor(0, 100, 0);
    break;
  case 4:
    // Yellow
    setColor(65, 95, 0);
    break;
  case 5:
    // Orange
    setColor(95, 65, 13);
    break;
  case 6:
    // Brilliant White
    setColor(100, 100, 100);
    break;
  case 7:
    // Dull White
    setColor(35, 35, 35);
    break;
  }

  // Wait 100 milliseconds before checking again
  delay(100);
}

// Function used to set the color of the LED
void setColor(int red, int green, int blue)
 {
  #ifdef COMMON_ANODE
  red = 255 - red;
  green = 255 - green;
  blue = 255 - blue;
  #endif

  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);

 
}

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: RGB pushbutton color change
« Reply #1 on: October 07, 2016, 08:26:40 pm »
Just a guess but I would suggest that you output the counter value via serial to see if you are reaching the >30 threshold that is required before you process any color change. Buttons are notorious for bouncing and if yours is than perhaps the counter is being reset to 0 before reaching the threshold of >30. If you button is bouncing you can research ways to prevent it. Oh, and also print the state of your button pin to see if it indeed is going high. I may have missed something in your code but that's where I would start for debug.

Also, I assume that you realize that with the 100ms loop delay x 30 you would have to hold the button for at least 3 secs to reach your threshold to process the color change.
« Last Edit: October 07, 2016, 09:18:14 pm by exeng »

Rythryn

  • Newbie
  • *
  • Posts: 4
Re: RGB pushbutton color change
« Reply #2 on: October 08, 2016, 07:42:23 am »
yeah. At the moment I am just using a wire as a direct connection, and leaving it in till it changes.  So at the moment I am using no momentary contact switch.
Also because I am using pin 4 as a PWM I can't have it connected to USB to see the print out.   

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: RGB pushbutton color change
« Reply #3 on: October 08, 2016, 09:34:15 am »
Perhaps you can use setcolor() temporarily for debug. Pick two notable colors and output one at the point you see HIGH (before the counter++) on the button pin, and the other when you reach the >30 threshold (right after the if test for >30).  At least that way you will be able to see if you are getting to these sections of code. Perhaps a third color could be used to tell if the counter is being reset to 0. Hope this helps.
« Last Edit: October 08, 2016, 03:14:54 pm by exeng »

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: RGB pushbutton color change
« Reply #4 on: October 09, 2016, 02:35:14 pm »
Look at this again and noticed that you are doing a digitalWrite using the var buttonstate setting it to 0. Since buttonstate is initialized a 0 you are effectively setting pin 0 low. Don't think this is the cause of you problem but I'm guessing this is not what you intended. You most likely wanted to set pin 5 (buttonPin) low.

Have you tried any debug using setcolor()?

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: RGB pushbutton color change
« Reply #5 on: October 09, 2016, 11:23:14 pm »
OK, I just had to dig out one of my digisparks (haven't played with one for awhile) and prototype your setup. I have a slightly modified version of your code working with the following changes:

1. Changed your button pin to be  pinMode (buttonPin, INPUT_PULLUP); so I can pull it to ground to initiate the color change.
2. Removed the digitalWrite to set buttonPin LOW (will pull it low instead to initiated color change.)
3. Test for LOW   if (buttonState == LOW) { to increment the counter.
4. Using 180 Ohm on R, and 150 Ohm on G and B. Don't think this is critical. Your larger Resistor values may yield dimmer light.

Here is the full mod of your code:
Code: [Select]
int redPin = 0;
int greenPin = 1;
int bluePin = 4;

int buttonPin = 5;
int buttonState = 0;

// The "counter" variable is used to keep track of how many cycles
// the button has been held down for.
int counter = 0;

// The "colorIndex" variable is used to keep track of which color is
// currently selected.
int colorIndex = 0;

// The "numberOfColors" variable is used to tell the colorIndex when to
// loop back around.
int numberOfColors = 8;

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

  pinMode (buttonPin, INPUT_PULLUP);

  setColor(100, 0, 0);                       // set initial color to red
//  Serial.begin(9600); // Use serial for debugging
}

void loop() {
  // Read the state of the button
     buttonState = digitalRead(buttonPin);

  // If the button is being pressed
  if (buttonState == LOW) {
    // Increase the
       counter++;
  } else
   {
    // Otherwise the user has released or is not pressing the button and,
    // reset the counter
      counter = 0;
   }

  // If the button has been held down for 30 cycles
  if (counter > 30)
   {
    // If we haven't reached the maximum number of colors yet
    if (colorIndex <= numberOfColors - 1)
   {
      // Move on to the next color
      colorIndex++;
      } else
      {
      // Go back to the first color
      colorIndex = 0;
      }

    // A color change has been performed, reset the counter
      counter = 0;
   }

   
  switch (colorIndex) {
  case 0:
    // Red
    setColor(100, 0, 0);
    break;
  case 1:
    // Violet
    setColor(65, 0, 100);
    break;
  case 2:
    // Blue
    setColor(0, 0, 100);
    break;
  case 3:
    // Green
    setColor(0, 100, 0);
    break;
  case 4:
    // Yellow
    setColor(65, 95, 0);
    break;
  case 5:
    // Orange
    setColor(95, 65, 13);
    break;
  case 6:
    // Brilliant White
    setColor(100, 100, 100);
    break;
  case 7:
    // Dull White
    setColor(35, 35, 35);
    break;
  }

  // Wait 100 milliseconds before checking again
  delay(100);
}

// Function used to set the color of the LED
void setColor(int red, int green, int blue)
 {
  #ifdef COMMON_ANODE
  red = 255 - red;
  green = 255 - green;
  blue = 255 - blue;
  #endif

  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);
}

It works for me and should work for you. Just pull pin 5 to GND with your button or a wire to GND. If it doesn't work, there is something else going on. Make sure your RGB LED leads are in the correct orientation so that you are connecting the Cathode to GND. It's easy to get these suckers backwards. I did while setting this proto up.
« Last Edit: October 09, 2016, 11:30:25 pm by exeng »

Rythryn

  • Newbie
  • *
  • Posts: 4
Re: RGB pushbutton color change
« Reply #6 on: October 10, 2016, 09:33:18 am »
Thanks. Yeah. It's a common Anode RGB, i'll try the modified code.  I'm using 220Ω resistor to G and B.

I'm going to try this. Thanks a lot :)

One thing the code is not doing is maintaining the color I want after button release.  As long as the button is held the color cycles, once I release the button it resets, and will not trigger the next color when i push it again.
« Last Edit: October 10, 2016, 11:00:01 am by Rythryn »

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: RGB pushbutton color change
« Reply #7 on: October 10, 2016, 11:23:38 am »
If you are using a common Anode style RGB LED, I don't see a #define for COMMON_ANODE in your code.

I was using a Pololu #1074 common Cathode RGB LED to test with. It as since been discontinued replaced on the Pololu site with a common Anode version. Obviously, these are not pin compatible.

I myself prefer to use WS2812B leds / matrixes. Better color mixing and brightness but they do require more extensive code, libraries and power depending on the number of them you are trying to control.  Digistump sells a RGB LED shield for the Digispark that breaks out a single WS2812B if you would like to try one.

I've used an 8x8 matrix of these from RGB-123 to do some simple animations using Neopixel libraries. Adafruit is another source for these.

Rythryn

  • Newbie
  • *
  • Posts: 4
Re: RGB pushbutton color change
« Reply #8 on: October 10, 2016, 02:51:26 pm »
Yeah, for some reason the #define COMMON_ANODE was missing.   I prefer the common anode because i'm not pushing more current through the board. Instead drawing it.  The color mixing isn't too bad.

I'm still trying to get the color to hold when i release the button.   thinking the physical board may be the issue

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: RGB pushbutton color change
« Reply #9 on: October 30, 2016, 11:48:39 pm »
Rythryn, et al,

Don't know if you are still playing with RGB LEDs but got bored and decided to play with your code to create a smooth color transition across the RGB colors. Ended up with a nice effect. Didn't analyze the color variations so I don't know how many I hit. Fun to stare at if you are bored...

Here is the code:
Code: [Select]
// Smooth RGB LED display

int redPin = 0;
int greenPin = 1;
int bluePin = 4;

int red = 64;
int green = 128;
int blue = 255;
int reddir = 1;
int greendir = 1;
int bluedir = 1;

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

  setColor(255, 0, 0); // set initial color to red
  delay(2000);
}

void loop() {
   // Vary individual color at different rates up and down
   if(reddir == 1) red += 3;
   else red--;
   
   if(greendir == 1) green +=2;
   else green -= 3;
   
   if(bluedir == 1) blue++;
   else blue -= 2;
 
   if (red >= 255) {
    red = 255;
    reddir = 0;
   }
   if (green >= 255) {
    green = 255;
    greendir = 0;
   }
   if (blue >= 255) {
    blue = 255;
    bluedir = 0;
   }

   if (red <= 0) {
    red = 0;
    reddir = 1;
   }
   if (green <= 0) {
    green = 0;
    greendir = 1;
   }
   if (blue <= 0) {
    blue = 0;
    bluedir = 1;
   }
   
   setColor(red, green, blue);
   delay(80);
}

// Function used to set the color of the LED
void setColor(int red, int green, int blue)
 {
  #ifdef COMMON_ANODE
  red = 255 - red;
  green = 255 - green;
  blue = 255 - blue;
  #endif

  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);
}