Lab 2: Serial Communication with Three LED Lights

Submitted by m-craig on Tue, 02/12/2013 - 13:44

This assignment expanded and modified the circuit created for Lab 1 by connecting three LED lights (one red, one blue, one green) to the PWM output ports on my Arduino UNO board.  After playing around with (pseudo-)analog auto-fading effects for a while, I wrote a serial communication program that allows a computer user to vary the brightness of each LED light by typing the letter "R" (red,) "B" (blue,) or "G" (green,) into the Serial Monitor feature of the Arduino software.  The code is written so that the brightness of each light will increase in different increments (Red by 15, Green by 7, Blue by 30) with each keystroke entered.

After completing the program, I created a light diffuser from a semi-translucent plastic drinking cup and a few small wads of cotton.  The cup is placed upside-down over the lights to create a "dome" effect.  Cotton is placed inside the cup, both to prevent LED glare from reflecting too sharply off the top of the "dome" and to create a shadow texture against which the light pulsates.

Components used:

1 - Arduino UNO Board
3 - 220-ohm resistors
3 - LED lights (1 red, 1 blue, 1 green)
1 - Semi-Translucent Plastic Drinking Cup
1 - USB Power Supply
A few loose pieces of cotton fluff

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
 *
 * Created 18 October 2006
 * copyleft 2006 Tod E. Kurt <tod@todbot.com
 * http://todbot.com/
 */

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   = 10;   // Red LED,   connected to digital pin 9
int greenPin = 11;  // Green LED, connected to digital pin 10
int bluePin  = 9;  // Blue LED,  connected to digital pin 11

int rValue = 0;
int gValue = 0;
int bValue = 0;

void setup() {
  pinMode(redPin,   OUTPUT);   // sets the pins as output
  pinMode(greenPin, OUTPUT);   
  pinMode(bluePin,  OUTPUT);
  Serial.begin(9600);
  analogWrite(redPin,   127);   // set them all to mid brightness
  analogWrite(greenPin, 127);   // set them all to mid brightness
  analogWrite(bluePin,  127);   // set them all to mid brightness
  Serial.println("enter color command (e.g. 'r43') :");  
}

void loop () {
  // clear the string
  memset(serInString, 0, 100);
  //read the serial port and create a string out of what you read
  readSerialString(serInString);
  for(int i = 0; i < 100; i++){
  if(serInString[i] == 'r'){
    rValue = rValue + 15;}
  if(serInString[i] == 'g'){
    gValue = gValue + 7;}
  if(serInString[i] == 'b'){
    bValue = bValue + 30;}
  }
      analogWrite(redPin, rValue);
      analogWrite(greenPin, gValue);
      analogWrite(bluePin, bValue);
 
  delay(100);  // wait a bit, for serial data
}

//read a string from the serial and store it in an array
//you must supply the array variable
void readSerialString (char *strArray) {
  int i = 0;
  if(!Serial.available()) {
    return;
  }
  while (Serial.available()) {
    strArray[i] = Serial.read();
    i++;
  }
}

 

(Personally, though, I find it more therapeutic just to set the LED to auto-fade and watch the lights pulsate on their own.  Ultimately, I would like to be able to create interfaces that allow for complex LED behavior that might produce similar "relaxation" effects while also allowing for user input, but I will need to learn a great deal more about coding before I will be able to do that.)
 

Code for Fade Effect:

/*
* Code for cross-fading 3 LEDs, red, green and blue, or one tri-color LED, using PWM
* The program cross-fades slowly from red to green, green to blue, and blue to red
* The debugging code assumes Arduino 0004, as it uses the new Serial.begin()-style functions
* Clay Shirky <clay.shirky@nyu.edu>
*/

// 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

// Program variables
int redVal   = 255; // Variables to store the values to send to the pins
int greenVal = 1;   // Initial values are Red full, Green and Blue off
int blueVal  = 1;

int i = 0;     // Loop counter    
int wait = 2; // 50ms (.05 second) delay; shorten for faster fades
int DEBUG = 0; // 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 (DEBUG) {           // 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()
{
  i += 1;      // Increment counter
  if (i < 255) // First phase of fades
  {
    redVal   -= 1; // Red down
    greenVal += 1; // Green up
    blueVal   = 1; // Blue low
  }
  else if (i < 509) // Second phase of fades
  {
    redVal    = 1; // Red low
    greenVal -= 1; // Green down
    blueVal  += 1; // Blue up
  }
  else if (i < 763) // Third phase of fades
  {
    redVal  += 1; // Red up
    greenVal = 1; // Green low
    blueVal -= 1; // Blue down
  }
  else // Re-set the counter, and start the fades again
  {
    i = 1;
  }  

  analogWrite(redPin,   redVal);   // Write current values to LED pins
  analogWrite(greenPin, greenVal);
  analogWrite(bluePin,  blueVal);  

  if (DEBUG) { // If we want to read the output
    DEBUG += 1;     // Increment the DEBUG counter
    if (DEBUG > 10) // 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
}

3-LED Circuit
3-LED Circuit with Diffuser: Purple
Close-Up of Diffuser: Blue
0
Your rating: None
Drupal theme by Kiwi Themes.