Serial Communication
Libraries
A library is a collection of procedures, where all the procedures are related. If you, say, want to control a motor, you may want to find a Motor Control Library: a collection of procedures that have already been written that you can use without having to learn the nuances of motors.
The
Serial Library allows the Arduino to send data back to the computer. It includes the following funtions:
- begin()
- available()
- read()
- write()
- println()
- print()
- flush()
What is Serial?
The word serial means
one after the other. For example, a serial killer doesn't stop with one murder, but stabs many people one after the other.
Serial data transfer is when we transfer data one bit at a time, one right after the other.
Information is passed back and forth between the computer and Arduino by setting a pin high or low. One side sets the pin and the other reads it. It's a little like Morse code, where you can use dits and dahs to send messages by telegram. In this case, instead of a long cable, its only a few feet.

Serial communication with the laptop allowing for greater design flexibility.
Measuring Data
- A single bit is either a zero or a one.
- 8 bits which is 1 byte.
- 1024 bytes (8192 bits) is one Kilobyte (sometimes written KB).
- 1024 KB (1048576 bytes) is one Megabyte (MB)
- 1024 MB is 1 Gigabyte (GB)
When you
Compile/Verify what you're really doing is turning the sketch into binary data (ones and zeros). When you
Upload it to the Arduino, the bits are shoved out one at a time through the USB cable to the Arduino where they are stored in the main chip.
Next time you upload a sketch, look carefully at the two LEDs near the USB connector, they'll blink when data is being transmitted. One blinks when the Arduino is receiving data (RX) and one blinks when the Arduino is transmitting data (TX)
Step 1
Wire the board to go with this code:
/*
* 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
* 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 = 50; // 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
}
Before you run the program describe what it will do.
Exercise 2
Complete the code below and upload it to the board.
/*
* 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;
//these leds will fade on and off
int redPin = _; // Red LED, connected to digital pin 9
int greenPin = _; // Green LED, connected to digital pin 10
int bluePin = _; // Blue LED, connected to digital pin 11
void setup() {
// set the pins as output
_____________________
_____________________
_____________________
//set up serial at a baudrate 9600
_____________________
//turn each light on half way (255 is all the way on)
_____________________
_____________________
_____________________
//Give user directions to program
Serial.println("enter color command (e.g. 'r43') :");
}
void loop () {
//read the serial port and create a string out of what you read
readSerialString(serInString);
//set color code to the first element in the array (r,g or b)
colorCode = serInString[__];
//make sure you've got a light
if( colorCode == 'r' || colorCode == 'g' || colorCode == 'b' ) {
//The C function atoi() takes a string in decimal and returns an integer
colorVal = atoi(serInString+1);
Serial.print("setting color ");
Serial.print(colorCode);
Serial.print(" to ");
Serial.print(colorVal);
Serial.println();
//To indicate you've used this string
//set the first element in the array serInString to 0
________________________
//update lights
if(colorCode == 'r')
analogWrite(redPin, colorVal);
else if(_________________)
_________________________
_________________________
_________________________
}
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++;
}
}
Exercise 3
Change the code below so that you can control the RGB values with multiple key presses. For example, pressing 'r' 5 times will set the brightness to 50% (or brightness = 127) and pressing 'r' 10 times will set it to 100% (or brightness = 255).
Here is a useful string comparison function that compares two strings to see if they are equal.
stringsEqual("hello","hello",5) => true
stringsEqual("hello","helaabbnn",3) => true
stringsEqual("hello","helaa",5) => false
To use this function you must include these lines before setup():
stringsEqual()
#include <stdio.h>
#include <string.h>
/*
* Serial RGB LED
* ---------------
* Serial commands control the brightness of R,G,B LEDs
*
* Command structure is "", where "colorCode" is
* one of "r","g",or "b" and "colorVal" is a number 0 to 255.
* "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 "*", where "colorCode" is
* one of "r","g", or "b".
* "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.
___________________
___________________
___________________
char serInString[100]; // array that will hold the different bytes of the string.
char colorCode;
int colorVal;
//these leds will fade on and off
int redPin = _; // Red LED, connected to digital pin 9
int greenPin = _; // Green LED, connected to digital pin 10
int bluePin = _; // Blue LED, connected to digital pin 11
//create separate variables to hold your pin values
//set them to halfway on
int redValue = ___
___________________
___________________
void setup() {
// set the pins as output
_____________________
_____________________
_____________________
//set up serial at a baudrate 9600
_____________________
//turn each light on use the pin values to turn them on halfway
_____________________
_____________________
_____________________
//Give user directions to program
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);
//INCLUDE A FUNCTION CALL HERE OR NOTHING WILL HAPPEN
//WHAT FUNCTION? LOOK BELOW AND PICK ONE OR WRITE YOUR OWN
//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)...
} _________________________
_________________________
_________________________
_________________________
_________________________
//If the character is b (blue)...
} _________________________
_________________________
_________________________
_________________________
_________________________
}
//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')
_________________________
else if(colorCode == 'g')
_________________________
else if(colorCode == 'b')
_________________________
}
}
boolean stringsEqual(char *string1, char *string2, int numCharacters) {
if (strncmp(string1, string2, numCharacters) == 0) {
return true;
} else {
return false;
}
}
Another version of your light
Come up with other ways of controlling the colors of the LEDs using the keyboard. Here's your chance to be creative and show off. Example: Read colors and set the appropriate RGB values like "orange" might set r=70%, g=50%, and b=0%.
Control 3 leds with three pots.
Put 220 Ohm resistors in line with pots, to prevent circuit from grounding out when the pots are at zero.
/*
* "Coffee-cup" Color Mixer:
* Code for mixing and reporting PWM-mediated color
*
* Control 3 LEDs with 3 potentiometers
* If the LEDs are different colors, and are directed at diffusing surface
* (placed in a paper coffee cup with a cut-out bottom), the colors will mix together.
*
* When you mix a color you like, stop adjusting the pots.
* The mix values that create that color will be reported in the serial monitor.
*
* Standard colors for light mixing are Red, Green, and Blue, though you can mix
* with any three colors; Red + Blue + White would let you mix shades of red,
* blue, and purple (though no yellow, orange, green, or blue-green.)
*
*
*/
// Analog pin settings with Potentiometers connected to analog pins 0, 1, and 2
__________________
__________________
__________________
// Digital pin settings—LEDs use PWM
__________________
__________________
__________________
// Create variables to store the values of the pots
__________________
__________________
__________________
// Variables for comparing values between loops
int i = 0; // Loop counter
//set the delay for 1 second
int wait = __________________
//create a variable to hold the sum of the pot values
__________________
//create a variable to hold the previous sum of pot values
__________________
//create a variable to hold the sensitivity threshold
//this will prevent smal changes in pot values from triggering
//false reporting.
//set this variable to 3
__________________
void setup(){
// set the led pins as output
_____________________
_____________________
_____________________
//set up serial at a baudrate 9600
_____________________
}
void loop(){
//increment loop counter by 1
________________________
// read input pins, convert to 0-255 scale
________________________
________________________
________________________
// Send new values to LEDs
________________________
________________________
________________________
//check if enough time has passed
//you can use the mod operator
//(counter%wait==0)
________________________
//set your sum of pot variable to the sum of pot values
________________________
//check that this new sum is greater than the previous sum by the sensitivity threshold variable
________________________
// ...then print the values.
Serial.print("A: ");
Serial.print(aVal);
Serial.print("\t");
Serial.print("B: ");
Serial.print(bVal);
Serial.print("\t");
Serial.print("C: ");
Serial.println(cVal);
}
//set the previous sum to the current sum
________________________
}
}