Anda di halaman 1dari 37

Introduction to

Microcontrollers
with the Arduino
Version 2.89

The Fine Print


Copyright 2010, 2012 TechShop, IncRon Craig. All rights reserved

This manual is furnished under license and may be used or copied only in accordance with the terms of such license. The
content of this manual is furnished for informational use only, is subject to change without notice, and should not be construed
as a commitment by TechShop Inc. Except as permitted by such license, no part of this publication may be reproduced, stored
in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, recording, or otherwise, without the
prior written permission of TechShop Inc.

TechShop and the TechShop logo are either registered trademarks or trademarks of TechShop Inc in the United States and/or
other countries. Microsoft and Windows logo are either registered trademarks or trademarks of Microsoft Corporation in the
United States and/or other countries. Apple, Mac and Macintosh are either registered trademarks or trademarks of Apple
Computer, Inc. in the United States and/or other countries. SnagIt is either registered trademarks or trademarks of TechSmith
Corporation in the United States and/or other countries. All other registered trademarks or trademarks are the property of the
respective owners.

These class materials are intended for use in an instructional setting. Successful completion of SBUs are REQUIRED for many
of the products at TechShop, an instructor must sign off on this requirement. It is NOT enough to just read and follow these
materials.

Except for the cover page, the content of this manual is under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0
License. Under this license, you are permitted to copy, distribute, and transmit this work. You are also free to adapt this work
for your usage. To comply with this license you must also provide attribution for the author, you may not use this work for
commercial purposes, and if you alter or share this work then you must distribute this license with the resulting work. For more
information about this license and the full legal code version text, please see this website:
http://creativecommons.org/licenses/by-nc-sa/3.0/

Colophon
These materials were created electronically using Microsoft Word. These materials were originally written by Marshall
Massengill. To view the original version of this material online, please visit Marshalls website here:
http://forum.nc2600.org/~nickfury/arduino_class/
Ron Craig has added a lot of material since the initial version. There is a web page tracking additional resources for the class.
The website is available at http://wiki.techshoprdu.com/index.php?title=Introduction_to_Microcontrollers_with_Arduino

Introduction to the Arduino


Microcontroller
Initial version by Marshall Massengill
Revised by Ron Craig
The Arduino (ARE-DWEEN-OH) can best be described as follows:
"Arduino is a tool for making computers that can sense and control more of the physical
world than your desktop computer. It's an open-source physical computing platform based on
a simple microcontroller board, and a development environment for writing software for the
board." --- http://arduino.cc, official Arduino website.
The Arduino can be purchased (or built) in many different forms but this class will cover the
"standard" Arduino, the Uno. The first thing to notice about the Uno is that the Arduino has
both a USB port and an external power source port for a 7-12 volt external adapter. The
external port is not required for most prototyping as the USB port provides 5 volt power to
the board.

More information on the Uno is available online at http://arduino.cc/en/Main/ArduinoBoardUno.

The second thing to notice about the Arduino is all of the pin headers. On the top of the
board there are Digital I/O pins. Digital I/O might seem like something fancy but it just
means that the signals sent and received on those pins must be in the form of 1s or 0s, either
+5 or 0 volts for the Arduino to understand them. Youll also notice that some of the Digital
pins have a PWM label underneath them. PWM will be explained a little later but the basic
idea is that for those specific pins, the Arduino can output a different kind of digital signal
that some special devices can understand and take advantage of. There is also a ground
connection and some serial communication ports on the top headers.
On the bottom headers you will find a couple of power output pins for +5v and +3.3v
power, along with a couple of ground pins. You can also find the Analog pins on the
bottom headers. The analog pins will be used for input to the Arduino from analog devices
like sensors and potentiometers. How they work will be explained a little later.
If you are curious about the specifications for the actual microcontroller then they arent
anything to write home about but they are more than enough for most small projects. The
heart of the Arduino is the little PDIP chip that sits in the middle of the board. It is an
ATmega328. The 328 provides 32KB of flash memory, 2KB of SRAM, and 1024 bytes of
EEPROM. The Arduino operates at a blazing fast 16MHz and it is an 8 bit processor. The
ATmega chips are based around a modified Harvard RISC architecture.
The data sheet for the microcontroller is available online at
http://www.atmel.com/dyn/resources/prod_documents/8271S.pdf
The previous version is the Duemilanove (Italian for 2009). The boards are identical except
for the support chip used to communicate over the USB port.

Now that youre almost asleep, its time to wake up and start programming.
3

Tutorial #0 - Installing and Using


