Description
I created a new function called myRepeatedKeyProcessCommand() that reads a series of repeated key strokes and calculates the correct level of brightness of the three LEDs. The expected key inputs are limited to the letter of r, g and b. The function counts the number of repeated r, g and b in the input. Each key stroke is  10% of the full brightness of the corresponding LED. For example, rrr is 30% of the full brightness 255. The maximum number of key inputs are set to 30, since ideally each key should be repeated maximum 10 times. If a key is repeated more than 10 times, the brightness is set to 100%, i.e 255. 
The formula used to calculate the brightness is: # of key repeated * 0.1 * 255
The  function checks if keys other than r, g, b are used as input and display error messages to the user. 
The diffuser consists of two parts. The inner layer is a large cotton ball and the outer layer is a cube cover made of white paper. The cotton ball was placed on the LEDs and then covered by the paper cover.  
	Components Used
- 1 red LED
- 1 blue LED
- 1 green LED
- 3 220  Ω Resistors
- 1 Arduino Uno
- cotton ball and cube paper cover as diffuser
 
	Code
 
	/* 
	 * Serial RGB LED
	 * ---------------
	 * Serial commands control the brightness of R,G,B LEDs
	 *
	 * Command structure is "<colorCode><colorVal>", where "colorCode" is
	 * one of "r","g",or "b" and "colorVal" is a number 0 to 255.
	 * E.g. "r0"   turns the red LED off.  
	 *      "g127" turns the green LED to half brightness
	 *      "b64"  turns the blue LED to 1/4 brightness
	 *
	 * Alternate command structure is "<colorCode>*", where "colorCode" is
	 * one of "r","g", or "b".
	 * E.g. "r"    increases the red LED brightness by 10
	 *      "rrr"  increases the red LED brightness by 30
	 *      "ggb"  increases the green LED brightness by 20 and the blue by 10
	 *
	 * Created 18 October 2006
	 * copyleft 2006 Tod E. Kurt <tod@todbot.com
	 * http://todbot.com/
	 *
	 * Adapted 5 September 2007
	 * copylefter 2007 Ryan Aipperspach <ryanaip@alumni.rice.edu>
	 *
	 */
	 
	//include support for manipulating strings.
	//for a useful string comparison function, see the bottom of this file... stringsEqual()
	#include <stdio.h>
	#include <string.h>
	 
	char serInString[100];  // array that will hold the different bytes of the string. 100=100characters;
	                        // -> you must state how long the array will be else it won't work properly
	char colorCode;
	int colorVal;
	 
	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
	 
	int redValue = 127;
	int greenValue = 127;
	int blueValue = 127;
	 
	void setup() {
	  pinMode(redPin,   OUTPUT);   // sets the pins as output
	  pinMode(greenPin, OUTPUT);   
	  pinMode(bluePin,  OUTPUT);
	  Serial.begin(9600);
	  analogWrite(redPin,   redValue);   // set them all to mid brightness
	  analogWrite(greenPin, greenValue);   // set them all to mid brightness
	  analogWrite(bluePin,  blueValue);   // set them all to mid brightness
	  Serial.println("enter color command (e.g. 'r43 or rrrrrrrrbbbb') :");  
	}
	 
	void loop () {
	  //read the serial port and create a string out of what you read
	  readSerialString(serInString, 100);
	 
	  
	    
	  //UNCOMMENT ONE OF THE FOLLOWING COMMANDS, OR NOTHING WILL HAPPEN WHEN YOU
	  //RUN THE PROGRAM...
	  
	  //Uncomment the following line to read commands of the form 'r245' or 'b3'  
	  //processNumericalCommands(serInString);
	  
	  //Uncomment the following line to read commands of the form 'rrrb'
	  //processRepeatKeyCommands(serInString, 100);
	  
	  //Or write your own function...
	  myProcessRepeatKeyCommands(serInString,30);
	 
	  //Erase anything left in the serial string, preparing it for the 
	  //next loop
	  resetSerialString(serInString, 100);  
	 
	  delay(100);  // wait a bit, for serial data
	}
	 
	void resetSerialString (char *strArray, int length) {
	  for (int i = 0; i < length; i++) {
	    strArray[i] = '\0';
	  }
	}
	 
	//read a string from the serial and store it in an array
	//you must supply the array variable
	void readSerialString (char *strArray, int maxLength) {
	  int i = 0;
	 
	  if(!Serial.available()) {
	    return;
	  }
	  while (Serial.available() && i < maxLength) {
	    strArray[i] = Serial.read();
	    i++;
	  }
	}
	 
	//go through the string, and increase the red value for each 'r',
	//the green value for each 'g', and the blue value for each 'b'.
	//For example "rrrg" increases red by 30 and green by 10.
	void processRepeatKeyCommands(char *strArray, int maxLength) {
	  int i = 0;
	  
	  //loop through the string (strArray)
	  //i = the current position in the string
	  //Stop when either (a) i reaches the end of the string or
	  //                 (b) there is an empty character '\0' in the string
	  while (i < maxLength && strArray[i] != '\0') {
	    //Read in the character at position i in the string
	    colorCode = serInString[i];
	    
	    //If the character is r (red)...
	    if (colorCode == 'r') {
	      //Increase the current red value by 10, and if you reach 255 go back to 0
	      redValue = (redValue + 10) % 255;
	      analogWrite(redPin, redValue);
	      Serial.print("setting color r to ");
	      Serial.println(redValue);
	      
	    //If the character is g (green)...
	    } else if (colorCode == 'g') {
	      greenValue = (greenValue + 10) % 255;
	      analogWrite(greenPin, greenValue);
	      Serial.print("setting color g to ");
	      Serial.println(greenValue);
	    
	    //If the character is b (blue)...
	    } else if (colorCode == 'b') {
	      blueValue = (blueValue + 10) % 255;
	      analogWrite(bluePin, blueValue);
	      Serial.print("setting color b to ");
	      Serial.println(blueValue);
	    }
	    
	    //Move on to the next character in the string
	    //From here, the code continues executing from the "while" line above...
	    i++;
	  }
	}
	 
	//change the value of the red, green, or blue LED according to the command received.
	//for example, r240 sets the red LED to the value 240 (out of 255)
	void processNumericalCommands(char *strArray) {
	  //read in the first character in the string
	  colorCode = serInString[0];
	  
	  //if the first character is r (red), g (green) or b (blue), do the following...
	  if( colorCode == 'r' || colorCode == 'g' || colorCode == 'b' ) {
	    //convert the string to an integer
	    //(start at the second character, or the beginning of the string '+1')
	    colorVal = atoi(serInString+1);
	    Serial.print("setting color ");
	    Serial.print(colorCode);
	    Serial.print(" to ");
	    Serial.print(colorVal);
	    Serial.println();
	 
	    if(colorCode == 'r') 
	      analogWrite(redPin, colorVal);
	    else if(colorCode == 'g')
	      analogWrite(greenPin, colorVal);
	    else if(colorCode == 'b')
	      analogWrite(bluePin, colorVal);
	  }
	}
	 
	//compare two strings to see if they are equal
	//compares the first 'numCharacters' characters of string1 and string2 to
	//see if they are the same
	//
	//E.g. stringsEqual("hello","hello",5) => true
	//     stringsEqual("hello","helaabbnn",3) => true
	//     stringsEqual("hello","helaa",5) => false
	boolean stringsEqual(char *string1, char *string2, int numCharacters) {
	  if (strncmp(string1, string2, numCharacters) == 0) {
	    return true;
	  } else {
	    return false;
	  }
	}
	 
	void myProcessRepeatKeyCommands(char *strArray, int maxLength){
	  int i=0;
	  int redCount =0;
	  int greenCount =0;
	  int blueCount =0;
	  int redVal = 0;
	  int blueVal = 0;
	  int greenVal = 0;
	  
	  if( serInString[0] !='\0'){
	  //read all the serial input characters and count number of repeated red, blue and green key strokes
	  while(i<maxLength && serInString[i] != '\0'){
	    colorCode = serInString[i];
	    
	    if(colorCode =='r'){
	      redCount ++;
	    }
	    else if(colorCode == 'g'){
	      greenCount ++;
	    }
	    else if(colorCode == 'b'){
	      blueCount ++;
	    }
	    else{
	      Serial.print("Wrong color code, use r, g, b.");
	      Serial.println();
	    }
	    i++;
	  }
	  Serial.print("redcount ");
	  Serial.println(redCount);
	  Serial.print("greenCount ");
	  Serial.println(greenCount);
	  Serial.print("blueCount ");
	  Serial.println(blueCount);
	 
	  
	  //percentage is incremental of 10%
	  //maximum key stroke for each color therefore is only 10 for 100%
	  //reset to 100% if key stroke goes over maximum
	  if(redCount >10){
	    redCount =10;
	  }
	  if(blueCount >10){
	    blueCount =10;
	  }
	  if(greenCount >10){
	    greenCount =10;
	  }
	    redVal = (int)(redCount*0.1*255);
	    analogWrite(redPin, redVal);
	    Serial.print("Setting red to ");
	    Serial.println(redVal);
	  
	    blueVal = (int)(blueCount*0.1*255);
	    analogWrite(bluePin, blueVal);
	    Serial.print("Setting blue to ");
	    Serial.println(blueVal);
	    
	    greenVal = (int)(greenCount*0.1*255);
	    analogWrite(greenPin, greenVal);
	    Serial.print("Setting green to ");
	    Serial.println(greenVal);
	  
	  }
	}