I did Option 2 with a few modifications. I had the potentiometers control the rate of change of the red, green and blue LEDs. Turning the potentiometer to zero would therefore “freeze” the color at whatever value it was at before the knob was fully turned to zero.
I also replaced the cross-fading code so that the red, green and blue LEDs were no longer in lock-step. Depending on the increment rate set by the knobs, each color of LED could overtake the other colors, depending on how quickly each LED hit the bounds set by the function. I.e. the sin/cos curve representing each function can be overlaid over each other with different shifts along the x-axis. (For example, you could theoretically line up all curves exactly with careful adjustment of the knobs, which would remove any color-mixing effect.)
I also noticed some blinking on my LEDs, which I troubleshooted as being caused by the LEDs being sent invalid values, such as -1 or 256. I set fatter bounds on both sides to avoid this blinking and for a smooth transition.
/* * Andrew Chong * Alternating RGB Fade with Potentiometers * Modified from Clay Shirky*/ // Output int redPin = 9; // Red LED, connected to digital pin 9 int greenPin = 10; // Green LED, connected to digital pin 10 int bluePin = 11; // Blue LED, connected to digital pin 11 float red_direction = 1; float blue_direction = 1; float green_direction = 1; // brightness float blue_brightness = 0; float red_brightness = 0; float green_brightness = 0; // Program variables float redVal = 255; // Variables to store the values to send to the pins float greenVal = 255; float blueVal = 0; int i = 0; // Loop counter int j = 0; // display counter int wait = 50; // 50ms (.05 second) delay; shorten for faster fades int DEBUG = 1; // DEBUG counter; if set to 1, will write values back via serial void setup() { pinMode(redPin, OUTPUT); // sets the pins as output pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); // If we want to see the pin values for debugging... Serial.begin(9600); // ...set up the serial ouput on 0004 style } // Main program void loop() { blue_brightness = analogRead(A0)*3/(float)1023; red_brightness = analogRead(A5)*3/(float)1023; green_brightness = analogRead(A1)*3/(float)1023; i += 5; // Increment counter j += 1; if (redVal>=250) { red_direction = -1; } if (redVal<=4) { red_direction = 1; } if (blueVal>=250) { blue_direction = -1; } if (blueVal<=4) { blue_direction = 1; } if (greenVal>=250) { green_direction = -1; } if (greenVal<=4) { green_direction = 1; } redVal += red_direction*red_brightness; greenVal += green_direction*green_brightness; blueVal += blue_direction*blue_brightness; if (j > 20) { j = 1; Serial.println(""); Serial.print("red increment:"); Serial.println(red_brightness); Serial.print("blue increment:"); Serial.println(blue_brightness); Serial.print("green increment:"); Serial.println(green_brightness); }; //Serial.println("red:"); //Serial.println("red:"); analogWrite(redPin, redVal); analogWrite(greenPin, greenVal); analogWrite(bluePin, blueVal); if (DEBUG) { // If we want to read the output DEBUG += 1; // Increment the DEBUG counter if (DEBUG > 20) // Print every 10 loops { DEBUG = 1; // Reset the counter Serial.print(i); // Serial commands in 0004 style Serial.print("\t"); // Print a tab Serial.print("R:"); // Indicate that output is red value Serial.print(redVal); // Print red value Serial.print("\t"); // Print a tab Serial.print("G:"); // Repeat for green and blue... Serial.print(greenVal); Serial.print("\t"); Serial.print("B:"); Serial.println(blueVal); // println, to end with a carriage return } } delay(wait); // Pause for 'wait' milliseconds before resuming the loop }
Here is a short video showing how the knobs can be adjusted (knob adjustment out of shot).