the Arduino IDE
Before beginning any of the projects, it is important to download, install, and familiarize
yourself with the Arduino development environment. The development environment is often
called an IDE (Integrated Development Environment) and in the case of the Arduino, it is
multi-platform compatible because it can be installed on Linux, Windows, or Mac OS X
systems. This class is being taught with Windows-based computers but most of the concepts
can be carried over to either of the other platforms with ease. Please note that special driver
installation and configuration may be required on other platforms to use the Arduino IDE.
The installation process for the Arduino IDE is fairly simple. I suggest reading through the
directions before attempting the installation. For the latest information, refer to
http://arduino.cc/en/Guide/HomePage. The software itself can be downloaded as a zip
archive from the http://arduino.cc/en/Main/Software website. Rather than give directions
that will necessarily be out-of-date almost immediately, use the directions on the web site.
Notice that there are likely even newer USB drivers at the FTDI website, offered as a zip file
that duplicates the contents of the FTDI USB Drivers folder of the Arduino download zip.
Once the Arduino IDE has been launched, it is important to select the right Arduino
development board. You can do this by clicking on the "Tools" menu item and then going
down to "Board" and then selecting the appropriate board. The reason that the correct board
must be selected is to allow the Arduino IDE to compile the code you write for the correct
chip and board. If you forget this step, your project wont load properly on the Arduino so
make sure you have the correct board selected.
You will also need to select the correct Serial Port for the Arduino. To do this, you will
need to know the correct Serial port for your Arduino and then you will be able to select it
under the "Tools->Serial Port" menu item. Identifying the Arduino's serial port can be done
through the Device Manager on a Windows machine. On other platforms it is often possible
to find the correct port simply by looking at the names given under the "Serial Port" submenu. Otherwise, disconnect the board and notice which option disappears from the Serial
Port sub-menuthats the one you want.
Familiarizing yourself with the Arduino IDE is important. If you understand the various
elements of the IDE then it will make it easier to finish your projects. In general, though, the
IDE is simple to use and very intuitive.

The various important bits of the Arduino IDE:


1. Application Title, note the version number.
2. The menu bar, and most importantly, the Help menu item.
3. The VERIFY button, you can use it to verify that your code will compile correctly.
4. The UPLOAD button, it will compile and upload the sketch to your Arduino. This is

the best button.


5. The NEW button, it will create a new project or "sketch" for you.
6. The OPEN button, it will open an existing project or sketch.
7. The SAVE button, it will save the sketch for you.
8. The SERIAL MONITOR button, it is used to monitor the serial connection to your

Arduino.
9. The tab for the sketch. Multiple tabs for multiple files in a single sketch are possible.
10. The actual coding area of the sketch. This is where you will write your code.
11. Another important piece of the IDE is located at the bottom of the screenthe debug

window. The debug window will provide you with the error messages from
compiling your code.
12. This identifies the board, the chip, and the serial port you have configured.

Tutorial #1 - Hello World with


the Arduino
The first project for this class will be the equivalent of a "Hello World" program on the
Arduino. In this case, the Arduino will be saying "Hi" to the world by blinking an LED.
This task might seem trivial but by walking through the program it will be possible to evolve
a basic understanding of the Arduino programming language.
All Arduino programs are called sketches. Every Arduino sketch must contain at least two
functions:
1. setup() is called exactly once whenever the Arduino power comes on. It is used to
do any start-up initialization tasks.
2. loop() is called after setup() completes. The function loop() is called over and over
as long as the Arduino has power.
The very simplest Arduino sketch, then, does nothing, but looks like this:

void setup()
{
}
void loop()
{
}

The setup function above is called exactly once, and then loop is called over and over, doing
nothing.

We will now create our first Arduino program. To begin, open the Arduino program on the
computer. This will bring up a window and a new blank project. This new blank project
doesn't contain anything so we're going to have to add some code to it.

