Lab 2 — Digital I/O. Building on the first lab last week, I…
By: Sam Stromberg
Tags: Beginner, Arduino, Electronics, Tangible User Interface

Building on the first lab last week, I explored the use of pulse-width modulation (PWM) to simulate analog output from my microcontroller board, as well as using the Serial Monitor function in the Arduino IDE to dynamically control the board using keyboard input.

The initial setup for the board was a fairly straightforward extension of the Lab 1 circuit, running the three LEDs in parallel. There were some physical/spatial considerations in this case, in that we wanted the three bulbs close together (to make it easier to mix their illumination), and in that, in order to use PWM, each circuit had to be controlled with a compatible output pin (denoted on the PCB with a ~; six of the digital output pins have this capability). I landed my circuits on pins 9, 10, and 11 for R, G, and B, respectively, and used matching-colored jumper wires for visual clarity.

The physical circuit

I played around with a few different configurations on the breadboard before reaching this solution, because I wanted the LEDs close together but didn’t want to snip their legs (or the legs of the resistors) for later usage. As well, I found that running jumper wires back to ground added a lot of visual clutter, so I went ahead and cut some small wires to size instead. Connections between the Arduino and breadboard are still made with jumpers to allow them to move a little bit relative to each other. I could have placed the LEDs ahead of their resistor(s) in the circuit, and so used a single resistor after landing the LEDs on the ground bus, but I vaguely remember being instructed to always keep resistors in front of their loads (in case of an accidental short, maybe?).

Components

Arduino Uno / USB-to-Serial cable

Mini breadboard

Red, blue, and green LEDs

3x 220-ohm resistors

Hand-cut and jumper wires

Paper bag, tissue paper, tape to make light diffuser

Code

First, I adapted the ‘Fade’ sample sketch to make sure I understood what was happening in the code and to explore the color space I’m working in. Next, I modified the part of the code reading input from the Serial Monitor to read the first character and step the brightness of the corresponding LED up by 10% of its maximum value (~25).

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 r_value;

int g_value;

int b_value; 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 void setup() {

pinMode(redPin, OUTPUT); // sets the pins as output

pinMode(greenPin, OUTPUT);

pinMode(bluePin, OUTPUT);

Serial.begin(9600);



r_value = 127;

g_value = 127;

b_value = 127;



analogWrite(redPin, r_value); // set them all to mid brightness

analogWrite(greenPin, g_value); // set them all to mid brightness

analogWrite(bluePin, b_value); // set them all to mid brightness

Serial.println(“choose a color (r/g/b):”);

} void loop () {

// clear the string

memset(serInString, 0, 100);

//read the serial port and create a string out of what you read

readSerialString(serInString);



colorCode = serInString[0]; // we only need the color code

if( colorCode == ‘r’ || colorCode == ‘g’ || colorCode == ‘b’ ) {

//colorVal = atoi(serInString+1);

Serial.print(“brightening color “);

Serial.print(colorCode);

Serial.println();

serInString[0] = 0; // indicates we’ve used this string

if(colorCode == ‘r’) {

r_value += 25;

analogWrite(redPin, r_value);

if(r_value > 230) {

r_value = 1;

Serial.print(“r max brightness reached”);

Serial.println();

}

}

else if(colorCode == ‘g’) {

g_value += 25;

analogWrite(greenPin, g_value);

if(g_value > 230) {

g_value = 1;

Serial.print(“g max brightness reached”);

Serial.println();

}

}

else if(colorCode == ‘b’) {

b_value += 25;

analogWrite(bluePin, b_value);

if(b_value > 230) {

b_value = 1;

Serial.print(“b max brightness reached”);

Serial.println();

}

}

}



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++;

}

}

Further Exploration

Because the LEDs provide directed illumination, I found that a multi-layer diffuser greatly improved the blending of colors. I trimmed a white paper lunch bag down and taped a layer of tissue paper inside to act as the first layer, which worked fairly well, even in bright, natural light.

I found the LEDs to have somewhat different apparent brightness, at least in the lighting conditions I was testing them in. An equal mix of blue and green light looked very blue to me, and while I could create orange readily, I found amber or yellow to be harder to locate.

Images of Diffuser

Lining a paper bag with tissue paper

The purple blended quite well.