/* Arduino Hello World Program


Written by Johnny Appleseed
August 12th, 1859
*/
int blinkyPin = 13;
void setup()
{
pinMode(blinkyPin, OUTPUT);
}
void loop()
{
digitalWrite(blinkyPin, HIGH); // sends +5V to pin
delay(1000);

// waits for a second

digitalWrite(blinkyPin, LOW);

// sets the pin to ground

delay(1000);

// waits for a second

The first bit of code to add is your name and some information about the project.
Programmers call this kind of thing a "comment" and it can come in two varieties. The first
is a multi-line comment and it begins with "/*" and ends with "*/". Anything between the
marks is ignored by the compiler and it is purely for human reference. The next type of
comment is a single-line comment and it is the characters "//" followed by the comment.
/* Arduino Hello World Program
Written by Johnny Appleseed
August 12th, 1859
*/

Sometimes, multi-line comments will have asterisk characters before each line in the
comment. This is more for style than anything functional. Technically, comments are not
functional at all but they help to make code readable and understandable. Without them,
coding would be a whole lot harder.
The next part of the program that needs to be written is a variable assignment. This part of
the program isn't strictly necessary but it will make the code more readable and it will
provide some practice. The code is as follows:
int blinkyPin = 13;

That might seem complicated but it isn't. The first word is "int" and it is shorthand for
"integer" and it serves to tell the compiler what kind of variable it needs to reserve space for.
There are other types of variables but they aren't terribly important to us at the moment. The
next word is "blinkyPin" and it is the name of the variable. From this point on, anytime we
want to refer to our variable then we will call it by its name. The third bit is an assignment
operator, the equals sign. Next is the integer value that we are assigning to the variable
"blinkyPin", in this case the value is 13. The last character is a semicolon and it serves to tell
the compiler that the line has ended.
At this point, if you are confused then it might help to avoid thinking of the equals sign as an
equals sign but rather as the word "gets." If you do so then the above can be read as "integer
variable blinkyPin gets thirteen."
Now, because the Arduino is a microcontroller, every sketch you write has two primary
functions. The first is the setup function and it is run exactly once after a reset and when
the board is first powered on. This function typically contains one-time events that serve to
"setup" the Arduino for the remainder of its execution. The setup function is the next
thing that we will program. We will program it using the following code:
void setup()
{
pinMode(blinkyPin, OUTPUT);
}

The first part of the setup function is marked void to set the return type for the function.
In this case, the setup function does not return anything so it is void. In other cases, a
function might return an integer or something else. The next part is the name of the function,
in this case that is setup as this is the setup function. If you were writing your own
function then it can be named almost anything you want to name it. The next part is a set of
parenthesis. If the function requires any arguments, they would be listed here. Because the
setup function does not require any arguments, the parentheses are empty. Next is a set of
curly braces. They serve as the bookends for the function and tell the compiler where the
function begins and ends. Anything inside of the curly braces is inside of the function and
will be executed exactly once when the Arduino is turned on.
8

Inside of the setup function we add the line that will configure the pin for our LED to
blink. The main point of this line is to call a function called pinMode and pass it two
arguments that will configure the pin that is connected to the LED we wish to blink. The first
argument is the variable that we created initiallyit names the pin. The second argument,
which is preceded by a comma to separate the two arguments, indicates whether we will set
the pins value or read from the pin. This variable is called OUTPUT and is a special type of
global variable that the Arduino provides. It will serve to set the pin for output so we can
blink the LED.
void loop()
{
digitalWrite(blinkyPin, HIGH); // sends +5V to pin
delay(1000);

// waits for a second

digitalWrite(blinkyPin, LOW);

// sets the pin to ground

delay(1000);

// waits for a second

The second function is a loop function that will repeat over and over again and again until
the Arduino loses power, or is reset. It returns nothing so its return type is also void and it
takes no arguments so the parentheses dont contain anything.
This code might look complex but it is very simple. The first line is calling the
digitalWrite function with two arguments. The first argument is the variable
blinkyPin (which we set to 13 earlier). The second argument is a constant in the Arduino
language called HIGH. A constant is basically a variable that is immutable, or in other
words, it is a variable that cannot be changed. In reality HIGH is just the integer 1 and we
could even rewrite the line and replace HIGH with 1 to accomplish the same thing but doing
so would make the code harder to read and understand. As it is, the line can be read as "set
the digital blinkyPin to HIGH output". Lastly, there is a single line comment on this line.
This comment serves to tell you exactly what the line is doing. Setting a digital pin to HIGH
sends +5 volts to the pin. LOW sets the pin to ground (0 volts).
The next line is calling the delay function with only one argument. That argument is an
integer value in milliseconds. In this case, the delay function is being called for one
thousand milliseconds, or one second. The delay function does exactly what you probably
think it doesit delays the code execution for a specified amount of time. This line also has
a single line comment.
The third line is very similar to the first. In fact, the only difference is that the third line is
using the constant LOW instead of the constant HIGH. The constant LOW is the integer
value 0 and if you felt inclined, you could replace LOW with 0 and the line would work just
the same. Again, the reason to use the constants is that it makes the code easier to read and
understand. Lastly, this line is also followed by a single line comment explaining what the
line is doing.
The fourth and final line is exactly the same as the second line.
9

Once you have all of these lines then you can save your code and then compile and upload it
to the Arduino board. The onboard LED should begin to blink on for one second and then off
for one second in a continuous and never-ending loop.
Something that you could try at this point is connecting the positive lead of an external LED
to digital pin 13, which is conveniently located right next to the ground pin. The negative
lead of the LED must also be connected to the ground pin. This external LED will then begin
to blink in the same manner as the onboard LED. Dont try this with pins other than 13
there is a special current-limiting resistor connected only to pin 13 that prevents your external
LED from being burned out.
To practice connecting up an LED properly, change the pin to pin 11 and connect one of your
LEDs to pin 11 using the half-size breadboard supplied with your student kit. Dont forget
the current-limiting resistor!
That concludes the first project of this class.

Layout showing LED plugged into


Arduino headers directly,
connecting Pin 13 and one of the
Ground pins.

Layout showing Arduino Pin 11


connected to an LED, a 220 Ohm
resistor, and then ground.

Schematic 1 showing +5V from a


digital pin, an LED, a 220 Ohm
resistor, and a connection to Ground
(0V).
10

11

Tutorial #2 - Controlling an LED


using digital sensors on the
Arduino
So far weve used the Arduino to affect the outside world, but now its time to sense
something in the physical world as well. There are two basic types of sensorsanalog
and digital. Lets now tackle the simplest digital sensor, a switch. In the student kit
youll find a momentary pushbutton. Its called momentary because it is only actuated
while you hold the button down. The switch in your kit is the most common kind, a
normally-open (NO) switch. This means that the circuit is normally openno current
can pass through it until the button is pressed and held. The other type of momentary
switch is rarerthe normally-closed (NC) switch, which interrupts the circuit when you
press it.
The schematic symbol for a NO switch is shown below. The switch has four pins. Pins 1
and 2 are always electrically connected to each other, and pins 3 and 4 are always
electrically connected to each other. Pressing the button connects the two sides of the
switch together, connecting pins 1 and 2 to pins 3 and 4 for as long as the button is held.

How do we use this to sense the world? If you set a pin to INPUT with
pinMode(pinNumber, INPUT), you can then make a call to determine if that pin
has a logical one (+5V) or zero (0V) value attached. If the voltage on the pin is 3 volts or
higher, the digitalRead function returns a 1. If the voltage is 2 volts or lower, the
function returns a 0. If the value is in the middle, youve wired something wrong or have
a poorly-designed circuit.
There is a function to read varying voltage values, but thats an
analogRead(pinNumber), which well use later with analog sensors.
Pull-up Resistors
12

So, what value will you get if the pin is not connected to anything? The answer is that
the value you get will be unreliable. If you intend to read a value (analog or digital) from
a pin, you really need to ensure that the pin is always connected to something.
You might think that the following would work, but they dont. Can you guess why?

In the left drawing, when the button is released, the pin is left floatingit is not
connected to ground nor is it connected to power. A digitalRead(4) might return
zero or one, depending on sunspots or your hand waving near the chip or just poor luck.
One thought might be to connect the other side of the switch to ground (right drawing).
This would be a Very Bad Idea because if the button were to be pressed, you would have
connected Vcc (your voltage source) to ground (GND), creating a short circuit. This
would certainly make the circuit stop working, possibly burn up the wires, and maybe
start a fire!
The solution to this problem is to drive the pin high in such a way that when the button is
released the value will be reliably high, but when the button is pressed, the value goes
low. This is done with what is called a pull-up resistor. A pull-up resistor is a largevalue resistor through which a HIGH voltage value (+5V for Arduino) is supplied to a
pin. The digital sensor is connected in a way that activating it will then drive the pin to a
low value. When the button is pushed 5 Volts will flow through the button to ground
voltage. Because the resistor limits the amount of current that can flow to ground, you
avoid a short circuit and setting things on fire. That scheme looks like this:

When the button is released, the pin will see the +5V that is connected through the pullup resistor. When the button is pressed, the +5V will flow to ground, and the pin will be
13

connected to ground, so the pin value will go to ground voltage as long as the button is
pressed.
This type of setup is used so very frequently that the designers of the ATMega chip
designed a 20K-Ohm pull-up resistor into every digital IO pin. You dont have to build
this circuit, you only need to use a special pinMode value to enable it.
pinMode(4, INPUT_PULLUP);

// set pin 4 to input mode


// and enable pull-up resistor

Once this call is made, the value read will be HIGH unless it is driven low by whatever is
connected to the pin. To disable the pull-up while running, you can make a call to
digitalWrite(4, LOW).
We can combine this new knowledge about digitalRead() and pull-up resistors to create a
program and circuit that can use a push button to light the LED weve already wired up.

14

/* Arduino Digital Input, Digital Output Program


Written by Robert Louis Stevenson
November 13, 1850
*/
const int buttonPin = 2; // constants are given an initial value when created
const int blinkyPin = 11;

// constants cannot change value after their creation

void setup()
{
pinMode(blinkyPin, OUTPUT); // digital output hooked to LED
// digital input from button is active when LOW because we will
pinMode(buttonPin, INPUT_PULLUP); // enable the pull-up resistor!!
}
void loop()
{
if ( digitalRead(buttonPin) == LOW )

// button pushed

{
digitalWrite(blinkyPin, HIGH);

// LED on

}
else

// button not pushed

{
digitalWrite(blinkyPin, LOW);

// LED off

}
}
The sketch starts with a multiline comment with your name and the purpose of the sketch.
const int buttonPin = 2;
const int blinkyPin = 11;

// constants are given an initial value when created


// constants cannot change value after their creation

These lines define our pins. They wont change, so we tell the compiler to keep us
honest by making them constants with the keyword const. If we write any code that
tries to change their value, the compiler will mark that code as an error for us.

15

void setup()
{
pinMode(blinkyPin, OUTPUT); // digital output hooked to LED
pinMode(buttonPin, INPUT_PULLUP); // digital input from button (active low)
}

When we set up the pins in our setup function, we need to remember to enable the
pull-up resistor so the value will stay high whenever the button is not pressed.
void loop()
{
if ( digitalRead(buttonPin) == LOW )

// button pushed

{
digitalWrite(blinkyPin, HIGH);

// LED on

}
else

// button not pushed

{
digitalWrite(blinkyPin, LOW);

// LED off

}
}
We want our programs loop to read the value of the digital input pin (the button), and
based on the value, switch the LED on or off. The code above turns the LED on while
the button is pressed, and off when the button is released.

Notice that now we need ground and +5V for more things, so we are connecting the
breadboards power and ground rails to the Arduino, then the components to the rails.

16

Figure shows GND and 5V connected to make power rails on breadboard. The
pushbutton switch is connected to digital pin 2 and the ground rail. The LED is
connected as before to digital pin 11.

17

The pull-up resistor is not included in the schematic.


We have ignored an important aspect of a physical push-button. The button contains a
piece of springy metal that is pressed down and makes physical contact between the two
sides of the switch. This contact isnt instantaneous and clean. The metal will in fact
bounce several times before it settles into continuous contact. We cannot tell this fact
from our program because the bounce is very fast, and only results in the LED being
switched on and off very quickly a few extra times whenever the button is pressed. If we
re-wrote our program a bit so that we captured the value read by the digital pin, we would
see that the value will bounce for a short time. Accounting for this behavior is called
debouncing the switch. Theres an optional program at the end of this class handout that
walks through proving this behavior is real. It also shows one simple method for dealing
with the issue.

18

Tutorial #3 - Fading an LED


using the Arduino
The Arduino has said "Hi" but it has a much larger vocabulary than just "Hi" (1) and
"Bye" (0). It can also output what is known as a PWM (Pulse Width Modulation) signal.
PWM is best summarized as incrementally controlling the duty cycle of a square wave
output signal. Dont worry, that will be explained in a moment. The PWM outputs on the
Arduino are located on Pins 3, 5, 6, 9, 10, and 11. The PWM outputs on the Arduino are
8 bits, meaning they are capable of being adjusted from a binary value of 00000000 (0) to
a binary value of 11111111 (255). Don't worry though, an understanding of binary isn't
required to use the PWM outputs on the Arduino, it's just helpful for understanding how
PWM functions. The purpose of this second project is to fade an LED on and off rather
than blinking it on and off. We will step the values supplied to the LED up from 0 to 255
and then back down to 0.
A Diversion: What is PWM?
While an LED may light up weakly with a low amount of current, each LED will behave
a little differently due to manufacturing variations. At some point there will be too little
current to light the LED, but that exact point isnt always predictable, and you dont want
to write code that has to be tuned for every LED you happen to hook up. So how can we
dependably and smoothly control the light level from nothing to full-bright?
By switching it fully on and off very quickly, and varying the proportion of the time it is
off or on, you can reduce the average voltage. For example, if you switch the LED on for
just as long as it is off, it will appear to be faded to about half-brightness. If it is on twice
as long as it is off, it will appear about 2/3 brightness (2/3 on, 1/3 off). The voltage
supplied to the LED (or DC motor or fan or laptop backlight, etc.) is not decreased, but
rather is switched on for differing amounts of time. If you hook up an oscilloscope you
will see a voltage signal like the following:
In the diagram you see the voltage is a
square waveeither zero volts or five
volts. The duty cycle is the proportion
of time that power is supplied. At a 50%
duty cycle the average voltage is just 2.5
volts.
The analogWrite() function will
configure one of the PWM-capable
analog pins to cycle power at the duty
cycle you specify until you tell it to
change it. The PWM frequency is about
490 Hz (490 times per second).

19

/* Arduino Fading LED Program


Written by Henry Wadsworth Longfellow
February 27th, 1807
*/
int value = 0;
int fadingPin = 11;
void setup()
{
pinMode(fadingPin, OUTPUT); // optional for analogWrite, but good practice
}
void loop()
{
for(value = 0 ; value <= 255; value=value+5) // fade in (from min to max)
{
analogWrite(fadingPin, value);
delay(30);

// sets the value (range from 0 to 255)

// waits for 30 milli seconds to see the dimming effect

}
for(value = 255; value >=0; value=value-5) // fade out (from max to min)
{
analogWrite(fadingPin, value);
delay(30);
}
}

The code for this project is very similar to the code from the first project. You could reuse some of the code from the first project but the tutorial is written so that you are
starting from a new file. So, start a new file! Just as before, make a multiline comment at
the beginning of the file describing the program and giving your name.
int value = 0;
int fadingPin = 11;
Here we create a few variables to use later. The first variable (we'll call it "value") is a
spot where we will store our temporary values for this program. Assign a value of 0 to it
for the time being. Also, create a variable called fadingPin and assign it the value of
20

11. This will allow you to connect the positive lead of the fading LED to the digital pin 11
of the Arduino board, and the negative lead to ground.
void setup()
{
pinMode(fadingPin, OUTPUT); // optional for analogWrite, but good practice
}
Technically, you don't need to put anything inside of the setup() function but for the
sake of completeness and proper coding you should add a line for making pin 11 an output
pin.
for(value = 0 ; value <= 255; value=value+5) // fade in (from min to max)
{
analogWrite(fadingPin, value);
delay(30);

// sets the value (range from 0 to 255)

// waits for 30 milli seconds to see the dimming effect

}
The first lines to add to the loop function are the ones that will make the LED fade on.
The first line of the above code is a for-loop. For-loops will execute the code within
them until the specified condition is no longer true. That might sound complicated but it
isn't. For-loops have three parameters, the first parameter is an initialization value, the
second is a conditional statement that must be true for the loop to execute, and the third
parameter is incrementing (or decrementing) the variable so that the for -loop doesn't get
stuck in a never-ending loop. Notice that the separators between the parameters are
semicolons, not colons.
The for -loop above, then, causes value to take on the value of 0, then 5, then 10, and
so on up to 255.
Inside the for -loop are two more function calls. The first one is the analogWrite
function and it needs two parameters. The first is the pin that it is controlling and the
second is the value, between 0 and 255, that is assigned to set the duty cycle. The other
function is a delay function and it has already been discussed. Now, that takes care of
fading the LED on.

21

Next we need to fade the LED back off by adding another for-loop after the one we just
created:
for(value = 255; value >=0; value=value-5) // fade out (from max to min)
{
analogWrite(fadingPin, value);
delay(30);
}
The second for-loop is nearly the same as the previous one but instead of incrementing
the last parameter, we are decrementing it. The functions inside of the loop are identical to
the previous one because we are applying the same values. That's it. Upload the code to
your Arduino board and run it. Make sure you have the LED connected correctly. You
should be rewarded with an LED that slowly fades on and off.
For a bonus, comment out the delay(30) in the first loop. What happens? Why?

We use the same circuit as the


previous exercise.

Schematic 2 showing a PWM signal from


pin 11 to an LED then through a currentlimiting resistor and then to ground.

22

Tutorial #4 - Fading an LED


using a sensors input
We are now going to use the Arduino's analog inputs. This project will be to use a
potentiometer for input to the Arduino and then use the output values to control the fading
LED. The analog input pins work similarly to the PWM outputs in that they are divided
into bit values. Unlike the PWM outputs though, the analog inputs are NOT 8 bits.
Instead, they are 10 bit values ranging from 0000000000 (0) to 1111111111 (1023). This
is great news for a lot of sensors that use analog signals to provide output because 10 bits
of clarity are better than 8 bits but unfortunately it means that it's not as simple as
assigning the input values directly to the output (the fading LED). This means that some
sort of function will have to be programmed into the Arduino to provide for the correct
mapping.
A Diversion: What is analogRead() really reading?
As we saw, the digitalWrite set a pin to ground or +5V, and digitalRead checks
if the voltage is 0-2V or 3-5V. Analog devices, though, deal in varying voltages, and
analogRead(pinNumber) returns a relative indication of the voltage connected to the
pin, as compared to a reference voltage (5 volts by default).
The processor maps the voltage range of 0 to 5 Volts into the return value of 0 to 1023.
Each step, then, is 5V / 1024 = 0.0049 volts (4.9 mV). If thats not sensitive enough, you
can actually have the processor lower the upper voltage below 5 volts (eg. 1.1 Volts) and
then divide the smaller range into 1024 units. Any voltage connected to the pin above this
new reference voltage will read as 1023, and each unit below 1.1 Volts is just 0.0011
volts (1.1 mV). See http://arduino.cc/en/Reference/AnalogReference for information and
an important warning on changing the reference voltage.

23

/* Arduino Analog Input to Fading LED Program


Written by Pyotr Ilyich Tchaikovsky
August 20th, 1880
*/
int potentiometerPin = A2; // Must be one of the analog pins
int fadingPin = 11; // Must be one of the PWM-capable digital pins
int value = 0;
void setup()
{
pinMode(fadingPin, OUTPUT); // declare the LEDs pin as an OUTPUT
Serial.begin(9600); // start up the serial port at 9600 baud (bits per second)
}
void loop()
{
value = analogRead(potentiometerPin);
value = map(value, 0, 1023, 0, 255); // map a value 0-1023 to the range 0-255
Serial.println(value);
analogWrite(fadingPin, value);
delay(10);
}
The program starts off with the usual multiline comment describing the function of the
program and providing your name.
int potentiometerPin = A2; // Must be one of the analog pins
int fadingPin = 11; // Must be one of the PWM-capable digital pins
int value = 0;
Next, we add in some variables to designate the analog input pin and the PWM output
pin. The analog pins are numbered A0 to A5. Also, create a variable called "value" and
initialize it to zero. We'll use it to store the temporary values we need for our program.

24

void setup()
{
pinMode(fadingPin, OUTPUT); // declare the LEDs pin as an OUTPUT
Serial.begin(9600); // start up the serial port at 9600 baud (bits per second)
}
Inside of the setup() function we do two things. The first is to set the mode for the
PWM output pin. The second thing we need to do is initialize the serial communication
protocol. We will be using the serial communication of the Arduino to get useful feedback
information from the Arduino about the state of our analog values. The
Serial.begin() function takes one parameter, in our case that parameter will be the
integer value, 9600, which is significant because it is the speed that the Arduino will
communicate at over the serial connection. Depending on your perspective, 9600 might
seem big or it might seem small, but the Arduino will happily convey the information we
are looking for at that speed.
value = analogRead(potentiometerPin);
value = value >> 2;

// get a 0-1023 value

// reduce a 10-bit value to a 8-bit value

Serial.println(value);

Inside the loop() function the first thing we are doing is to read in the value of the
potentiometer. We store that value in the "value" variable we created earlier.
Now, remember how the analog inputs on the Arduino offer 10 bits of precision? Well, we
need to alter our stored value a little to make it fit within the 8 bits we are allowed to
provide to our PWM output. To do this we use what computer science types would call a
"bitwise operation." In this case, we shift each bit two positions to the right with the
following line of code:
value = value >> 2; // 1111111111 (1023) becomes 0011111111 (255)
Basicially, what we just did was chop off the last two figures of our binary value. In other
words, we removed two bits of precision thereby giving us the magical 8-bit number that
we needed for our PWM output to understand.
Theres another way to do this, of course (isnt there always another way?) The Arduino
libraries provide a function called map which returns a value mapped into another
range. The call would be
value = map(value, 0, 1023, 0, 255); // map a value from the range 0-1023 into 0-255
Next, we are going to use our serial connection to send this value back to the computer so
we can actually see it changing on the screen. To do this, we will use the
Serial.println() function that can take a couple of different parameters. In our
particular instance, we are only concerned with giving it our "value" variable as a
parameter. There are several other functions to write information over the serial
connection including Serial.write(), and Serial.print(). We are not
interested in those functions right now, though, but you should be aware of them.
25

analogWrite(fadingPin, value);
delay(10);
Next, we are going to use the analogWrite() function to output a value to our PWM
output pin and the delay() function to slow things down just a little.
Before we upload this code to the Arduino, we need to build the circuit. The circuit you
already have for controlling the LED can be left in place as it is. Instead of controlling the
brightness with hard-coded values in a loop, were simply adding another circuit to get the
desired brightness, and your program will serve to link the two circuits together!
Find the potentiometer (also called a pot or variable resistor) and put that into your
breadboard so that each of the 3 leads is on its own row of the board. You'll want to
connect the potentiometer with the two outer legs connected separately to +5 volts and
ground. The wiper (the middle pin) of the potentiometer is connected to the analog input
pin we specified previously, Pin A2.
That's it. Save it and upload it to your Arduino. Once you have it uploaded to the Arduino
you will be able to open the Serial monitor and see the values of the potentiometer scroll
by and change as you adjust the potentiometer.
Switch the +5 and ground going to the potentiometer. What happens? Why?
For a bonus, try connecting a photoresistor or thermistor between +5V and pin A2 in
place of the potentiometer. How does that work? What values do you see? If you
disconnect pin A2 totally, what values do you see as you wave your hand over the board?
How does the LED react?
That completes this project.
Schematic of tutorial
showing a potentiometer
connected to pin A2 and
an LED connected to pin
11.

26

27

Tutorial #5 - Interfacing the


Arduino with a PC
The last thing that will be covered in this class is a project involving output and input from
a host computer. The Arduino isn't just limited to using its onboard ports for input and
output, it is also capable of sending and receiving information from a host computer (of
course it is, how else could we program it?). Fortunately for us, the Arduino is based on a
programming language for the host computer called Processing and we will use it to
interface with the Arduino. The goal of this last project will be to create a sliding control
on the host computer with Processing and then use that to control the fading of our LED,
much like the potentiometer that we used in the previous project.
/* Serial Controlled Fading LED
Written by Werner Herzog
October 17th, 2008
*/
int fadingPin = 11;
byte value = 0;
void setup()
{
Serial.begin(9600);
pinMode(fadingPin, OUTPUT);
}
void loop()
{
if (Serial.available())
{
value = Serial.read();
analogWrite(fadingPin, value);
}
}
Start the coding by declaring a variable for the PWM output pin. You can just use pin 11,
like we have been doing. You will also want to declare a new type of variable called a
"byte" that will be the value we read in from the serial connection coming from the
28

Processing program on the computer. The "byte" type is just an 8 bit number (from 0 to
255). You can assign it the value of 0 for now.
void setup()
{
Serial.begin(9600);
pinMode(fadingPin, OUTPUT);
}
Inside of the setup() function we initialize the serial communication and set the pin
mode of the PWM output pin to be output:
if (Serial.available())
{
}
Next, we move on to the loop() function. Inside of it, we need to create an ifstatement. An if-statement works similarly to a for-loop but instead of executing its
contents for a certain number of iterations, it executes its contents if (and only if) a
specified condition is met. Our if-statement will execute only if data is available on the
serial port.
The if-statement will execute if the value inside of the parenthesis is true. In our code
above, we are taking advantage of something that the Arduino (and most other)
programming language doesit evaluates any non-zero integer value to be true. So it
doesn't matter what the Serial.available() function actually returns because we don't care
as long as the value isn't zero. Luckily for us, the Serial.available() function returns the
number of bytes ready to be read, and that is zero only if the serial connection has no data
available. Pretty neat, huh?
value = Serial.read();
analogWrite(fadingPin, value);
Next, we add some code inside of the if-statement. The code we add reads in the value
from the serial connection and then assigns that value as the duty cycle value of the PWM
signal.
The Serial.read() function is very similar to the Serial.write() function that we used
previously except, as you've probably guessed by now, it doesn't write values to the serial
connection, it reads them from it.

29

Now, we need to concentrate on our Processing code. Processing is the Arduino


language's PC equivalent. As a matter of fact, you will download and install the
Processing IDE just like you did with the Arduino IDE. The Processing IDE can be
downloaded from http://processing.org and just like the Arduino IDE, it is multi-platform
compatible. Download it and install it now.
Once you have the Processing IDE installed, open up the Processing.exe file and you will
be presented with a very familiar environment:
Since we already know the parts of the IDE, let's start coding. Begin with a multi-line
comment describing the function of the program and giving your name:
/* Serial Controlled Fading LED using Processing
Written by Emmanuel Goldstein
Janurary 1st, 1984
*/
Next, we need to import a library into our Processing program to enable serial
communication. That sounds complicated but it really isn't. A library is what
programmers call a collection of code that is pre-written and is external to the program
they are writing. Both Processing and the Arduino languages come with a large number of
libraries that are extremely handy. So, to enable serial communication use the following:
import processing.serial.*;
Serial port;
That second line isn't for importing the library, it is for creating an object called "port" that
is of the type "Serial". It is a bit beyond the scope of this class to discuss objects but
imagine it to be a fancy type of variable.
Now, the Processing language, just like the Arduino language has two primary functions.
The first is the setup() function and the second is the draw() function. You should
create them now:
void setup() {
}
void draw() {
}
Those two functions work very similarly to the two functions that the Arduino uses. The
setup() function runs once at the beginning of the program being executed and the draw()
function loops over and over again and again. Now, inside of the setup() function we need
to add some code:
size(256, 150);
port = new Serial(this, "COM1", 9600);

30

The first line is creating a new window that has a size of 256 pixels by 150 pixels. The
window will serve as our slider. The second line is defining the port object that we created
earlier and assigning it some basic properties. You will need to change the COM1
portion of this code to be the specific COM port that your Arduino is using. Leave
the 9600 alone, though, as it is the speed that we defined for our serial communication on
the Arduino previously.
Next, we need to add code to the draw() function in our Processing program. First, create
a for-loop that counts from 0 to 256 in increments of one:
for (int i = 0; i < 256; i++) {
}
Inside of the "for" loop, we should add the following to create a gradient and give us
something to look at within our window that we created earlier:
stroke(i);
line(i, 0, i, 150);
At this point, it might seem like we are rushing through this Processing stuff but don't
worry about that because this class is about the Arduino, not Processing. You can just
copy the code for now if you need to.
Lastly, outside of the for-loop but still within the draw() function we will add the
following line to get the location of the mouse from our window and output that
information to the serial port:
port.write(mouseX);
Now, at this point we should verify and then run both the Processing sketch and the
Arduino sketch that we created. If all is working as it should, then as we move the mouse
back and forth across the gradient that our Processing program is running we should see
the LED on the Arduino fade on and off. If you made it this far then give yourself a pat on
the back because you now know that Microcontrollers are no where near as scary as you
might have thought they were.

31

Processing Code:
/* Serial Controlled Fading LED using Processing
Written by Emmanuel Goldstein
Janurary 1st, 1984
*/
import processing.serial.*;
Serial port;
void setup() {
size(256, 150);
port = new Serial(this, "COM1", 9600); // must match your machines COMx
}
void draw() {
for (int i = 0; i < 256; i++) {
stroke(i);
line(i, 0, i, 150);
}
port.write(mouseX);
}

32

Debouncing a button
We asserted in an early lesson that proper detection of simply pressing a button could
actually be harder than it might at first appear. If you type in the following program Ill
prove it.
const int buttonPin = 2;
const int LEDPin = 13;

// connect button to ground and to pin 2


// we can just use the LED on the board

void setup()
{
pinMode(LEDPin, OUTPUT);
// LED pin is for output
pinMode(buttonPin, INPUT ); // digital input from button
digitalWrite(buttonPin, HIGH); // enable pullup so no press reads a 1
Serial.begin(9600);
// for the serial monitor output
}
int buttonState = HIGH;
int prevState = HIGH;
boolean ledState = true;
int buttonPress = 0;
int dumped = 0;

//
//
//
//
//

button is originally not pressed


to track the previous state of button
the desired initial state of the LED
We want to count button presses
And periodically dump them out

void loop()
{
buttonState = digitalRead(buttonPin);

// read the button state

/* These lines will debounce the switch.


* Leave them commented out at first.
*/
// if (buttonState != prevState)
// {
//
delay(50);
// }
// buttonState = digitalRead(buttonPin);
if (buttonState != prevState) // if the state differs from before
{
ledState = !ledState; // changes true to false, false to true
if (buttonState == LOW) // button pressed
{
buttonPress++; // count button presses
}
}
if ( ledState )
{
digitalWrite(13, HIGH);
}
else
{
digitalWrite(13, LOW);
}
prevState = buttonState;
if (((buttonPress % 1) == 0) && (dumped != buttonPress))

33

{
}

dumped = buttonPress; // remember which stats weve displayed


dumpStats(); // call the function to display the buttonPress count

}
void dumpStats() // this function displays the number of button presses
{
Serial.print("Button Presses = ");
Serial.println(buttonPress, DEC);
}

If you run the program and view the serial monitor, it starts blank. Press the button 10
times. Is the code seeing button presses that match your presses? If you press the button
10 times, does it report 10 button presses or more?
Now, remove the leading slashes on the lines that do the debouncing and run the sketch
again. Does it work now? Why?
The loop() function is called very very rapidly. If the button bounces, the program will
interpret each bounce as a button press then a button release, then another press, another
release. Each press and each release is another button state change, and youll often see
several with a single physical button press. The simple way to work around this is to give
the button some time to settle down. The new lines are triggered on a potential button
press. They give the button some time to settle down (50 milliseconds in this case) and
then check the button again to see if it still thinks the button is in the new state.

34

One more thing...


That concludes this class. This class was only an introduction into the world of the
Arduino microcontroller and the knowledge gained in it can be applied far beyond the few
projects in this class. In the following, links and resources for information about the
Arduino can be found. Coding for Processing is very similar to coding for the Arduino.

Resources for this class:


0 - The official class wiki site (Errata, etc.): http://wiki.techshoprdu.com/index.php?
title=Introduction_to_Microcontrollers_with_Arduino

1 The schematics and illustrations in this document made with: http://fritzing.org


2 Eaglepopular software used to create PCB layouts: http://www.cadsoftusa.com

Resources for the Arduino:


0 - The official Arduino site- http://arduino.cc
1 - Official Arduino forums - http://arduino.cc/forum/
Old version: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl
2 Lady Adas Arduino Tutorials - http://www.ladyada.net/learn/arduino/index.html
3 - MAKE's Arduino book - http://oreilly.com/catalog/9780596155513/
4 - MAKE's Arduino gift guide:
http://blog.makezine.com/archive/2008/11/aduino_gift_guide.html
5 - A new friend at TechShop. Lots of people are willing to help you make your project
work.

Project Ideas:
0 - Interfacing LCDs - http://www.arduino.cc/playground/Code/LCD
2 - Arduino Projects @ MAKE - http://blog.makezine.com/archive/arduino/
4 - Ardunio @ Instructables - http://www.instructables.com/id/Arduino/

Places to buy shields and other Arduino related stuff:


0 - http://sparkfun.com
1 - http://arduino-direct.com/
2 - http://adafruit.com
3 - http://seeedstudio.com/depot
4 - http://store.makerbot.com
5 - http://www.liquidware.com/shop

35

General Purpose Electronic Part Suppliers:


0 - http://digikey.com
1 - http://mouser.com
2 - http://allelectronics.com
3 - http://alliedelec.com
4 - http://jameco.com

Your Student Kit Bill of Materials:


The materials come from Arduino Direct (URL above).
1 LEDs of various colors
2 Small breadboard
3 Passive speaker (use with Arduinos Tone library)
4 Photoresistor (type 5516 10K Ohm at 10 Lux)
5 Thermistor (10K Ohm at 77 degrees F)
6 Resistor (220 Ohm for LEDs, 10K Ohm for pull-ups, etc.)
7 NO Switch 6x6mm
8 Potentiometer (10K with handle. Plugs into breadboard)

36