You are on page 1of 131

Arduino Tutorial

originally written by xxx, March 9, 2009 14:26 (http://www.ladyada.net/learn/arduino) manually pasted into OpenOffice by Friedl on June 2, 2009

Introduction
So, I get two or three emails a day, all basically asking the same thing: "Where can I learn about electronics?" In general, most of these people have seen some of my projects and want to be able to build similar things. Unfortunately, I have never been able to point them to a good site that really takes the reader through a solid introduction to microcontrollers and basic electronics.
UNTIL NOW!!!

Table of Content
Arduino Tutorial...................................................................................................................................1 Introduction .....................................................................................................................................1 Goes well with: Arduino Starter Pack and a nice Merlot ...............................................................3 Lesson 0: Pre-flight check...Is your Arduino and computer ready? ..............................................11 Lesson 1: The "Hello World!" of electronics, a simple blinking light...........................................20 Lesson 2: Sketches, variables, procedures and hacking code........................................................37 Lesson 3 - Breadboards, resistors and LEDs, schematics, and basic RGB color-mixing .............42 Lesson 4: The serial library and binary data - getting chatty with Arduino and crunching numbers .......................................................................................................................................................63 Lesson 5: Buttons & switches, digital inputs, pull-up and pull-down resistors, if/if-else statements, debouncing and your first contract product design.....................................................81 Lesson 6: Wiring up an LCD to an Arduino................................................................................116 Appendix: HELP!........................................................................................................................128 Goes well with: Arduino Starter Pack and a nice Merlot I designed this tutorial course to accompany the Arduino starter pack sold at the Adafruit webshop. The pack contains all the components you need (minus any tools) for the lessons Tools Here are some recommended tools:

Multimeter/Oscilloscope A meter is helpful to check voltages and continuity. Check out my recommended basic multimeter and where to buy.

Flush/diagonal cutters. Great for cutting component leads and wires. Check out my recommended basic diagonal cutters and where to buy.

Wire strippers very handy for making wire jumpers! Check out my recommended basic wire strippers and where to buy.

If you need to get any soldering done, you may also want.... Soldering iron. One with temperature control and a stand is best. A conical or small 'screwdriver' tip is good, almost all irons come with one of these. A low quality (ahem, $10 model from radioshack) iron may cause more problems than its worth! Do not use a "ColdHeat" soldering iron, they are not suitable for delicate electronics work and can damage the kit (see here) Check out my recommended basic soldering iron and where to buy.

Solder. Rosin core, 60/40. Good solder is a good thing. Bad solder leads to bridging and cold solder joints which can be tough to find. Dont buy a tiny amount, you'll run out when you least expect it. A quarter pound spool is a good amount. Check out my recommended basic solder and where to buy.

Share and Enjoy! All of the content in the Arduino Tutorial is CC 2.5 Share-Alike Attrib. You can use the text and pictures all you want, providing you do all the hosting, and indicate the attribution like: "This tutorial is by Limor Fried and from http://www.ladyada.net/learn/arduino". Thanks! Love it? Hate it? See a mistake? Post it to the forums! Credits and other links To some extent, the structure of the material borrows from: The impressively good "What's a microcontroller?" book (& now PDF) by Parallax. It's for BASIC Stamps but is still a good read even if you don't plan to use Stamps. "Spooky Arduino" - Todbot's excellent (if fast-paced!) class on Arduino projects for Halloween. Arduino Booklet - With some really great drawings!

Goes well with: Arduino Starter Pack and a nice Merlot


I designed this tutorial course to accompany the Arduino starter pack sold at the Adafruit webshop. The pack contains all the components you need (minus any tools) for lessons 0-10. If people like this system, I will add another pack for another half-dozen lessons, numbers 11+ 1. Starter pack contents 2. Tools you'll want 3. Assemble the protoshield and 9V battery pack Starter pack contents Description Assembled Arduino board, preferrably a Diecimila (or whatever the latest version is) Distributor Quantity

Adafruit

Adafruit USB Cable. Standard A-B cable is required. Any length is OK. Or any computer supply store

Proto shield kit See assembly instructions here

Adafruit

Tiny breadboard

Adafruit

9V DC switch-mode power supply with 2.1mm barrel plug

Adafruit

9V battery case with 2.1mmm barrel plug

Adafruit

Red 5mm LED

Digikey

Green ultrabright LED

Digikey

Red ultrabright LED

Digikey

Blue ultrabright LED

Digikey

1K Potentiometer Elexp (Marked 102) 1/2W 10K Potentiometer Elexp (marked 103) 1/2W

1 1

100 ohm resistor, 5% 1/4 W Brown Black Brown Gold 1.0 Kohm resistor, 5% 1/4 W Brown Black Red Gold

5 Generic

10 Kohm resistor, 5% 1/4 W Brown Black Orange Gold

CdS Photocell DigiKey

12-18" of 22 gauge solidcore wire in differing colors. Tools

Tools are not included in the starter pack, but you probably have a few of these tools kicking around the house. Ask a friend if you can borrow them? Multimeter/Oscilloscope A meter is helpful to check voltages and continuity. Check out my recommended basic multimeter and where to buy.

Flush/diagonal cutters. Great for cutting component leads and wires. Check out my recommended basic diagonal cutters and where to buy.

Wire strippers very handy for making wire jumpers! Check out my recommended basic wire strippers and where to buy.

If you need to get any soldering done, you may also want....

Soldering iron. One with temperature control and a stand is best. A conical or small 'screwdriver' tip is good, almost all irons come with one of these. A low quality (ahem, $10 model from radioshack) iron may cause more problems than its worth! Do not use a "ColdHeat" soldering iron, they are not suitable for delicate electronics work and can damage the kit (see here) Check out my recommended basic soldering iron and where to buy. Solder. Rosin core, 60/40. Good solder is a good thing. Bad solder leads to bridging and cold solder joints which can be tough to find. Dont buy a tiny amount, you'll run out when you least expect it. A quarter pound spool is a good amount. Check out my recommended basic solder and where to buy.

Stuff to do You'll want to solder up your protoshield and 9V battery holder. The protoshield instructions are here. The 9V instructions follow! Learn how to solder by looking here, if you don't know how. Start by unscrewing the plastic cover from the barrel plug

Thread the barrel cover onto the red and black wires so that the round part is near the pack itself, see the image below

Use a pair of pliers (or your fingernails) to make little hooks out of the ends of the red and black wires.

Place the 2.1mm barrel plug in a vise or 3rd hand tool to keep it steady. Hook the red wire onto the middle tab and the black wire to the outer tab as shown. Then bend the hooks over all the way so

that the wires can't come loose while you solder

Solder both hooks to the tabs with a touch of solder. Make sure you heat the black wire tab well as its large enough that it may take a moment for the solder to melt onto the tab well.

Make sure the soldering is neat, the two wires should not be poking out.

Gently pull the red wire towards the black wire and bend over the tabs so that they hold the two wires together. Don't crimp them too tightly or the tab can/will cut into the red wire. Just make sure its snug.

Now screw the plug cover on to protect the connector

You should probably use your multimeter to test continuity between the inner conductor and the outer conductor to make sure they are not shorted. A tutorial on how to do this is here.

Lesson 0: Pre-flight check...Is your Arduino and computer ready?


Introduction This lesson won't teach any electronics, really. Its more for making sure that everything is setup and ready for the future lessons. It will verify the Arduino is working as intended and that the computer

you are using is compatible. Do you have everything you need? For this lesson you will need some stuff! Make sure you have this stuff or you will be unable to complete this lesson Image Description Distributor

Assembled Arduino board, preferrably a Adafruit Diecimila or Duemilanove (or $35 whatever the latest version is) but NG is OK too

Adafruit USB Cable. Standard Or any computer A-B cable is supply store required. Any length is OK. $5

Adafruit 9V DC power plug with 2.1mm barrel plug, positive tip Optional Any electronics supply store (Best Buy, Radio Shack, etc.) $10

4 Rubber bumpers Optional

These are included in Arduinos purchased from the Adafruit shop, otherwise any hardware store should have them. $1

Preparing the Arduino! Take your Arduino out of its protective bag. Look at it and make sure it looks kinda like this:

Diecimila Arduino Or like this:

NG Arduino If there's anything missing or really wrong, make sure to contact the store you bought it from. For example, here is an Arduino that is missing the two round silver capacitors!

OK, now that you are satisfied that your Arduino looks good, put the rubber bumpers on the bottom of the board. This will protect your Arduino from spills and dirty tables. If your table is made out of metal, this is essential!

Download Driver You'll want to grab the USB drivers before plugging in the Arduino for the first time. First, download the USB VCP driver from the FTDI website I strongly suggest visiting the site and downloading the most recent drivers, as of Sept. 2007 the following links are the most recent. Windows XP/2000/Vista Mac OS X PPC Mac OS X Intel, v 10.4 or higher Linux v2.4 or lower kernel only!

If you have a Linux computer, and you have a 2.6 kernel, the driver is built-in and you are good to go. You can always run uname -a to get the kernel version. Then extract the driver bundle onto the Desktop. Under Windows use Unzip or rightclick and select "Extract All..."

Power up! (USB) Now we are ready for the moment of truth, it's time to plug your Arduino in and power it up. The most common way to do this is to plug one end of the USB cable into the Arduino and the other end into a computer. The computer will then power the Arduino. The jumper-setting step is only for Diecimila and OLDER arduinos! Make sure the Power Jumper is set correctly. Right next to the USB jack, there is a jumper with 3 pins. If the jumper is on the two pins nearest USB jack, that means you are planning to power the Arduino via the USB cable. If it's on the two pins nearer the DC Jack then it means you are planning to power the Arduino using a 9V battery or wall adapter.

You'll want it set as shown in the picture above. Make sure your cable is a A-B cable. One end should be thin, rectangular. The other end should be

square.

Plug the thin end into your computer

Make sure that the USB cable is plugged in directly to a computer port. Sometimes monitors or keyboards have a USB port you can plug into. Most of the time this is fine, but I strongly suggest you plug it directly into the computer as that will eliminate any possible problems. Same goes for USB hubs. Later on, once you've verified you can power the Arduino and upload sketches no problem, then you can try plugging it into other ports. Plug the square end into your Arduino

You should get a small green light on the right side of the Arduino, as shown here.

And a few blinking orange lights, on the left side, as shown in this video (download mp4 here)

Click To Play play_blip_movie_385086();If you're plugging it into a Mac or Linux machine, you may not get as much blinking from the orange lights. The video is from plugging into a Windows computer. If no lights or blinking occurs, double check:

Is the USB cable plugged into the computer and into the Arduino? Is the computer on? Is the jumper set correctly? Try another USB port, USB cable, and computer

If you still can't get it working, your Arduino may be faulty. Next its time to install the driver! Follow these links for instructions for each of the supported operating systems Windows Mac Linux Power up! (9V DC, optional!) Another way to power up the Arduino is to plug in a battery or wall adapter into the DC jack. Verify that you have a 9V DC 100-500mA power adapter, with a 2.1mm barrel plug and positive tip. If the box doesn't have any information about the adapter, you can look for these clues

Make sure the symbol near the bottom of the label is present. It means that the outside of the plug is negative and the inside is positive. A center-negative plug will not work with the Arduino. To verify the DC plug is the right shape, just try plugging it in. If it doesn't fit or is wobbly, it's the wrong kind. You can learn how to test wall adapters using a multimeter here. The jumper-setting step is only for Diecimila and OLDER arduinos! Make sure the Power Jumper is set correctly. The jumper should be set so that it connects the two pins close to the DC jack

Plug in the adapter and verify you get the green light! If not, double check: Is the DC adapter plugged in? Is the DC adapter the right kind? Check voltage, polarity, plug size, etc. Is the jumper set correctly? Try another adapter.

If you still can't get it working, your Arduino may be faulty.

Lesson 1: The "Hello World!" of electronics, a simple blinking light


Introduction Ah yes, it is finally time to make your Arduino do something! We're going to start with the classic hello world! of electronics, a blinking light. This lesson will basically get you up and running using the Arduino software and uploading a sketch to the Arduino board. Once you've completed this step we can continue to the really exciting stuff, which is when we start writing our own sketches! These instructions mostly show Windows software. Except when indicated, the software (should be) identical on all platforms. Linux will be added once I figure out how to get it working (yay) Do you have everything you need? Not much is needed for this lesson, just a USB cable and an Arduino. If you have an older Arduino you may also need an LED. Any LED is fine as long as it looks sorta like the photo, with a plastic bulb and two legs Make sure you've gone through Lesson 0 first!

Assembled Arduino Adafruit board, preferrably a Diecimila (or whatever the latest version is)

$35

Adafruit USB Cable. Standard A-B cable is required. Any length is OK. Or any computer supply store

$5

LED - Optional Nearly any LED is OK, as long as it has two wire legs. This Any part is only required electronics $1 for NG rev c Arduinos supply store (and maybe other older ones). Diecimila Arduino's have this part 'built-in' Download the Software The first thing to do is download the Arduino software. Go to the Arduino Software Download page and grab the right file for your OS. As of Sept 2007 the version is 009 but you should use whatever is most recent. The packages are quite large, 30-50 MB so it may take a while to finish

Unpack and Install Extract the package onto the Desktop

Windows

Mac OS X

Windows

Mac OS X

Startup! Double click the Arduino software icon

Windows

Mac OS X To open up the workspace

I think I get the red error text shown because I already have Arduino installed. Either way, it isn't a problem if you do or don't see it. Select chip The first step is to configure the Arduino software for the correct chip. Almost all Arduinos use the ATmega168, but there's a chance you have an ATmega8. Look for the chip on the Arduino that looks like this:

If the text says ATMEGA8-16P then you have an atmega8 chip. If the text says ATMEGA168-20P then you have an atmega168 chip. If it says "ATMEGA328P-20P" you have an atmega328p chip

Make sure the correct chip is selected (this picture is really old, will be fixed soon). This preference is saved so you only have to set it once, the program will remember next time it's run. Select port Next, its time to configure the Serial Port (also known as the COM Port). Go back to lesson 0 to remind yourself of which port it is. On a PC it will probably be something like COM3 or COM4. On a Mac it will be something like tty.usbserial-xxxxx

Windows port selection

Mac port selection This preference is saved so you only have to set it once, the program will remember next time it's run. However, if you have multiple Arduino's, they may be assigned difference COM ports. So every time you plug in a new Arduino, double check that the correct port is selected. Open blink sketch Sketches are little scripts that you can send to the Arduino to tell it how to act. Let's open up an Example Sketch. Go to the File menu -> Sketchbook -> Examples -> Digital -> Blink

The window should now look like this, with a bunch of text in the formerly empty white space and the tab Blink above it

Verify / Compile The first step to getting a Sketch ready for transfer over to the arduino is to Verify/Compile it. That means check it over for mistakes (sort of like editing) and then translate it into an application that is compatible with the Arduino hardware.

After a few seconds, you should see the message Done compiling. in the Status Bar and Binary Sketch Size: in the Notification area. This means the sketch was well-written and is ready for uploading to the Arduino board!

Reset (NG only) To tell the Arduino that it should prepare itself for a new Sketch upload, you must reset the board. Diecimila Arduino's have built-in auto-reset capability, so you don't need to do anything. Older Arduinos, such as NG, must be manually reset before uploading a sketch. To do that simply press the black button on the right hand side of the board, shown here.

Upload Now it's time to upload. Make sure the Arduino is plugged in, the green light is on and the correct Serial Port is selected. If you have an NG Arduino, press the Reset Button now, just before you select the Upload menu item. Select Upload to I/O Board from the File menu

After a few seconds you should get this screen, with the message Done uploading. in the status bar.

If you get the following error message "avrdude: stk500_getsync(): not in sync: resp=0x00" that means that the Arduino is not responding

Then check the following: If you have a NG Arduino, did you press reset just before selecting Upload menu item? Is the correct Serial Port selected? Is the correct driver installed? Is the chip inserted into the Arduino properly? (If you built your own arduino or have burned the bootloader on yourself) Does the chip have the correct bootloader on it? (If you built your own arduino or have

burned the bootloader on yourself) If you get the following error message:

It means you dont have a serial port selected, go back and verify that the correct driver is installed (lesson 0) and that you have the correct serial port selected in the menu. If you get the following error Expected signature for ATMEGA

Then you have either the incorrect chip selected in the Tools menu or the wrong bootloader burned onto the chip If you get the following error: can't open device "COM10": The system cannot find the file specified (under Windows, COM port value may vary)

It means that you have too many COM ports (maybe you've got 9 Arduinos?) You should make sure that the port is numbered as low as possible. You can use a program like FTClean to clear out old COM ports you aren't using anymore. Once you've cleaned out the ports, you'll have to reinstall the driver again (see lesson 0). Alternately, if you're sure that the ports are not used for something else but are left over from other

USB devices, you can simply change the COM port using the Device Manager. Select the USB device in the Device Manager, right click and select Properties

Then click Advanced... and in the next window change the COM port to something like COM4 or COM5. Don't forget to select the new port name in the Arduino software. The lower port names may say (in use) but as long as the other USB devices aren't plugged in, it shouldn't be a problem. This is a little riskier than just using FTClean... Video of all steps Here is a video showing the timing of the steps described so far.

Object 1

Insert LED (NG Arduinos) Some older Arduinos don't have a built in LED, its easy to tell if yours does or not If you have a Diecimila or other Arduino with a built in LED you will see a translucent part as shown

If you have an NG rev C or other Arduino without an LED, the translucent part will not be there, and instead you will see two silver dots

If you don't have an LED, you'll need to add your own. Any LED will do, as long as it has two legs and kinda looks like the one shown here. LEDs are directional components. That means if you put it in backwards it will not work! To help you put the LED in right, the LED factory cuts the legs at different lengths. The longer leg goes in the hole marked 13 and the shorter one goes in the hole marked GND

Watch! If you have a Diecimila Arduino, the upload process is quite fast, just start the Upload from the software. The board will automatically reset itself, transfer the sketch and start the sketch. The little translucent LED will start blinking

Click To Play play_blip_movie_386213();If you have an NG arduino, make sure the LED is inserted as indicated before. Here is a video of the entire uploading process. Right after I press the Reset Button I start the sketch upload. There is a short wait while the software prepares to transfer the sketch. Then the two small orange lights blink, indicating the sketch is being transfered. When its done, there is a 7 second delay until the sketch starts.

Click To Play play_blip_movie_386202();If you don't get a blinking LED, make sure you put the part in the right way, in the correct holes, and perhaps try a different LED as it may be bad.

Lesson 2: Sketches, variables, procedures and hacking code


Introduction OK you've gotten your Arduino set up and also figured out how to use the software to send sketches to the board. Next step is to start writing your own sketches. We'll start off easy by just modifying something that already works. To start we will venture deep into the Blink sketch, looking at each line and trying to understand what its doing. Then we will start hacking the sketch! Blinkie Start up the Arduino software and open the Blink example sketch, as you did in Lesson 1. The sketch itself is in the text input area of the Arduino software. Sketches are written in text, just like a document. When you select Compile/Verify from the menu, the Arduino software looks over the document and translates it to Arduino-machine-language - which is not human-readable but is easy for the Arduino to understand. Sketches themselves are written in C, which is a programming language that is very popular and powerful. It takes a bit of getting used to but we will go through these examples slowly.
/* * Blink * * The basic Arduino example. Turns on an LED on for one second, * then off for one second, and so on... We use pin 13 because, * depending on your Arduino board, it has either a built-in LED * or a built-in resistor so that you need only an LED. * * http://www.arduino.cc/en/Tutorial/Blink */ int ledPin = 13; void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); delay(1000); } // LED connected to digital pin 13 // run once, when the sketch starts // sets the digital pin as output

// run over and over again // // // // sets the LED on waits for a second sets the LED off waits for a second

Comments Lets examine this sketch in detail starting with the first section:

/* * Blink * * The basic Arduino example. Turns on an LED on for one second, * then off for one second, and so on... We use pin 13 because, * depending on your Arduino board, it has either a built-in LED * or a built-in resistor so that you need only an LED. * * http://www.arduino.cc/en/Tutorial/Blink */

This is a comment, it is text that is not used by the Arduino, its only there to help humans like us understand whats going on. You can tell if something is a comment because there is a /* at the beginning and a */ at the end. Anything between the /* and */ is ignored by the Arduino. In this example the person who wrote the comment decided to make it look pretty and add *'s down the side but this isn't necessary. Comments are very useful and I strongly encourage every sketch you make have a comment in the beginning with information like who wrote it, when you wrote it and what its supposed to do. Variables Lets look at the next line:
int ledPin = 13; // LED connected to digital pin 13

This is the first line of actual instruction code. It is also extremely unlike English (or any other human language). The first part we can easily understand is the part to the right, which is also a comment. Turns out if you want to make a small comment, you can use // as well as /* */. // is often used for short, one line comments. The rest of the line, the stuff before the //, is what is called a statement, which is basically like a computerized sentence. Much like human sentances end with a . (period), all computer sentences end with a ; (semicolon) OK all we have left is the statement itself, which turns out to be a sentence telling the computer that we would like it to create a box named ledPin and to put the number 13 in that box. If you remember your math, you may recall that the box is also known as variable. box-type int box-name ledPin = = stuff-to-put-in-box 13

The first part of this sentence is int, which is short for integer which is a fancy way of saying whole number The second part of this sentence is ledPin which is the name of the box The third part is an =, which basically says that the variable (box) named ledPin should start out equaling whatever is after the = The fourth part is 13, a whole number (integer) which is assigned to ledPin Procedures Lets move on to the next section
void setup() { pinMode(ledPin, OUTPUT); } // run once, when the sketch starts // sets the digital pin as output

OK we've got two comments, each starting with //. We understand comments already so lets skip that. We also see in the middle there is a statement, we know its a statement because it ends with a ;

(semicolon) however there's a whole bunch more stuff before and after it. This bunch of code is an example of a procedure, a procedure is a collection of statements, its used to group statements together so that we can refer to them all with one name. Its just like a procedure that we use to perform a task step by step. returned value void procedure name setup (input values ) () { statements } { pinMode(ledPin, OUTPUT); }
// a procedure

To better understand procedures, lets use an analogy to the kinds of procedures we're used to
clean cat wash the cat(dirty cat) for washing the cat { turn on the shower. find the cat. grab the cat. put cat under shower. wait 3 minutes. for cat to get clean. release cat. }

// wait

This is a procedure for washing the cat. The name of the procedure is wash the cat, it uses a dirty cat as the input and returns a clean cat upon success. There are two brackets, an open bracket { and a closed bracket }, thats are used to indicate the beginning and end of the procedure. Inside the procedure are a bunch of statements, indicating the correct procedure for washing a cat. If you perform all of the statements then you should be able to turn a dirty can into a clean cat. Looking again at the procedure, we see that it is named setup and it has no input values and it returns void. Now you're probably asking yourself "what is void?" Well thats a computer-scientist way of saying nothing. That is, this procedure doesnt return anything. (That doesnt mean it doesn't do anything, just that it doesn't have a tangible number or whatever, to show when its complete)
void setup() // run once, when the sketch starts

There is one statment in this procedure,


pinMode(ledPin, OUTPUT); // sets the digital pin as output

We'll return to this statement in detail later, suffice to say it is a way of telling the Arduino what we would like to do with one of the physical pins on the main processor chip. Procedure calls We're onto the next bunch of text.
void loop() { digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); delay(1000); } // run over and over again // // // // sets the LED on waits for a second sets the LED off waits for a second

Using our now well-honed technique we recognize that the text to the right is all comments. We also recognize another procedure, this one called loop which also has no inputs or output. This procedure has multiple statements, one after the other. We're going to skip the first statement for now and go straight to statement #2.

The second and fourth statements are the same, and have something to do with a delay. This statement is very similar to the "wait 3 minutes." command in our cat-washing procedure. This statement says "Dear Arduino. Stop what you're doing for a short amount of time. Thanks!" To do this, the statement performs a procedure call. (We will use the phrasing calls a procedure). Basically, we want the Arduino to take a break but don't quite know how to do it, lucky for us, someone else wrote a procedure called delay which we can call upon to do the work for us. Kind of like if we need to do our taxes and we dont know how, we call upon an accountant to do it for us, giving them the paperwork input and getting tax return as the result. procedure name delay (input values) (1000) ; ;

This means that somewhere out there, there's a procedure something like this:
void delay(number of milliseconds) { "Dear Arduino. Stop what you're doing for (number of milliseconds) amount of time. Thanks!" }

(Of course, this example is not proper code) Turns out this delay procedure works pretty well, and all we have to do is tell it how many milliseconds (1/1000th of a second) to wait and it will do the job for us. Returning to the first statment, we see that it is also a procedure call. This time for some procedure called digitalWrite. We'll also skip this one in detail for a bit, except to explain that its turning a pin on the Arduino chip on and off, and that pin is powering the LED so in essence its turning the LED on and off. Special Procedures - Setup() and Loop() I do want to mention quickly here that the two procedures we've mentioned so far are extra-special in that when the Arduino first wakes up after being reset, it always does whats in the setup procedure first. Then it does whatever is in the loop procedure over and over and over...forever! Or at least until you turn it off. Modifying the example Now that we've analyzed the entire program it's time to make some changes. In your Arduino software, change the number in the delay procedure calls to 500 (from 1000) as shown
void loop() { digitalWrite(ledPin, HIGH); delay(500); digitalWrite(ledPin, LOW); delay(500); } // run over and over again // sets // waits // sets // waits the for the for LED on a second LED off a second

If you try to save the sketch, you'll get the warning that it's read-only.

Not a big deal, you can save it under a new name, such as MyBlink

Compile/Verify the sketch and Upload it, using your Lesson 1 techniques.

Once the Arduino has been updated with the new sketch you should see a faster-blinking light than before If the LED is not blinking faster, check: Did you make the changes to the delay procedure call to make it 500? Did the compile/verify complete successfully? (should look like the screenshot above) Did the upload complete successfully? (should look like the screenshot above)

Exercises Now it time for you to make modifications to the sketch and experiment with different delay values Exercise 1. Modify the code so that the light is on for 100 msec and off for 900 msec Exercise 2. Modify the code so that the light is on for 50 msec and off for 50 msec. What happens? Highlight the text below to see the answer Intense strobe action!

Exercise 3. Modify the code so that the light is on for 10 ms and off for 10 ms. What happens? Highlight the text below to see the answer The light is no longer blinking Now pick up the Arduino and gently wave it back and forth, in a dark room. What happens? Highlight the text below to see the answer The LED creates a dashed trail of light in the air. z What do you think is happening here? Highlight the text below to see the answer The LED is blinking, but its blinking so fast that our eyes can't pick it up, so it looks like a blur. When the Arduino is waved in the air, we see streaks of light from the blinks. Wrap up Congrats, you have finished the second lesson! In this lesson you examined the Blink sketch in detail, and learned a bit of the language used to talk to the Arduino. You also learned how to modify a sketch, and practiced uploading sketches to the Arduino some more.

Lesson 3 - Breadboards, resistors and LEDs, schematics, and basic RGB color-mixing
Introduction You've started modifying sketches, and played a bit with the onboard LED (or if you have an NG, an LED you added). The next step is to start adding onto the hardware component of the Arduino. We will do this by adding a solderless breadboard to our setup, connecting up new parts with wire. Get your gear

Assembled Arduino board, Adafruit preferrably a Diecimila (or whatever the latest version $35 is) but NG is OK too

Adafruit Or any USB Cable. Standard A-B computer cable is required. Any supply store length is OK. $5

LEDs For this lesson, a red, green and blue LED are best. Make sure you get a Any "5mm" or "3mm" LED, electronics with two legs, as shown in supply store the example image. "Ultrabright" LEDs (1000 mcd rating or higher) are preferred Any electronics Three 1K Resistors supply store (brown black red gold) Any values from 300 to 2K are probably OK. $1

Arduino Prototyping Shield with tiny breadboard

Adafruit $15 + Adafruit $7.50

Adafruit Standard solderless breadboard If you dont have a protoshield, this is a substitute $5 Many hobby shops and electronics stores will have these

Hookup Wire Get 22 gauge solid-core wire in red, black and some other color. Make sure its not stranded wire! Say hello to the solderless breadboard! Solderless breadboards are an important tool in your quest for electronics mastery. They allow you to make quick circuits, test out ideas before making a more permanent Printed Circuit Board. They're also inexpensive and reusable.. You can pick on up at any hobby shop or electronics supply store. They often look like this Any hardware store

Basically, a chunk of plastic with a bunch of holes. However, something special is going on inside the breadboard! Although you can't see it, inside the breadboard are many strips of metal that connect the rows and columns together. The metal strips are springy so that when you poke a wire into the hole, the clips grab onto it.

In the images above you can see how there are two kinds of metal strips. There are short ones that connect 5 row holes at a time, and then there are very long ones that connect 25 (or more!) column holes at a time. The long columns are called rails and the short strips are called rows. Breadboards are almost always made so that they have two sets of 5-hole rows and on either side there are a pair of rails. For example the breadboard on the left has 30 row pairs and 2 sets of double rails on either side. The one on the right is quite small, it has only 17 row pairs and no rails. In this lesson, we will show pictures of both the tiny breadboard on a protoshield and also using a 'standard' breadboard without a shield. However, after this lesson, you'll be more on your own to figure out how to connect up the standard breadboard, OK? Warning! Distressing as it may sound, solderless breadboards can be very flakey, especially as they age. If you're having problems with your circuit, it could be that the little metal clips on the inside aren't working well. Try poking it with your finger, or moving it to a different section. Say hello to wires! To use the breadboard, you'll need jumper wires. These are basically 22 gauge solid-core (not stranded) wires that are cut down and have the insulation pulled off. You can use a fingernail or, best of all, a real wirestripper tool to remove the insulation, just takes a few tries and then its really easy. Heres how to do it with just diagonal cutters...Cut the wire first, using wire cutters

Nick the insulation, then pull it off.

To connect rows together, just stick the wire ends without insulation into the square holes!

Now is a good time to practice making jumpers, go forth and make a few 3" long jumpers! Say hello to the resistor! The resistor is the most basic and also most common electronic part. An electronic gadget, such as an mp3 player has easily a thousand resistors inside of it!

Behold...a resistor! Resistors have one job to do, and that is to resist the flow of electricity (otherwise known as current). That's why they're called resistors. By resisting current they control where and how fast it flows. One common way of thinking about this is if we were talking about water current, then pipes are like resistors. Thin pipes let less water through (high resistance), thick pipes let a lot of water through (low resistance). Wth a fire hydrant, you want low resistance. With a water fountain, you'd want high resistance. If you mixed up the two pipe sizes, you wouldnt be able to put out a fire and you'd hurt yourself while trying to get a drink. Resistance is measured in ohms, often written as the symbol . The bigger the resistance value (in ohms) the more it fights. Most resistors you'll see range between 1 ohm and 1 megaohm (1.0 M). Since the resistive element is inside a ceramic casing, its not possible to tell the resistance of a resistor just by looking at it. You'll have to read it by looking at the colored stripes on the body of the resistor. This is known as the resistor color code, and its a real pain when you first start electronics. Eventually you'll get really good at telling the value of a resistor just by glance but to start off you'll want to use a reference chart. (Or you can use a multimeter to measure the resistance accurately) Click here to view a reference chart that you can print out (in color) and use as your guide. There are also website calculators that you may find very handy Remember: Just because the stripes are in a certain order doesn't mean the resistor has a direction! Resistors are the same forward and backwards, it doesnt matter which way they are used. Quick quiz! What is the color code for a 5% 1.0K resistor? Highlight the text below to see the answer Brown - Black - Red - Gold What is the color code for a 5% 220 resistor? Highlight the text below to see the answer Red - Red - Brown - Gold What is the value of this resistor?

Highlight the text below to see the answer The stripes are yellow (4) - violet (7) - red (* 100) = 4700 = 4.7K What happens if you put a resistor in backwards? Highlight the text below to see the answer Ha! Trick question, it is not possible to put a resistor in 'backwards'. They work either way! Note on Wattages.... In all these examples, we use 1/4W resistors. Unless otherwise noted you can use 1/16 W or 1/2W or whatever you can get your hands on. Higher wattage resistors are larger and usually more expensive, but sometimes your local hobby shop will only have 1/2W. Say hello to the LED! We've had some time with the LED already, but lets get to know her a little better. The word LED stands for Light Emitting Diode. The light-emitting part, well, that makes sense. We've used the LED to make a blinking light in lessons 1 and 2. The LED component turns current into light, much like any sort of light bulb. But what is this mysterious diode?

A diode is basically a one-way street for current. Imagine such a one-way street with a traffic policeman in front. If you want to turn onto the street the wrong way, he will not let you. Likewise the diode simply does not let current go through it the wrong way. Current in a diode can only flow from the positive side to the negative side. If you recall from lesson 1, Arduino NG users had to make sure that they inserted the LED in the right way. If you place the LED in backwards it won't work. Diecimila Arduino users already have the LED (a very very small one) soldered onto the circuit board the right way.

Look again! Its a tiny LED As we mentioned before, its easy to figure out which side of an LED is positive and which one is negative. The positive leg is slightly longer and if you look inside, the chunk of metal is larger on the negaive side.

Light up my breadboard We're going to now use the breadboard to light up an LED. You will need a breadboard, an LED and a 1.0K ohm resistor (brown black red gold). If you have a protoshield, make sure its assembled first. Then, place the tiny breadboard on top. You can remove the backing to stick it on (which is permanent) or you can just use double-sided tape. If you have a regular breadboard you'll need 2 jumper wires as well. Important Note! While LEDs will not work when placed backwards, you don't have to worry about whether it will be damaged: as long as there is a series resistor of at least 100 ohms next to it, the LED will survive the experience! However, using an LED without a series resistor is a sure-fire way to kill it! (You'll see a bright flash and it may turn dark) Always use a resistor! A 1.0K ohm is a good place to start. We'll cover how to figure out the best resistor value later on. Place the resistor and LED as shown. Make sure the longer leg of the LED is to the right, connected to the resistor. The resistor doesn't have a direction, so it doesnt matter which way it goes in.

Click for a high resolution photo if necessary! If you're using a standard breadboard, you'll need to use wires to reach the Arduino. Run one wire (red) to the 5V socket on the Arduino. Run the other wire (black) to one of the GND sockets on the Arduino. The colors aren't essential but they will help you remember what the wires are connected to!

Plug in the Arduino, you should see the LED light up. If not, check the following: Is the Arduino plugged in? (look for the little green light on the Arduino as in lesson 0) Is the LED in backwards? Try flipping it around, just in case. This wont damage the LED. Are the parts firmly placed in the breadboard? Loose parts are a common breadboard problem, try jiggling them with a finger and see if it starts working. Is the LED on and its just very dim? Try turning down the lights or looking at it head on: some LEDs are very directional. Is the red wire going into the hole labeled 5V? Is the black wire going into one of the holes labeled GND? Try another LED in case this one is damaged Make sure the parts are as shown in the image above, if you have a wire in one row and the resistor in the other, they aren't connected and it wont work! Scheming schematic Hooray, you just built your first circuit! Its quite simple but still worth explaining. Basically you've connected the LED and resistor in series (one after the other) to a 5V 'battery'. The positive pin of the LED is connected to the positive terminal of the battery, then the negative pin is connected to a resistor which goes to the negative terminal of the battery. The battery is supplying the current that flows through the LED, making it light up. The positive and negative battey terminals are often called the power supply, as they supply power to our circuit. The positive terminal is called power (as thats where current flows from) and the negative terminal is called ground, as it is where current flows to. Lets say you want to "save" this design and send it to a friend to check out and build for herself...one way you could do that is to take a good photo. But a better way is to draw a wiring diagram. Then it wouldn't matter if your camera wasn't very good. A wiring diagram is also known as a schematic. Schematics are the standard method for people to trade information about circuits. Being able to read and write schematics is a key skill! Here is a schematic for a really big project, a Roland TB-303 synthesizer clone Each electronic component has a schematic symbol, which is a simplified drawing of the part. For resistors the symbol looks like this:

Resistor symbol And the symbol for LED's look like this:

LED symbol, positive pin on the left, negative pin on the right You can see that the resistor symbol is symmetric, just like resistors themselves. The LED symbol, however, has an arrow thing going on. This is the direction in which current flows. The little arrows that are coming out of the symbol indicate that this is a diode that emits light. Power and ground also have symbols:

Power and Ground symbols The only thing we need to do now is indicate how the LED and resistor are hooked up and show the 5V and ground connections.

A barebones schematic Next to symbols, we often write important information like what the resistor value is, what color and size the LED should be, and the voltage associated with the power supply.

A well documented schematic! For practice, try drawing your own schematic on a piece of paper. A Quick Rewiring... We're going to make a very small modification to our wired up circuit

In our new schematic, instead of connecting the resistor to +5V power, we'll connect it to ground. Before you change your breadboard, make a guess of what will happen: Will the LED stay lit? Will the LED go out? Something else? Now make the change to your breadboard:

You will notice that, in fact, the LED has gone out. That is because it is no longer connected to a power source and current is not flowing. By connecting the resistor to +5V or ground, you can turn the LED on and off. If you were very fast at it, you could make the LED blink! Hmm.... Re-visiting an old friend Start up the Arduino software again and open up the MyBlink sketch from lesson 2. If you left it with delay times of 10ms, you may want to modify it so its back to 500ms on and 500ms off. Upload the sketch to your Arduino. Now change your breadboard wiring so that it matches this schematic.

That is, instead of connecting the resistor to 5V or ground, connect it to the Arduino pin socket labeled 13. If you have an NG Arduino, you'll need to remove the old LED you used, if its still in the socket.

You should see the LED turn on and off. If you have a Diecimila Arduino, both the on-board LED and the wired LED will blink in unison. Lets look at that code again
void loop() { digitalWrite(ledPin, HIGH); delay(500); digitalWrite(ledPin, LOW); delay(500); } // run over and over again // sets // waits // sets // waits the for the for LED on a second LED off a second

We didn't quite explain what digitalWrite does, but now it should be clear: the digitalWrite procedure connects the pin indicated by the first input (ledPin) to either the +5V power supply or to ground depending on the second input (HIGH or LOW) This is a pretty awesome capability and is the basis of all electronics! You may want to think about how cool it is for a few moments. A new pin Now change the wiring so that the resistor is connected up to pin socket #12

The LED isn't be blinking anymore! Lets fix it! Go back to the beginning of the sketch and find this line again
int ledPin = 13; // LED connected to digital pin 13

This is the line of code that indicates which pin is connected to the LED. Change it so that it is now connected to pin 12
int ledPin = 12; now! // LED connected to digital pin 12

Re-compile and verify the sketch, then send it over the the Arduino. The LED should now be blinking again. Note that if you have a Diecimila Arduino you will not see any blinking on the onboard LED. Thats because its connected to pin 13 only! Exercises!

Spend some time experimenting with different pins. Connect the LED to different pin sockets, and modify the sketch so that the LED blinks. Change around your wiring so that it matches this schematic:

Make sure to modify you sketch so that the ledPin is 13 again. Re-compile and upload it to the Arduino. What does the LED do? Highlight the text below to see the answer It blinks just like before If you have a Diecimila Arduino, what do you notice about the breadboard LED and the on-board LED? Highlight the text below to see the answer They are alternating when they blink Why do you think that is? Highlight the text below to see the answer When the pin is LOW (connected to ground) the breadboard LED is on: current is flowing from +5V to ground through the pin. When the pin is HIGH (connected to +5V) the onboard LED is on, just like before. Adding a green LED... OK sure you've had plenty of practice messing around with LEDs. It's time to go full color! Find a red, green and blue LED. If you have the Arduino Starter Pack they will be the three clear LEDs. You can't tell which one is which until they are lit so just build the circuit and then rearrange them if needed.

Red, green and blue LED schematic In this schematic we will have three LEDs connected to three different pins: #10, #11 and #12.

Go back to your sketch and change it so it looks like this:


int redPin = 12; 12 int greenPin = 11; pin 11 // Red LED connected to digital pin // Green LED connected to digital

void setup() { pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); } void loop() { digitalWrite(redPin, HIGH); digitalWrite(greenPin, HIGH); delay(500); digitalWrite(redPin, LOW); digitalWrite(greenPin, LOW); delay(500); }

// run once, when the sketch starts // sets the digital pin as output // sets the digital pin as output // run over and over again // // // // // // sets the Red LED on sets the Green LED on waits for half a second sets the Red LED off sets the Green LED off waits for half a second

You can just copy and paste this text into your Arduino software window. Quick quiz What does this sketch do? Compile and upload the sketch to test your hypothesis. Highlight the text below to see the answer It blinks the two LEDs connected to pins 11 and 12 at the same time

Click To Play play_blip_movie_392145();If you are having problems getting this sketch to work, double check: Is the sketch compiling properly? Did it upload correctly? Are the LEDs in the right way? Are the resistors in the right sockets? Are the LEDs connected to ground on the other side? Is the breadboard wired up right? Check your connections.

Exercises! Change the code so that the LEDs alternate their blinks: Click To Play play_blip_movie_392150();Highlight the text below to see one possible solution Change the second digitalWrite() procedure call to set the pin LOW, and the fourth call to set the pin HIGH. Change the loop() procedure code so that both LEDs are on for 500 ms, then only the red LED is on for 500 ms, then both LEDs are off, and finally only the green LED is on for 500 ms Highlight the text below to see one answer
void loop() { digitalWrite(redPin, HIGH); digitalWrite(greenPin, HIGH); delay(500); digitalWrite(redPin, HIGH); digitalWrite(greenPin, LOW); delay(500); digitalWrite(redPin, LOW); // run over and over again // // // // // // // sets the Red LED on sets the Green LED on waits for half a second sets the Red LED on sets the Green LED off waits for half a second sets the Red LED off

digitalWrite(greenPin, LOW); delay(500); digitalWrite(redPin, LOW); digitalWrite(greenPin, HIGH); delay(500); }

// // // // //

sets the Green LED off waits for half a second sets the Red LED off sets the Green LED on waits for half a second

Full color adventures! After successfully adding support for the green LED its time to add in the blue LED. Go back to this sketch, the one from the last step
int redPin = 12; 12 int greenPin = 11; pin 11 void setup() { pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); } void loop() { digitalWrite(redPin, HIGH); digitalWrite(greenPin, HIGH); delay(500); digitalWrite(redPin, LOW); digitalWrite(greenPin, LOW); delay(500); } // Red LED connected to digital pin // Green LED connected to digital // run once, when the sketch starts // sets the digital pin as output // sets the digital pin as output // run over and over again // // // // // // sets the Red LED on sets the Green LED on waits for half a second sets the Red LED off sets the Green LED off waits for half a second

You can just copy and paste this text into your Arduino software window. Now you will add the code for the Blue LED by yourself Step 1. Add the line of code that will create a variable called bluePin. What pin should it be assigned? Examine the schematic above to find out. Step 2. Add the line of code that will tell the Arduino that bluePin is a digital output. Step 3. Add the 2 lines of code so that the blue LED will be lit when the red and green LEDs are lit Compile and verify your code. Does it work? If not use your debugging skills to figure out what is wrong and fix it! Color mixing Now that you have red, green and blue light, you can start having fun with color mixing. Color mixing is the neat ability that our eyes have to combine different light colors and create a new color

A additive (light) color mixing diagram According to this diagram, if we have both red and blue light mixed together we should get a violet light. Quick quiz Modify your code to create the following colored light: Violet (red & blue), Turquoise (blue & green) and yellow (green & red) Now you are ready for the "final project" of this very long lesson. You are going to make a color changing light! Modify the sketch so that the emitted light goes in order: red, yellow, green, turquioise, blue violet and back to red. It should pause about half a second between each color change. Hint: One way to make the color mixing work better is to diffuse the light, in a light box. You can make a light box out of plain paper, scissors and some tape. Just make a paper box and cut a hole in it. Fill the box with tissue paper. The tissue acts as a diffuser, helping the light mix nicely

Click To Play

Lesson 4: The serial library and binary data - getting chatty with Arduino and crunching numbers
Introduction Ah, Arduino, I remember when you were just crawling around and blinking LEDs. Now you're ready to learn how to speak! In this lesson we'll learn how to use the Serial Library to communicate from the Arduino board back to the computer over the USB port. Then we'll learn how to manipulate numbers and data. For this lesson we won't be using the shield, so simply remove it (keeping the mood light LEDs on it you'd like). The shield doesn't contain any programs or data, it is just our way of connecing up the LEDs and resistors. We'll use the shield again but for now, we can examine the RX and TX LEDs on the main Arduino board which will help you with debugging What is a Library? Libraries are great places, and not yet illegal in the United States! If you ever need to learn how to

do something, like say fix a motorcycle, you can go to your local library and take out a book. Sure you could buy the book but the library is nice because as a resource you can get the book whenever you need it, keeping your house uncluttered. Software Libraries are very similar. We already studied what a procedure is, in lesson 3: a procedure is a list of things to do. A library is a big 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 for you that you can use without having to do the dirty work of learning the nuances of motors. The library we will be using is the Serial Library, which allows the Arduino to send data back to the computer:

What is Serial? Serial may sound like a tasty breakfast food, but its actually quite different. 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 & forth between the computer and Arduino by, essentially, setting a pin high or low. Just like we used that technique to turn an LED on and off, we can also send data. 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.

This is as good as Microsoft Visio can do, yay! (Now, people who are all geeked-out will probably get angry at this point because I'm simplifying things. Well guess what, its an Arduino tutorial, not a OSI Physical Network Architecture tutorial.) Bits & Bytes The world isn't run by weapons anymore, or energy, or money. It's run by little ones and zeroes, little bits of data. It's all just electrons. - Sneakers Now is a good time to review how data is measured. For example, we measure weight with "ounces" and "pounds" (or grams and kilograms) and distances with "inches," "feet," and "miles" (or centimeters, meters and kilometers). Information has its own system of measurements: A single bit is either a zero or a one. You can group bits together into 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) An interesting thing to note is while 1000 grams is a kilogram, nearly all computer systems consider 1024 bytes to be a kilobyte. That is, a 1.0 Kilobyte file on your computer is 1024 bytes:

Quick quiz! If your hard disk is 200 Gigabytes, how many bytes is that? Use a calculator with lots of digits! Highlight the text below for the answer

200 GB * 1024 = 204800 MB 204800 MB * 1024 = 209715200 KB 209715200 KB * 1024 = 214748364800 bytes! Hard drive makers are quite sneaky, you'll notice that they define GB as being 1000 MB, and 1 MB = 1000 KB, etc. Given this fact, how many bytes can you really store in your 200GB drive? Highlight the text below for the answer 200 GB * 1000 = 200000 MB 200000 MB * 1000 = 200000000 KB How much less storage do you get thanks to the marketing guy who came up with this trick? Highlight the text below for the answer About 4.6% less than you'd expect A familiar friend? We've actually used the Serial communications capability already quite a bit...that's how we send sketches to the Arduino! 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)

Time for our first sketch Enough chatting amongst ourselves, its time to get the Arduino talking. Our first sketch is going to be the hello world! program. When it starts up, it will say "hello world!" Create a New Sketch... and save it as HelloWorld

Into the new sketch, copy and paste the following source code, then save it
/* * Hello World! * * This is the Hello World! for Arduino. * It shows how to send data to the computer */ void setup() { Serial.begin(9600); // run once, when the sketch starts // set up Serial library at 9600 bps // prints hello with ending line

Serial.println("Hello world!"); break } void loop() { }

// run over and over again // do nothing!

OK first thing to notice is that there's nothing in the loop procedure! We've gutted it...and put some stuff into the setup procedure. Even if we have nothing in the setup or loop procedures, the Arduino requires them to be there. That way it knows you really mean to do nothing, as opposed to forgetting to include them! The first line of code in the setup procedure is this one:
Serial.begin(9600); // set up Serial library at 9600 bps

We definately see that there is a Serial thing going on, and it looks like there is a procedure call as well. This is a library procedure call. The library is called Serial and inside the library is a procedure called begin. library name Serial . . procedure (input values ; name ) begin (9600) ;

If there's no library name, it means that the procedure is in the 'default' collection of procedures we

use. For example, delay() is so common, the designers of the Arduino software didn't bother putting it into a library. So there's some mystery procedure that's called begin, well it's not too tough to figure out what it might do. It's the procedure that gets the Serial stuff ready. But what's the 9600 about? The comment says 9600 bps, and just so you know bps stands for bits-per-second (we will refer to this as the baud rate) If you have broadband connection, you may remember reading somewhere that it has, say 350 kbps download rate. This is how fast the connection can read and write bits on the wire. (Needless to say, your broadband connection can transfer data a lot faster than an Arduino!) OK so Serial.begin sets up the Arduino with the transfer rate we want, in this case 9600 bits per second. Lets move on to the next line.
Serial.println("Hello world!"); break // prints hello with ending line

This line also uses the Serial library, this time it's calling a procedure called println which is just a shorthand for "print line". Note that the 6th letter in println is the letter L not the number 1. This time the input is a quotation, the line of text we would like it to print. We use two "'s (double quotes) to indicate the beginning and end of a line of text. Quick quiz! If the Arduino transfers data at 9600 bits per second and you're sending 12 bytes of data, how long does it take to send over this information? Highlight the text below for the answer 12 bytes of data equals 12 * 8 = 96 bits of data. If we can transfer 9600 bits per second, then 96 bits takes 1/100th of a second! If the Arduino transfers data at 19200 bits per second (19200 baud) and you're sending 12 bytes of data, how long does it take to send over this information? Highlight the text below for the answer This is twice as fast as before, so it will take half the time, about 1/200th of a second. Good, now compile the sketch and upload it to your Arduino.... And then...nothing??? It looks like not much is going on here. Somewhat disappointing since we had so much fun with blinking colored lights before. The trick here is that while you can see blinking lights quite easily, seeing serial data requires a monitor, which like your display monitor will show us what data is being transfered. Lucky for us, there's a serial monitor built into the Arduino software!

I'm not quite sure what the icon means, but regardless if you click that button you will replace the black Program Notification area with a Serial Monitor. So...click it! Hello...world? What happens next is, sadly, quite dependent on which kind of Arduino you have Windows NG Arduino does not reset. Arduino resets, starts the sketch a few seconds later Mac OS X Arduino does not reset. Arduino resets, starts the sketch a few seconds later Linux Arduino does not reset. Arduino resets, starts the sketch a few seconds later

Diecimila

In the very common case of having a Diecimila Arduino, the serial monitor will auto-reset the Arduino. The sketch will start up a couple of seconds later Otherwise, the Arduino does not reset itself. Either way, once you've switched to the serial monitor, press the reset button. If you have an NG Arduino you'll have to wait 7 seconds for the sketch to start.

Voila! It is our sketch! Baud rate match up! If you ever find that you're getting a whole lot of gibberish instead of proper text, make sure that you have the correct baud rate selected in the drop down menu of the Serial Monitor. Note that this communication baud rate is indepedent of the upload process, which is fixed at 19200 bps. Next, try pressing the reset button a few times to make more Hello Worlds! appear. If you have an NG, this may be a bit annoying but do it anyways.

Each time you reset the Arduino, it performs the setup procedure, and prints out Hello again. If you look closely at the Arduino, you will also see the little TX LED blink just as it prints out this message. That's your indication that data was sent. What's Send do? When you println you are sending data from the Arduino to the computer. The Send button (and the text input next to it) are used to send data to the Arduino. We aren't going to be using it in this lesson so don't be surprised that it doesn't do anything when you click it! 10 PRINT HELLO 20 GOTO 10 Our next sketch will be a minor modification of this one. Instead of printing out Hello World just once, we'd like it to print it out over and over and over again. Quick quiz! What simple modification should we perform to make the Arduino print Hello World over and over again? Highlight the text below for the answer Simply move the Serial.println("Hello world!"); statement from the setup procedure to the loop procedure. Perform this modification and then compile and upload the new hyper-hello sketch. Then start up the serial monitor. You will see Hello World! scroll by super fast!

Quick quiz! Whats going on with the TX LED? Highlight the text below for the answer It's lit, not blinking Try waving the Arduino around in a dark room, what do you see?

Highlight the text below for the answer There are little dotted light trails What's going on here? Hint: Remember lesson 2? Highlight the text below for the answer The data is being transmitted so fast, that we can't see the TX LED blinking...it's sending data many times a second! Make the Arduino chill out a little by adding a one second delay to the sketch, so that it only prints out Hello World once a second.
/* * Hello World! * * This is the Hello World! for Arduino. * It shows how to send data to the computer */ void setup() { Serial.begin(9600); } // run once, when the sketch starts // set up Serial library at 9600 bps

void loop() // run over and over again { Serial.println("Hello world!"); // prints hello with ending line break delay(1000); }

Now you should spend some time playing with println and making it display a message of your choice! Perhaps add some more println statements in order to make the message longer? Math is hard, let's try programming! We've played around with printing out phrases, but it turns out we can also print out numbers pretty easily too.
/* * Math is fun! */ int a = 5; int b = 10; int c = 20; void setup() { Serial.begin(9600); // run once, when the sketch starts // set up Serial library at 9600 bps

Serial.println("Here is some math: "); Serial.print("a = "); Serial.println(a); Serial.print("b = "); Serial.println(b); Serial.print("c = "); Serial.println(c); Serial.print("a + b = "); Serial.println(a + b); // add

Serial.print("a * c = "); Serial.println(a * c); Serial.print("c / b = "); Serial.println(c / b); Serial.print("b - c = "); Serial.println(b - c);

// multiply // divide // subtract

void loop() its empty { }

// we need this to be here even though

Try out this sketch on your Arduino

Note that we're using 2 procedures here, the original println and now also print. The print procedure is just like println except it does not print out a "carriage return" at the end, starting a new line. You can experiment with changing the print's to println's and looking at the Serial Monitor output to verify this for yourself. Here's whats going on in the Arduino with this sketch. For example, lets look at this line:
Serial.println(a);

We've seen that if you use a quoted line of text as input to println procedure, it will display that text. In this case you can see that if you use a variable to println it will look up what that variable contains and print that out! It turns out that the Arduino is smart enough to also do math when asked:
Serial.println(a + b);

In this case, the Arduino looks at what the input to println is, and finds its actually a calculation. It looks up what a is (5) and what b is (10) and then adds them together (+) and then uses that as the value to send to println Note that for now, we can only do math using integers, which if you recall, are whole numbers. That means we can't yet print out numbers like 3.14 or 1.5. I could go on and on about operators, its all very important stuff, but many people have written good tutorials on this topic already so I'm going to send you off to read them there! A C++ tutorial (this one's pretty nice, just ignore the cout stuff which is C++'s way of printing out values) A C tutorial on operators A list of all the math operators

Pythagorean party

Let's make our first simple calculator, to calculate a hypoteneuse. If you remember from grade school, if you have a right-triangle, the hypoteneuse h can be calculated from the lengths of the two legs, c1 and c2 (which we'll call a & b) a2 + b 2 = h 2 h = (a2 + b2)
/* * Math is fun! */ #include "math.h" int a = 3; int b = 4; int h; void setup() { Serial.begin(9600); // run once, when the sketch starts // set up Serial library at 9600 bps // include the Math Library

Serial.println("Lets calculate a hypoteneuse"); Serial.print("a = "); Serial.println(a); Serial.print("b = "); Serial.println(b); h = sqrt( a*a + b*b ); Serial.print("h = "); Serial.println(h); } void loop() empty { } // we need this to be here even though its

The first thing that's new here is this line at the very beginning of the sketch:
#include "math.h" // include the Math Library header

Which basically says "We'd like to use the math procedures, which are in a library that requires us to include the file math.h where the sqrt procedure lives". Just ignore it for now, it's not important. The second thing that's different here is that when we create the variable h we don't assign it a value.

int h;

It turns out that this is totally OK, it just means that we don't know what h is going to store yet, because we're going to calculate it later. Since it's not assigned to a value upon creation, the Arduino just creates the box, the stuff inside is whatever was in left over in memory. Default values If you don't assign a value to a variable, it could be any value. Make sure you don't try to use the variable before you assign it a value! Later on in the sketch, we assign it the value.
h = sqrt( a*a + b*b );

In this line, we square a and b and then add them together, then we call the sqrt() procedure (which does exactly what you may think), to take the square root. Then we assign that to the variable h. Variable = Value ;

Whatever was in h before is lost, replaced by the new value. You can nest procedures and functions all you want, calling a procedure on the return value of another procedure. Quick quiz! Lets say you have a variable "foo" which contains a number. You'd like to find the square root of the square root of this number. What line of code would print out this value? Highlight the text below for the answer Serial.println( sqrt( sqrt(foo) ); First take the square root of foo, then take the square root of that and then use that value as the input to println Now its your turn to create a calculator. You'll create a Ohm's law calculator. Ohm's law says that Voltage = Current * Resistance. (This is a pretty useful law which forms the basis of electronics, and we'll study it in depth more later.) Starting with two variables, i for current and r for resistance, have it print out the amount of voltage that can be measured accross the resistor. Drive size calculator Let's write a program that will do that hard drive size calculation we did before. We'll start with the hard drive size in GB, and print out how many MB there are. We'll start simple, just printing out the drive size in GB
/* * Drive size calculator! */ int drive_gb = 5; void setup() { Serial.begin(9600); Serial.print("Your HD is "); Serial.print(drive_gb); Serial.println(" GB large."); // run once, when the sketch starts // set up Serial library at 9600 bps

void loop() empty { }

// we need this to be here even though its

Copy and paste this sketch into Arduino software and name the sketch DriveCalc. Then compile and upload it.

OK, lets add a section of code that will print out the number of Megabytes in the hard drive.
/* * Drive size calculator! */ int drive_gb = 5; int drive_mb; void setup() { Serial.begin(9600); Serial.print("Your HD is "); Serial.print(drive_gb); Serial.println(" GB large."); drive_mb = 1024 * drive_gb; Serial.print("It can store "); Serial.print(drive_mb); Serial.println(" Megabytes!"); } void loop() empty { } // we need this to be here even though its // run once, when the sketch starts // set up Serial library at 9600 bps

This time if you compile and upload it you should get

Which is correct, yay! Now try a few different whole numbers for the drive size, from 1 GB to 100 GB. You may notice that if you put in a 100GB drive size, something very, very strange happens:

A 100GB drive should have 102400MB in it, not some negative number. What's going on here? Introduction to types (part 1) What's happening is that we have an overflow problem. Think about your car odometer. The odometer has only 4 digits, it can display 0 miles to 9999 miles travelled. If you travel 10000 miles, the odometer will "roll over" to 0 again, and from then on it will display an incorrect value. Keeping that in mind, remember in lesson 2 we said that when we define a variable we also define the box-type of the variable? The box is where we store the data, in this case the type is int. It turns out that an int type can store only 2 bytes. Quick quiz! How many bits are in 2 bytes? Highlight the text below for the answer There are 8 bits in 1 byte so 2 bytes is 16 bits To figure out how big a number we can store in a 2 byte-sized box use a calculator and take 2 to the power of the number of bits (since each bit can store 2 values, 0 or 1). Then we subtract 1 because like in the car odometer, you can't actually display the final value, 10000. So, in this case the largest number is 216 - 1 = 65535. Since the number we're trying to store (102400) is larger than that, we see that "rollover." OK let's fix it! All we need to do is change the variable type so that it can store more than 2 bytes of data. Here is a short list of types we can use. Type byte int long
/* * Drive size calculator! */ int drive_gb = 100; long drive_mb; "long" // we changed the type from "int" to

Size (bits) 8 16 32

Size (bytes) 1 2 4

It looks like we want to use the long type. So lets make that change

void setup() { Serial.begin(9600); Serial.print("Your HD is "); Serial.print(drive_gb); Serial.println(" GB large."); drive_mb = 1024 * drive_gb; Serial.print("It can store "); Serial.print(drive_mb); Serial.println(" Megabytes!");

// run once, when the sketch starts // set up Serial library at 9600 bps

void loop() empty { }

// we need this to be here even though its

Compile and upload this sketch....then run the Serial Monitor....

Uh oh, we didn't actually fix the problem! How frustrating, we did the right thing and it still didn't work. The problem we have now is although the boxes are the right size, we're not handling them well.
drive_mb = 1024 * drive_gb;

If you look at this line, what's happening here is that the Arduino looks up the value of the variable drive_gb to get 100. Then we multiply 100 by 1024 to get 102400 and put that in the drive_mb box. Except the way that the Arduino software does this is that it creates a temporary variable the same size as drive_gb to store that calculation result before it sticks it into drive_mb. So basically we are still getting an overflow, except now its happening as we do the calculation. Here is one way to fix this insiduous bug:
/* * Drive size calculator! */ int drive_gb = 100; long drive_mb; void setup() { Serial.begin(9600); Serial.print("Your HD is "); Serial.print(drive_gb); // run once, when the sketch starts // set up Serial library at 9600 bps

Serial.println(" GB large."); drive_mb = drive_gb; drive_mb = drive_mb * 1024; Serial.print("It can store "); Serial.print(drive_mb); Serial.println(" Megabytes!"); // we need this to be here even though its

void loop() empty { }

Now when we do the calculation, the temporary result is stored in a box the same size as drive_mb (a long) instead of an int. Compile and upload this sketch to try it out

There you go, now its working! Introduction to types, part 2 It turns out that I wasn't completely honest in the previous section when I described all the different types. There's another important fact to know, and that has to do with storing negative numbers. We know that a variable that is 2 bytes large (16 bits) can store 216 different values. We assumed before that these values were 0 - 65535 inclusive. But then how do we store negative numbers? It turns out that there are two kinds of variables, signed and unsigned. Signed variables can have a positive or negative value, so you can store negative numbers. Unsigned variables can only store positive numbers. By default, variables are signed. Size (bits ) 8 8 16 16 Size (bytes) 1 1 2 2 Minimum Value 0 -128 0 -32768 Maximum Value 255 127 65535 32767

Type

unsigned byte byte unsigned int int

unsigned long long Quick quiz!

32 32

4 4

0 -2147483648

4294967295 2147483647

Lets say you have a program that stores the age of a human in years (which so far is no more than 122), whats a good data type to use? Highlight the text below for the answer You probably want to use a byte type Lets say you want to store the age of a human in seconds, what is an appropriate data type now? Highlight the text below for the answer 110 years = 3468960000 seconds. You'll need to store this in an unsigned long variable. Why Types? OK so you're probably wondering: "This is such a pain, why bother with different size types? Lets just have every variable be as big as possible and we'll never have roll-over problems." Well, on your desktop computer, with gigabytes of memory (RAM), this is a reasonable thing to do. However, the tiny tiny computer in the Arduino has a grand total of 1 Kilobyte of memory. And some of that is used for background stuff you don't see. For small sketches sure you can make everything a long and be done with it, but if you have a bigger sketch, you'll run out of memory really fast and then you'll have major problems. So in this case, every byte counts! What's weird about signed numbers is that if you reach the end of the positive value range you'll rollver into the negative values. For example, lets say you have a signed int. If you have the value 32767 in that variable, and you add 1 to the variable, you'll actually rollover to -32768.

This sketch will test out this fact:


int test = 32767; void setup() { Serial.begin(9600); // run once, when the sketch starts // set up Serial library at 9600 bps

Serial.print("Test value is: "); Serial.println(test); test = test + 1; Serial.print("Now it is "); Serial.println(test); // we need this to be here even though its

void loop() empty { }

Compile and upload to run the test.

Quick quiz! Let's say we have a variable that is byte type, it's signed by default. It starts out with the value 127 and we add one to the variable, what will the new variable value be? Highlight the text below for the answer It's a signed variable so it will roll over to -128 Let's say now it is an unsigned byte type, what happens now? Highlight the text below for the answer Since it is unsigned, it can store much more data, so it will be able to hold the value 128. If we have an unsigned byte and it starts out with the value 250 and we add 10, what will the value be? Highlight the text below for the answer Even though thie variable can store a lot, it can't store more than the number 255, so it will rollover and we'll end up with the number 4. Now it's your turn! Write some sketches that will help you understand variable sizes, try creating variables of different types and signedness and adding and subtracting. Although this lesson part seems quite boring, and severely lacking in blinky lights, understanding this stuff now will save you from a lot of headaches later when you have data overflows and your program is all wonky and you're really frustrated because you can't figure out why. (Trust me on this one!) Wrapping up, the final project! Now its time for you to expand the drive size calculator. Starting with the DriveCalc sketch, modify it so that it will also calculate how many KB are stored in the hard drive. Test it out with a couple different drive sizes. Once you've got that working, modify it again so that it will also display how much space the drive actually holds thanks to the sneaky math-trick that manufacturers use. Have the sketch display how much storage space is 'missing' (in KB) as well. Here's one possible solution:
/* * Drive size calculator! */ int drive_gb = 100; long drive_mb; long drive_kb; long real_drive_mb; long real_drive_kb;

void setup() { Serial.begin(9600); Serial.print("Your HD is "); Serial.print(drive_gb); Serial.println(" GB large."); drive_mb = drive_gb; drive_mb = drive_mb * 1024; drive_kb = drive_mb * 1024;

// run once, when the sketch starts // set up Serial library at 9600 bps

Serial.print("In theory, it can store "); Serial.print(drive_mb); Serial.print(" Megabytes, "); Serial.print(drive_kb); Serial.println(" Kilobytes."); real_drive_mb = drive_gb; real_drive_mb = real_drive_mb * 1000; real_drive_kb = real_drive_mb * 1000; Serial.print("But it really only stores "); Serial.print(real_drive_mb); Serial.print(" Megabytes, "); Serial.print(real_drive_kb); Serial.println(" Kilobytes."); Serial.print("You are missing "); Serial.print(drive_kb - real_drive_kb); Serial.println(" Kilobytes!"); // run over and over again

void loop() { }

Conclusion Good work, you got through one of the more boring lessons. In this lesson you learned how to print text and data to the Serial Monitor. This is essential for debugging future projects! You also learned about data types and storage and how to use the Arduino to calculate stuff.

Lesson 5: Buttons & switches, digital inputs, pull-up and pull-down resistors, if/if-else statements, debouncing and your first contract product design
Introduction We've done a lot so far, blinking lights, printing messages...all of that stuff is output: signals coming from the Arduino. The next step is to start playing with input, with the Arduino responding to outside events. In this lesson we will begin with the most basic kind of input, a push-button switch! What you'll need

Assembled Arduino board, preferrably a Diecimila (or whatever the latest version is) but NG is OK too

Adafruit $35

Adafruit USB Cable. Standard A-B cable is required. Any length is OK. Or any computer supply store $5

5 Red LEDs The brighter the better

Any electronics supply store $3 Any electronics supply store

6mm tact switch (pushbutton) $0.50 One 100 Resistor (brown black brown gold) Any values from 20 to 220 is probably OK.

Any electronics supply store $1

Five 1K Resistors (brown black red Any electronics gold) supply store Any values from 300 to 2K are probably OK. One 10K Resistors (brown black orange gold) Any value from 5K to 100K is probably OK. $1

Any electronics supply store $1

Adafruit $15 Arduino Prototyping Shield with tiny + Adafruit breadboard $7.50

Hookup Wire Get 22 gauge solid-core wire in red, black and some other color. Make sure its not stranded wire! Any hardware store

What's a switch? You're probably familiar with switches, there's tons of them in your house. One kind of switch you use every day is a light switch. A light switch is a simple device with two positions, on and off. When on, two wires are connected inside, which allows current to flow. When off, the two wires are disconnected.

On the left, the switch is open and no current flows. On the right, the switch is closed, current flows and the light turns on.

(thanks wikipedia!) In this photo, you can see the internals of a light switch. The two wires connect to the top and bottom. The flat bar that goes verically down the middle is what is physically moved to connect or disconnect. Light switches are great but we need something smaller. We'll be primarily using 6mm tactile button switches.

These little switches are a 1/4" on each side, cost about 25 cents, and can plug directly into a breadboard. These mechanical devices have 4 legs, which may make you think that there are 4 wires that are switched on and off, but in fact, two on each side are actually connected together inside. So really, this switch is just a 2-wire switch.

Normally, the two wires are disconnected (normally open) but when you press the little button on top, they are mechanically connected.

To get the buttons to sit better in the protoshield, you may want to straighten out the legs (just squish them with a pair of pliers) so that they look like the button on the left. Quick Quiz! Find 5 things around the house that have switches. Whats the average number of

switches per device? Light switch We're going to make our first test of the pushbutton by having it turn on and off an LED light

Fig 5.1 You'll note that the schematic symbol for a pushbutton switch is a little bit different than the one above Get out your red LED and 1.0K resistor, as well as the tiny pushbutton and build the schematic onto your protoshield:

Power up the Arduino and try pressing the button. The LED should light up when the button is held down (current is able to flow) and go dark when it's released (current is not able to flow).

Switch capability Before you try to turn a 100W lightbulb on and off using a pushbutton switch, be aware that switches have ratings that will tell you the maximum amount of current and voltage they can switch. The little switches are only rated for a few volts and milliAmps. Big switches such as wall light switches are rated for 120V and many Amperes. Make sure you choose the right switch for the job or you may accidentally cause a small fire! Quick Quiz! What does this wiring setup do? (The LED is connected to ground, but its kind of hidden in this photo) Make a guess and then build it and test your guess.

Highlight the text below to see the answer The switch is oriented so that the LED is always on! These switches have the part number B3F-1000, here is a datasheet webpage for the part. There's a lot of information, but learning how to navigate these sorts of pages is rather important. Use your detective skills to figure out the follwing: What is the maxiumum amount of current this button can switch? Highlight the text below to see the answer 50 mA What is the maximum voltage you can use this switch for? Highlight the text below to see the answer 24V What is the recommended Operating Force (how hard the button is pressed) for the B3F-1000? Highlight the text below to see the answer 0.98 Newtons (100 gf) DigitalRead Switches are great for controlling current, as shown by our little light switch demo. But they're even better as input devices! In previous lessons we set a pin on the microcontroller (say pin 13) to HIGH (5V) or LOW (ground, 0V) using the DigitalWrite procedure. Now we get to do the opposite. We will set the voltage on a pin to 5V or ground and then use DigitalRead to inquire whether that pin is HIGH or LOW For our first test, we will use a wire as our switch. Turn on the Arduino and run this little sketch
/* * Switch test program */ int switchPin = 2; // Switch connected to digital pin 2

void setup() { Serial.begin(9600); pinMode(switchPin, INPUT); read switch }

// run once, when the sketch starts // set up Serial library at 9600 bps // sets the digital pin as input to

void loop() // run over and over again { Serial.print("Read switch input: "); Serial.println(digitalRead(switchPin)); // Read the pin and display the value delay(100); }

You'll note that we have to tell the Arduino to set the pin as an input. This is pretty easy, use pinMode() but use INPUT instead of OUTPUT
pinMode(switchPin, INPUT); switch // sets the digital pin as input to read

We also use the new digitalRead() procedure, which just takes as an input the pin to examine.
Serial.println(digitalRead(switchPin)); the value // Read the pin and display

The digitalRead() procedure returns a result when its done. That result is either 0 (LOW) or 1 (HIGH) depending on what it saw when it looked at the pin's voltage. In this case, we read the pin and then pass the result as an input to another procedure, println(). Sure we could use a variable to hold the result from digitalRead() and then use that variable as input to println() but this is much more succinct.
var = digitalRead(switchPin); var Serial.println(var); var // read the pin and save it into // print out the value stored in

Now use a wire to alternate between connecting Pin 2 to 5V and Ground through a 100 resistor, and watch the serial monitor.

Fig 5.2

Switch input tied HIGH (5v)

Switch input tied LOW (ground) You should see it print out two messages depending on whether a the wire jumper connects the input to HIGH (5V) or LOW (ground) voltage. Dont forget, in digital binary land, HIGH is another word for 1 and LOW is another word for 0.

Valid inputs The best way to completely destroy a microcontroller such as an Arduino is to feed it voltages that are much too high. Make sure your input voltages are between 0 and 5V! Never connect a 9V battery directly into an input pin, it will fry the pin for good and possibly destroy the Arduino microcontroller! Whats this 100 resistor all about? There's a 100 resistor we use to connect the input pin to either HIGH or LOW voltage. Why is it there? Well, lets say you accidentally set P2 to be an OUTPUT type pin, but then you connected it to 5V. If you write a LOW to the pin (0V) but its connected to HIGH (5V), you've basically caused a short circuit at that pin. This isn't very good for the pin and could damage it! The 100 resistor acts as a buffer, to protect the pin from short circuits. Floating high above the clouds Of course, connecting and disconnecting a wire is a lot of work, and we'd like to replace that with a mechanical switch. Only thing is, our switch can only connect and disconnect two wires, it can't alternate connections.

Fig 5.3 Our two alternative switch wiring possibilities For example, in these schematics we can connect and disconnect pin 2 to 5V, or we can connect and disconnect pin 2 to ground. In both cases, as long as the button is held down, the pin is connected to a valid input voltage. When the button is released, though, pin 2 is not connected to anything. This is called a floating input voltage. Basically, it's invalid input! Try building up one of these schematics, and trying out the switch testing sketch above. When the

button is held down you should definately get the right printout. When its released, it may keep the old value, or it may change, but its certainly not reliable!

Wiring when the switch is connected to 5V

Wiring when switch is connected to ground One solution is to get a switch that alternates connections, like this one, diagrammed here.

Fig 5.4 The problem is, these switches are suprisingly complex and 10 times more expensive than a little tactile button! Instead we use a trick called a pull-down resistor.

Fig 5.5 The pull-down resistor here is the 10K resistor. When the switch is held down, the 100 resistor is connected directly to 5V. When the switch is released, the 100 resistor is connected to the 10K resistor which pulls it down to ground. Here's how to think of it: When you press the button and connect the 100 resistor to 5V, the button has a very small resistance (less than 1 !), so it provides a strong pull to 5V. The 10K resistor is also connecting the 100 resistor to ground, but since the 10K resistor has 10000 times more resistance than the button, its a very weak pull to ground and can't compete. The strong 5V connection overpowers the weak ground connection and the input pin reads HIGH. However, when the switch is disconnected, there is no longer a strong pull to 5V. In fact, its let go completely. But there is still weak pull to ground. Despite being a weak connection, it's better than nothing and so the resistor pulls the input pin to LOW. Build this circuit and try it out with the switch test sketch. It should be very reliable now! If its not working, make sure you have the right resistor values and that the parts are connected up properly.

You can also use the switch to connect the input to ground, and use a resistor as a pull-up resistor.

Fig 5.6 Try this schematic as well, and verify for yourself that the button is now reliable. Note that the strong and weak connections have nothing to do with whether the switch is configured as a pull-up or pull down. The strength of the connection comes from the fact that the button is very low resistance when held down and that the resistor is much much more resistive to current flow than the button.

Must a pullup/down resistor be 10K? You'll notice that both the Arduino schematic, and the examples here use a 10K resistor as the pullup or pulldown. Is there something special about 10K? Nope! While, it is pretty much univerally used as the 'default' value, most of the time you can use as high as 100K or as low as 4.7K. Going much lower will waste more power, going higher may give you unstable results (due to microcontroller-internals that are not that important right now). I suggest going with 10K because they are common resistor values and people reading your schematic will be more likely to understand that its 'just a pullup resistor'. Quick Quiz! With the pull-down resistor configuration, what is the value read by digitalRead() when the button is pressed? Highlight the text below to see the answer The returned value is 1 (HIGH) With the pull-down resistor configuration, what is the value read by digitalRead() when the button is released? Highlight the text below to see the answer The returned value is 0 (LOW) With the pull-up resistor configuration, what is the value read by digitalRead() when the button is pressed? Highlight the text below to see the answer The returned value is 0 (LOW) With the pull-up resistor configuration, what is the value read by digitalRead() when the button is released? Highlight the text below to see the answer The returned value is 1 (HIGH) Lets say you wanted to design a switch so that when its pressed, the value read from the pin is 1, and when it's released the value is 0. Would you use a pull-up or pull-down resistor configuration? Highlight the text below to see the answer You would want to use a pull-down resistor configuration. Here is a small part of the Arduino schematic, (you can see the whole thing here)

Fig 5.7 There is a switch and a resistor (Europeans use a rectangle instead of a squiggly for resistors), they are both connected to a pin on the Arduino microcontroller called RESET (in the bottom right corner) Is this switch connected up with a pull-up or pull-down resistor? What value is the resistor? Highlight the text below to see the answer The resistor is a 10K pull-up The switch is called S1, look on your Arduino (you may have to remove the shield to see it) to identify S1. What is S1 used for? Highlight the text below to see the answer S1 is the button you press to reset the Arduino Based on what S1 does and what you've learned about pullup/pulldown resistors, describe what you think this circuitry does, and how the RESET pin works Highlight the text below to see the answer Normally the RESET pin is pulled up to 5V. When the button is pressed, the pin is connected to ground. The Arduino microntroller resets itself when the RESET pin is connected to ground. Iffy statements The next step is to combine inputs (buttons) and outputs (LEDs). We will make a simple digitallycontrolled light. The sketch we want to write does the following When the button is pressed, the LED turns on Which we can rephrase more specifically as If the button is pressed, turn on the LED. If the button is not pressed, turn off the LED. Here is how we will wire up the switch and LED.

Fig 5.8 Build this schematic on your protoshield

Copy and paste this sketch into the Arduino software and upload it to the Arduino. Verify that when the button is pressed, the LED turns on and when the button is released, the LED turns off. If its not working, try using println statements to debug your project: when you press the button have it print out a message. That way you can tell if its the input half that isnt working or the output half.
/* * Switch and LED test program */ int ledPin = 12; int switchPin = 2; int val; // LED is connected to pin 12 // switch is connected to pin 2 // variable for reading the pin status

void setup() { pinMode(ledPin, OUTPUT); pinMode(switchPin, INPUT); } void loop(){ val = digitalRead(switchPin); val if (val == LOW) { digitalWrite(ledPin, HIGH); } if (val == HIGH) { pressed digitalWrite(ledPin, LOW); } }

// Set the LED pin as output // Set the switch pin as input

// read input value and store it in // check if the button is pressed // turn LED on // check if the button is not // turn LED off

This sketch introduces a completely new and exciting type of statement, the if statement. This is a logical statement, which you may remember from grade school math class. Basically, until now we've had the Arduino just do stuff: blink LEDs, print out messages, etc. But now we want it to make decisions. if if (test statement) ( val == LOW ) { statements to perform if test is True} { digitalWrite(ledPin, HIGH); }

The if statement is the first statement that is conditional, it only runs the statements if a condition is true. In this case, the conditions are "is the button pressed?" and "is the button not pressed?" Some Conditional Tests... Symbol Definition Usage Example if (foo == 5) { Serial.print("Foo is equal to 5"); } == Equality test Make sure you don't confuse this for the assignment operator = ! if (digitalRead(buttonPin) != LOW) { Serial.print("The button pin is not LOW "); } if ( var2 > 10 ) { Serial.print("Variable #2 is larger than 10"); } if ( chickenstock < 10 ) { Serial.print("We have less than 10 chickens in stock"); }

!=

Inequality test

>

Greater-than test

< <=

Smaller-than test

Smaller-than-or-equal-to if ( 20 <= yearstolive ) { test Serial.print("Good news, you have at least 20 years

left!"); } if ( kitten() >= 6 ) { Serial.print("The kitten() procedure returned a number larger than or equal to 6"); }

>=

Greater-than-or-equal-to test

Quick Quiz! Modify the sketch so that it does the opposite, when the button is pressed the LED turns off and when it is released it turns on. Remember to change the sketch only, use the same circuitry! Highlight the text below to see the answer Swap the lines digitalWrite(ledPin, HIGH); and digitalWrite(ledPin, LOW); Modify the sketch so that the LED blinks 5 times a second (100ms on and 100ms off) when the button is pressed and is completely off when the button is released. Highlight the text below to see the answer
int ledPin = 12; int switchPin = 2; int val; // LED is connected to pin 12 // switch is connected to pin 2 // variable for reading the pin status

void setup() { pinMode(ledPin, OUTPUT); // Set the LED pin as output pinMode(switchPin, INPUT); // Set the switch pin as input } void loop(){ val = digitalRead(switchPin); // read input value and store it in val if (val == LOW) { // check if the button is pressed digitalWrite(ledPin, HIGH); // turn LED on delay(100); digitalWrite(ledPin, LOW); // turn LED on delay(100); } }

Note that you don't need to do anything if the switchPin is HIGH because at the end of the "val == LOW" statements the LED has been turned off! Now its your turn: add another red LED and resistor to pin 11, modify the sketch so that when the button is pressed one LED is lit and the other one is off and when the button is released the first LED is off and the second LED is lit.

Fig 5.9 Try to wire up the protoshield just from the schematic. If you're having trouble, click here for a photo of the parts wired up. Here is one possible solution sketch:
/* * Switch and 2 LED test program */ int int int int led1Pin = 12; led2Pin = 11; switchPin = 2; val; // // // // LED #1 is connected to pin 12 LED #2 is connected to pin 11 switch is connected to pin 2 variable for reading the pin status

void setup() { pinMode(led1Pin, OUTPUT); pinMode(led2Pin, OUTPUT); pinMode(switchPin, INPUT); } void loop(){ val = digitalRead(switchPin); val if (val == LOW) { digitalWrite(led1Pin, HIGH); digitalWrite(led2Pin, LOW); } if (val == HIGH) { pressed digitalWrite(led1Pin, LOW); digitalWrite(led2Pin, HIGH); } }

// Set the LED #1 pin as output // Set the LED #2 pin as output // Set the switch pin as input

// read input value and store it in // check if the button is pressed // turn LED #1 on // turn LED #2 off // check if the button is not // turn LED #1 off // turn LED #2 on

Do it...or else! Having an LED turn on or off when a button is pressed is quite impressive, but it would be pretty odd if you had to press a button constantly to keep the TV on. What we want is an alternating action switch, where the press-and-release of a button does something, not just press-and-hold. Basically we want to test whether the button was just released, or just pressed.

To do this, we need to keep track of the button input value, to see if its changed. This is called the state of a button. When the state changes (an action occurs), that's when we want to perform an action.
/* * Alternating switch */ int switchPin = 2; int val; int buttonState; state void setup() { pinMode(switchPin, INPUT);

// switch is connected to pin 2 // variable for reading the pin status // variable to hold the last button

// Set the switch pin as input

Serial.begin(9600); // Set up serial communication at 9600bps buttonState = digitalRead(switchPin); // read the initial state } void loop(){ val = digitalRead(switchPin); in val

// read input value and store it

if (val != buttonState) { // the button state has changed! if (val == LOW) { // check if the button is pressed Serial.println("Button just pressed"); } else { // the button is -not- pressed... Serial.println("Button just released"); } } buttonState = val; variable } // save the new state in our

Upload it to your Arduino and try it out, watching the serial monitor as you press and release the button. Lets go through the new lines of code:
int buttonState; // variable to hold the button state

This line isn't too unusual, its just a variable that is going to hold the state of the button. Since we don't know the state of the button when the Arduino is first turned on, we will leave it as unknown (uninitialized).
buttonState = digitalRead(switchPin); // read the initial state

In the setup() procedure, we initialize (set the initial/starting value) of the button state variable by reading the button value once we've started up and set the pin to an input.
void loop(){ val = digitalRead(switchPin); in val // read input value and store it

OK now to the interesting part. In the loop procedure, we begin by first checking the button pin state and storing it an temporary variable val.
if (val != buttonState) { if (val == LOW) { // the button state has changed! // check if the button is pressed

Now we see 2 if statements that are nested, this means that we perform one test and if that test comes out true we go on to perform another test. This is more complex than a simple if statement but not much more different than the kinds of decisions we make all the time. For example:
if ( it is raining ) { falling on me? if ( I have an umbrella ) { OpenUmbrella(); opening procedure } } // look up, is there water // check my purse // Perform the umbrella

Of course, we can't open the umbrella if we don't have one. And there's no point in checking if we have one if its not raining! In the first if statement, we check if the current button state (HIGH or LOW) is different than the last time we looked at the button. If it is different (tested by the != inequality operator ) then we execute the next group of statements, enclosed by the {} braces. Lets move on and examine the new statement we see, which is the exotic if-else statment.
if (val == LOW) { // check if the button is pressed Serial.println("Button just pressed"); } else { // the button is -not- pressed... Serial.println("Button just released"); }

This statement is easy to understand: before, we would run a test and if that test passed, we would perform the statements in the {} braces. Now we also have an alternative, which is what we should do if the test fails! Now we used to perform two tests, one for (val == LOW) and one for (val == HIGH). This code is equivalent but its a little more straightforward. If its not LOW it must be HIGH. if if (test statement) ( val == LOW ) { statements to perform if test is True} { ... } else else { statements to perform if test is not True} { ... }

In the if-else statement, we simply examine val to deterimine if the last digitalRead() procedure informed us that the button is currently pressed or not pressed.
buttonState = val; variable // save the new state in our

Finally, we make sure that we've updated the button state variable with the current state. Quick Quiz! Remove (or comment out) the line that says "buttonState = val;" from the sketch and re-upload it to the Arduino. What happens now? Highlight the text below to see the answer When the button is held down, the Arduino prints out "Button just pressed" over and over again. When its released, nothing is printed Why does this happen? Go through the sketch, keeping track of what buttonState and val are storing at each line. Highlight the text below to see the answer

When the Arduino starts up, it sets buttonState to LOW (assuming the button isn't pressed as it is reset). Whenever the button pin is read as HIGH the (val != buttonState) test is true and it prints out a message. The buttonState is never set to HIGH so it never prints "Button is released" and it always passes the (val != buttonState) test Counting presses A pretty useful techinque you'll want to add to your collection of sketch-knowledge is how to keep track of button presses. Try this sketch
/* * Counting presses */ int switchPin = 2; int val; int buttonState; int buttonPresses = 0; pressed void setup() { pinMode(switchPin, INPUT);

// // // //

switch is connected to pin 2 variable for reading the pin status variable to hold the button state how many times the button has been

// Set the switch pin as input

Serial.begin(9600); // Set up serial communication at 9600bps buttonState = digitalRead(switchPin); // read the initial state } void loop(){ val = digitalRead(switchPin); in val

// read input value and store it

if (val != buttonState) { // the button state has changed! if (val == LOW) { // check if the button is pressed buttonPresses++; // increment the buttonPresses variable Serial.print("Button has been pressed "); Serial.print(buttonPresses); Serial.println(" times"); } } buttonState = val; // save the new state in our variable }

We've added one new thing in this sketch, which is the ++ operator. Simply, the statement "buttonPresses++" increments (adds 1 to) the buttonPresses variable. This is a shortcut for "buttonPresses = buttonPresses + 1". Quick Quiz! Modify the sketch so that message is only printed when the button is released, not when it's pressed. Highlight the text below to see the answer Change the "val == LOW" test to "val == HIGH" Modify the sketch so its a countdown device! Step 1. Have the buttonPresses variable start at 10. Step 2. Every time the button is pressed, decrement the buttonPresses variable (use the -operator, which does the opposite of ++). Step 3. Once you have that working, have the Arduino print out "We have x presses to go till takeoff!" where x is the number of presses remaining, but only if the number of presses left

is larger than 0 (check the conditional test table above to see how to test if a variable is larger than a number) Step 4. Once you have that working, make the Arduino print out "EXPLODE!" on the last button press.

Highlight the text below to see one possible answer


/* * Takeoff! */ int int int int switchPin = 2; val = 0; buttonState; buttonPresses = 10; // // // // switch is connected to pin 2 variable for reading the pin status variable to hold the button state 10 presses to go!

void setup() { pinMode(switchPin, INPUT);

// Set the switch pin as input

Serial.begin(9600); // Set up serial communication at 9600bps buttonState = digitalRead(switchPin); // read the initial state } void loop(){ val = digitalRead(switchPin); // read input value and store it in val

if (val != buttonState) { // the button state has changed! if (val == LOW) { // check if the button is now pressed buttonPresses--; if (buttonPresses == 0) { Serial.println("EXPLODE!"); } if (buttonPresses > 0) { Serial.print("We have "); Serial.print(buttonPresses); Serial.println(" presses to go till takeoff!"); } } buttonState = val; // save the new state in our variable }

Design challenge, part 1 The phone rings, and you pick it up! Voice: Hello, this is the president of Blinky Lite Fun Company Inc., a company that

specializes in blinky light products. We're noticing that a majority of our customers ride bicycles and they'd like to be more safe. We're thinking of offering a bicycle safety light and we hired an electrical engineer to design a light for us. However, he decided to go on a week-long kite surfing expedition and has left us in the lurch. Here is the schematic we found on his desk:

All the bike light has to do is turn on when the button is clicked and turn off the next time the button is clicked. Can we hire you to finish the project? You: Sure, this is not a problem, I'll send you over a contract and get started as soon as the documents are signed! The contracts are faxed and signed and now it's time to do your job. Here is a video demonstrating the functionality the customer wants

Click To Play play_blip_movie_463022();Step 1. Wire up the 5 red LEDs onto your breadboard as shown in the schematic. Use jumpers when necessary to connect all of cathodes (the negative pin of the LED) to ground. If you're having trouble figuring out the wiring, click here for a high-res photo. Step 2. Test the LEDs. Write a simple sketch to verify you've wired them up correctly by blinking all the LEDs. Step 3. Wire up the switch as shown (or if its already on the breadboard from the previous projects, leave it as is). If you're having trouble figuring out the wiring, click here for a high-res photo. Step 4. Test the switch. Modify an earlier sketch in this lesson so that when the button is held down, all of the LEDs turn on. When the button is released the LEDs turn off Step 5. Adapt the "Counting Presses" sketch Instead of a variable called buttonPresses you have a variable called lightMode, which starts at 0 (off). The lightMode variable will keep track of the bike light state. When the button is

clicked, check the lightMode value. If it is 0 (off), set it 1 (on) and turn on all the LEDs, otherwise set it 0 (off) and turn off all the LEDs. Highlight the text below to see a hint When the button is pressed, use an if-else statement like this: if (lightMode == 0) { <some stuff goes here> } else { <some other stuff goes here> } Here is one possible solution sketch:
/* * */ int int int int int Bike light, revision 1 led1Pin led2Pin led3Pin led4Pin led5Pin = = = = = 12; 11; 10; 9; 8; // switch is connected to pin 2 // variable for reading the pin status // variable to hold the button state // Is the light on or off?

int switchPin = 2; int val; int buttonState; int lightMode = 0; void setup() { pinMode(switchPin, INPUT); pinMode(led1Pin, pinMode(led2Pin, pinMode(led3Pin, pinMode(led4Pin, pinMode(led5Pin, OUTPUT); OUTPUT); OUTPUT); OUTPUT); OUTPUT);

// Set the switch pin as input

Serial.begin(9600); // Set up serial communication at 9600bps buttonState = digitalRead(switchPin); // read the initial state } void loop(){ val = digitalRead(switchPin); if (val != buttonState) { if (val == LOW) { if (lightMode == 0) { lightMode = 1; digitalWrite(led1Pin, digitalWrite(led2Pin, digitalWrite(led3Pin, digitalWrite(led4Pin, digitalWrite(led5Pin, } else { lightMode = 0; digitalWrite(led1Pin, digitalWrite(led2Pin, digitalWrite(led3Pin, digitalWrite(led4Pin, digitalWrite(led5Pin, } } } buttonState = val; }

// read input value and store it in val // // // // the button state has changed! check if the button is pressed light is off light is on!

HIGH); HIGH); HIGH); HIGH); HIGH); LOW); LOW); LOW); LOW); LOW); // light is on!

// save the new state in our variable

Brooklyn Debounce The phone rings, and you pick it up! Voice: Hello, this is the president of the Blinky Lite Fun Company Inc., thanks for getting us that bicycle light prototype so quickly. It works pretty well, but we have found a bug in your design. It turns out that every once in a while, when we press the button, the light doesn't turn on or off. Here is a video demonstrating the problem. Can you fix this? We'll send you the check next week, thanks! You play a little bit with the bike light prototype and find that, yes, this is a problem. (You should try it out, although depending on your button you may or may not see this problem occur, it is a sneaky bug)

Click To Play play_blip_movie_463045();You spend some time looking over your code but can't seem to find the problem. Turns out this is not a software (sketch) problem, but actually a mechanical problem. Inside the little tactile switch is a small disc spring. When you push the button you squeeze the spring so that it makes contact with the two wire connections. When you release, the spring bounces back. This works great except that, well, the spring is springy. And that means that once in a while, when you press the button it bounces around a little in the switch, making and breaking contact a few times before settling. If you have a oscilloscope, you can look at the input to the Arduino pin in detail to see the "bouncing" in action. Here is a screencapture from my Tektronix scope

The X axis is time. Each dotted line lengthwise indicates 250 microseconds (.25 milliseconds) The Y axis is voltage. The center is 0 volts (ground) and each dotted line indicates a change of 2V. In this image you can see how when the button is released, the voltage into the input pin starts at ground (LOW), then there are some spikes and finally it goes up to 5V (HIGH). Most of the time, there are no spikes, but once in a while they do occur. This is called a contact bounce! Remember! The bounces don't occur when the button is held down or not pressed. They only occur during the press or release of a button. This causes our sketch to hiccup because every once in a while, there's a bounced switch, and when the Arduino checks the pin it thinks that the user pressed and depressed the switch many times. Thus the light turns on for a few microseconds, and then turns off. How to solve this problem? Well there are some very fancy techniques one can use to debounce a button but there's also a dead-simple one: adding a delay. You'll notice that the bounces only occur for half a millisecond. That means that we can check the button twice, at least 1 millisecond apart. If the two readings are different, that means there could have been a bounce. If the two readings are the same, that means that the switch has settled on the value. We'll require that the two readings must read the same before we perform the rest of the sketch. We'll also use a much more generous 10 millisecond delay, which will take care of even the most bouncy of switches.
/* * Bike light, debounced */ int switchPin = 2; int led1Pin = 12; int led2Pin = 11; // switch is connected to pin 2

int led3Pin = 10; int led4Pin = 9; int led5Pin = 8; int val; int val2; delayed/debounced status int buttonState; int lightMode = 0; void setup() { pinMode(switchPin, INPUT); pinMode(led1Pin, pinMode(led2Pin, pinMode(led3Pin, pinMode(led4Pin, pinMode(led5Pin, OUTPUT); OUTPUT); OUTPUT); OUTPUT); OUTPUT); // variable for reading the pin status // variable for reading the // variable to hold the button state // Is the light on or off? // Set the switch pin as input

Serial.begin(9600); // Set up serial communication at 9600bps buttonState = digitalRead(switchPin); // read the initial state } void loop(){ val = digitalRead(switchPin); // read input value and store it in val delay(10); // 10 milliseconds is a good amount of time val2 = digitalRead(switchPin); // read the input again to check for bounces if (val == val2) { // make sure we got 2 consistant readings! if (val != buttonState) { // the button state has changed! if (val == LOW) { // check if the button is pressed if (lightMode == 0) { // is the light off? lightMode = 1; // turn light on! digitalWrite(led1Pin, HIGH); digitalWrite(led2Pin, HIGH); digitalWrite(led3Pin, HIGH); digitalWrite(led4Pin, HIGH); digitalWrite(led5Pin, HIGH); } else { lightMode = 0; // turn light off! digitalWrite(led1Pin, LOW); digitalWrite(led2Pin, LOW); digitalWrite(led3Pin, LOW); digitalWrite(led4Pin, LOW); digitalWrite(led5Pin, LOW); } } } buttonState = val; // save the new state in our variable } }

Here is the important, new section of code we added:


int val; int val2; // variable for reading the pin status // variable for reading the

delayed/debounced status int buttonState; void loop(){ val = digitalRead(switchPin); in val delay(10); amount of time val2 = digitalRead(switchPin); for bounces if (val == val2) { readings! if (val != buttonState) { changed!

// variable to hold the button state // read input value and store it // 10 milliseconds is a good // read the input again to check // make sure we got 2 consistant // the button state has

Now we have used a delay() procedure call to space out our input readings. We take two readings and compare them to make sure that the switch has settled on whatever value we read. If there's a bounce, it'll get filtered out by our delay. Try it out and see if it helps make your bike light more reliable. Note that this line
buttonState = val; variable // save the new state in our

is in the if statement that makes sure the two input reads are the same. You should not consider the val variable to hold valid information unless you've verified it against the second read, val2. Otherwise you will get strange performance Design Challenge, part 2 The phone rings, and you pick it up! Voice: Hello, this is the president of Blinky Lite Fun Company Inc., your correction has solved our flaky light problem. The bike light works great. Only thing is, its just not, well, blinky enough! And this is the Blinky Lite Fun Company Inc. Can you make the light more blinky? We'll send you the check next week, kthxbye! Well, OK that shouldn't be too hard. You modify the debounced sketch so it looks like this:
/* * Bike light, blinky */ int int int int int int switchPin led1Pin = led2Pin = led3Pin = led4Pin = led5Pin = = 2; 12; 11; 10; 9; 8; // switch is connected to pin 2

int val; int val2; delayed/debounced status int buttonState; int lightMode = 0; void setup() { pinMode(switchPin, INPUT); pinMode(led1Pin, OUTPUT); pinMode(led2Pin, OUTPUT);

// variable for reading the pin status // variable for reading the // variable to hold the button state // Is the light on or off? // Set the switch pin as input

pinMode(led3Pin, OUTPUT); pinMode(led4Pin, OUTPUT); pinMode(led5Pin, OUTPUT); Serial.begin(9600); // Set up serial communication at 9600bps buttonState = digitalRead(switchPin); // read the initial state } void loop(){ val = digitalRead(switchPin); in val delay(10); amount of time val2 = digitalRead(switchPin); for bounces if (val == val2) { readings! if (val != buttonState) { changed! if (val == LOW) { pressed if (lightMode == 0) { lightMode = 1; digitalWrite(led1Pin, digitalWrite(led2Pin, digitalWrite(led3Pin, digitalWrite(led4Pin, digitalWrite(led5Pin, delay(100); digitalWrite(led1Pin, digitalWrite(led2Pin, digitalWrite(led3Pin, digitalWrite(led4Pin, digitalWrite(led5Pin, delay(100); } else { lightMode = 0; // turn light off! // No need to do anything because the light is 'off' when it finishes with mode 1 } } } buttonState = val; // save the new state in our variable } } LOW); LOW); LOW); LOW); LOW); // read input value and store it // 10 milliseconds is a good // read the input again to check // make sure we got 2 consistant // the button state has // check if the button is // is the light off? // turn light on! HIGH); HIGH); HIGH); HIGH); HIGH);

// blink on!

// blink off!

You are feeling pretty proud because you remembered that you did not have to turn off the LEDs when entering the off mode: they're off at the end of the blinky code that is run when lightMode is 1. Upload this sketch to your bike light and try it out. Quick quiz! Does this sketch work correctly? Highlight the text below to see the answer

No! What does it do? Highlight the text below to see the answer When the button is pressed to turn the light on, it only blinks once. Use println() procedure calls and your brain to try and figure out why the sketch acts this way. What happens just after the button is pressed to turn the light on? What happens the next time the loop() procedure runs? Highlight the text below to see the answer When the button is just pressed, the if statement conditions are true and the light mode changes form 0 (off) to 1 (on). The LEDs are then turned on for 100ms and then off for 100ms. However, next time the loop() procedure runs, the if conditionals are false (the button state has not changed) and so the code that would blink the LED is not run again. Thus the single blink. The trick here is that you want to split up your loop() procedure into two sections. The first section will do all the button checking and debouncing stuff. It will also determine whether the button state has changed and if so, it will change the lightMode variable appropriately. Once that dirty work has been done, the next section of code will examine the lightMode variable and then perform the correct actions for that mode. Try to fix the code above so it does the right thing. Here is one solution:
/* * Bike light, revision 3: blinky */ int int int int int int switchPin led1Pin = led2Pin = led3Pin = led4Pin = led5Pin = = 2; 12; 11; 10; 9; 8; // switch is connected to pin 2

int val; int val2; status int buttonState; int lightMode = 0; void setup() { pinMode(switchPin, INPUT); pinMode(led1Pin, pinMode(led2Pin, pinMode(led3Pin, pinMode(led4Pin, pinMode(led5Pin, OUTPUT); OUTPUT); OUTPUT); OUTPUT); OUTPUT);

// variable for reading the pin status // variable for reading the delayed // variable to hold the button state // What mode is the light in? // Set the switch pin as input

Serial.begin(9600); // Set up serial communication at 9600bps buttonState = digitalRead(switchPin); // read the initial state } void loop(){ val = digitalRead(switchPin); in val // read input value and store it

delay(10); amount of time val2 = digitalRead(switchPin); for bounces if (val == val2) { readings! if (val != buttonState) { changed! if (val == LOW) { pressed if (lightMode == 0) { lightMode = 1; } else { lightMode = 0; } } } buttonState = val; variable }

// 10 milliseconds is a good // read the input again to check // make sure we got 2 consistant // the button state has // check if the button is // light is off // turn light on! // turn light off!

// save the new state in our

// Now do whatever the lightMode indicates if (lightMode == 1) { digitalWrite(led1Pin, HIGH); digitalWrite(led2Pin, HIGH); digitalWrite(led3Pin, HIGH); digitalWrite(led4Pin, HIGH); digitalWrite(led5Pin, HIGH); delay(100); digitalWrite(led1Pin, LOW); digitalWrite(led2Pin, LOW); digitalWrite(led3Pin, LOW); digitalWrite(led4Pin, LOW); digitalWrite(led5Pin, LOW); delay(100); } // If lightmode is 0, we dont have to do anything because the LEDs are already off! }

Design Challenge, part 3 The phone rings, and you pick it up! Voice: Hello, this is the president of Blinky Lite Fun Company Inc., I love the blinking light, its just so me! But, OMG, our competitor just brought a bike light into the market that has 4 modes. We can't compete with them in the free market if we only have this lame bike light. We need more blinky, flashy light modes. Also, please make our logo bigger. We'll send you the check next week, for reals! The final design challenge is to take the sketch from Design Challenge 2 and upgrade it to have at least 4 modes: off, all-on, blinking LEDs, and 'wave'.

Click To Play play_blip_movie_466034();First, modify the first half of the sketch so that pressing the button cycles through all the modes, from mode 0 to mode 3. Use println() procedure calls to verify that you are successfully changing between all of the

modes Need a Hint? Highlight the text below to see a clue With only two modes, you can use an if-else statement, but with more than two, you'll need to handle multiple possibilities. Turns out that just like you can nest if statements, you can also nest if-else statements!
if ( condition1 ) { do this; } else { if (condition2) { do that; } else { if (condition3) { jump around; } } }

After that is working, modify the second half of the sketch so that it performs the different effects for each mode. Here is an example of the finished project code
/* * Bike light, final version */ int int int int int int switchPin led1Pin = led2Pin = led3Pin = led4Pin = led5Pin = = 2; 12; 11; 10; 9; 8; // switch is connected to pin 2

int val; int val2; status int buttonState; int lightMode = 0; void setup() { pinMode(switchPin, INPUT); pinMode(led1Pin, pinMode(led2Pin, pinMode(led3Pin, pinMode(led4Pin, pinMode(led5Pin, OUTPUT); OUTPUT); OUTPUT); OUTPUT); OUTPUT);

// variable for reading the pin status // variable for reading the delayed // variable to hold the button state // What mode is the light in? // Set the switch pin as input

Serial.begin(9600); // Set up serial communication at 9600bps buttonState = digitalRead(switchPin); // read the initial state } void loop(){ val = digitalRead(switchPin); in val delay(10); amount of time // read input value and store it // 10 milliseconds is a good

val2 = digitalRead(switchPin); // read the input again to check for bounces if (val == val2) { // make sure we got 2 consistant readings! if (val != buttonState) { // the button state has changed! if (val == LOW) { // check if the button is pressed if (lightMode == 0) { // if its off lightMode = 1; // turn lights on! } else { if (lightMode == 1) { // if its all-on lightMode = 2; // make it blink! } else { if (lightMode == 2) { // if its blinking lightMode = 3; // make it wave! } else { if (lightMode == 3) { // if its waving, lightMode = 0; // turn light off! } } } } } } buttonState = val; // save the new state in our variable } // Now do whatever the lightMode indicates if (lightMode == 0) { // all-off digitalWrite(led1Pin, LOW); digitalWrite(led2Pin, LOW); digitalWrite(led3Pin, LOW); digitalWrite(led4Pin, LOW); digitalWrite(led5Pin, LOW); } if (lightMode == 1) { // all-on digitalWrite(led1Pin, HIGH); digitalWrite(led2Pin, HIGH); digitalWrite(led3Pin, HIGH); digitalWrite(led4Pin, HIGH); digitalWrite(led5Pin, HIGH); } if (lightMode == 2) { // blinking digitalWrite(led1Pin, HIGH); digitalWrite(led2Pin, HIGH); digitalWrite(led3Pin, HIGH); digitalWrite(led4Pin, HIGH); digitalWrite(led5Pin, HIGH); delay(100); digitalWrite(led1Pin, LOW); digitalWrite(led2Pin, LOW); digitalWrite(led3Pin, LOW); digitalWrite(led4Pin, LOW); digitalWrite(led5Pin, LOW); delay(100); } if (lightMode == 3) { // "wave" digitalWrite(led5Pin, LOW); digitalWrite(led1Pin, HIGH); delay(50);

digitalWrite(led1Pin, digitalWrite(led2Pin, delay(50); digitalWrite(led2Pin, digitalWrite(led3Pin, delay(50); digitalWrite(led3Pin, digitalWrite(led4Pin, delay(50); digitalWrite(led4Pin, digitalWrite(led5Pin, delay(50); digitalWrite(led5Pin, } }

LOW); HIGH); LOW); HIGH); LOW); HIGH); LOW); HIGH); LOW);

For extra credit, come up with with some more flashy modes, and post your video to the forums For triple-word-extra credit, use the 9V battery pack to power your Arduino bike light and duct tape it to your shirt! Conclusion blah blah blah

Lesson 6: Wiring up an LCD to an Arduino

Arduino Tutorial Wiring up an LCD to an Arduino Intro Starting Lesson 0 Lesson 1 Lesson 2 Lesson 3 Lesson 4 Lesson 5 LCDs HELP!!! Buy stuff Forums

Home

About ladyada.net Portfolio Research Press Publication & Presentation Photos Wiki (backend) Projects Arduino Ethernet Shield GPS Shield Proto Shield Motor Shield Wave Shield BoArduino DIGG Button Drawdio Fuzebox Game Grrl Game of Life MIDIsense MiniPOV2 MiniPOV3 MintyMP3 MintyBoost SIM Reader SpokePOV TV-B-Gone USBtinyISP Wattcher Wave Bubble x0xb0x XBee YBox2 Quickies Halloween Pumpkin Vintage Bike Lite Kite Arial Photo Bike Stand LiIon Bike Lite More... ->Instructables Learn Arduino tutorial AVR tutorial Multimeter tutorial Soldering tutorial

Library Arduino Hacks Batteries E.E. Tools Find Parts Kits Laser uC Annoyances Open Source Hardware PCB Design & Tips PIC vs. AVR Blog Store Forums

ladyada.net Introduction

Search

This is a bit of a side note, there's no LCD included with the Arduino starter pack, but I figure its a popular request, so here we go! What you'll need

Assembled Arduino board, preferrably a Diecimila (or whatever the latest version is) but NG is OK too

Adafruit $35

Adafruit USB Cable. Standard A-B cable is required. Any length is OK. Or any computer supply store $5

2 pieces of 7-pin female header (you can always cut down longer header)

Any electronics supply store $3

2 pieces of 7-pin male header (you can always cut down longer header).

Any electronics supply store $0.50

Arduino Prototyping Shield kit, without breadboard!

Adafruit $15

Character LCD with parallel interface

Pretty much any online electronics shop!

Hookup Wire Make sure its not stranded wire! Any hardware store

Annie, get yer LCD The first step is to get the LCD you want. Parallel LCDs come in a couple different sizes, from 16 characters, 1 line (16x1) to 24 characters, 4 lines (24x4).

In this tutorial I use the 16x2 Picvue from Jameco because thats what was I had in my box of stuff, but you can easily adapt it for any other LCD. The wiring may differ a little bit but that will be covered. Check out the pins The first step is to turn over the LCD and check out the pins. Parallel LCDs almost always have 14 or 16 pins. In this model they are all the way to the left, near the label J1. I soldered 2 7-pin female headers for e-z plugging. Somtimes the pins are along the bottom all in a row.

Look closely at the header for the numbers that show which pins are which. In this model, the first pin is at the top right, the second pin is top left, etc till pin 14 in the bottom left.

When the LCD is flipped over, the pinout will be mirrored, to help me keep track of it, I made a diagram: 1 3 5 7 9 11 2 4 6 8 10 12

13

14

Whatever your pinout is, make sure you have a diagram written out since you will need to refer to it many times! Header up!

OK now that we are diagrammed out, I took the protoshield and soldered 2 7-pin headers at one end of the pcb. Note that they are not all the way to the edge, I left one row of holes so I could easily solder some wires. I also soldered a short piece of header (that comes with the shield kit) at the left so that the LCD will be propped up.

You can now do a test fit to verify how it will look. it hangs over a bit but thats OK by me

Shave & a haircut, 4 bits! Since this is a parallel LCD, data will be sent to it over a parallel interface. That is, multiple bits at a time. These LCDs are designed for either a 8-bit or 4-bit interface. Since we'd like to save pins, lets go with the 4-bit interface! The data pins are name D4, D5, D6, and D7. Double-check your datasheet but almost all parallel LCDs have these pins numbered 4, 3, 2, and 1 respectively. 1 (D7) 3 (D5) 5 7 9 (ENABLE) 11 (RS) 13 (GND/VSS) 2 (D6) 4 (D4) 6 8 10 (R/W) 12 (CONTRAST) 14 (+5V/VDD)

There's a lot of wiring to be done but we're going to go thru it very slowly so it shouldn't be too bad. Lets connect these to the arduino thusly: D4 -> Arduino pin #7, D5 -> Arduino pin #8, D6 -> Arduino pin #9, D4 -> Arduino pin #10

Since I wasnt sure of the wiring, I used the sockets on the protoshield. Once I test and verify they are correct, I'll solder them in! Next are the two power wires. Parallel LCDs run off of +5V so you can just solder the Vcc wire to 5V and the ground wire to GND.

Next are the 2 control wires, ENABLE and RS which we connect to pins 12 and 11 respectively.

Theres another control line called R/W that you can use to control whether you're reading or writing to the LCD. Since we'll just be writing, that pin can be connected to ground, saving another arduino pin

The last wire is the contrast control, we need to connect a potentiometer to this to make the display visible. I dont know the specifics of the input current but I used a 10K potentiometer and it worked great. One pin is connected to +5V, the pin on the other side is connected to ground and the middle pin is connected to the contrast line.

Now place the LCD on top. Looks good!

Make sure you finish up the rest of the shield so you can plug it into an arduino. At least solder in the male headers. Test 1 Our first test will be just to connect it up to power and see what happens. Plug it into an Arduino and power it up. You should see the following:

Make sure you tweak the contrast potentiometer, if the contrast is all the way down you may not see anything Install LCD4bit library Next you'll want to install the LCD4bit library, so download it from the Arduino playground Uncompress and install the library by dragging the files into the hardware/libraries folder inside your Arduino installation

The inside of the LCD4Bit folder:

Open up LCD4Bit.cpp with a text editor such as WordPad and scroll down to the part where the pins used are defined

Make sure the Enable pin is set to 12 and the RS pin is 11. USING_RW should be set to false, as well. Froots! Finally, start up your Arduino software, and select from the menu: Sketchbook->Examples->Library-LCD4Bit->LCD4BitExample Upload the sketch to your Arduino with the LCD attached, you should see a randomized list of fruits!

Hooray! You're ready to start printing your own messages. Check out the example code to see how this is done, then just copy and paste the code into your own project.

Appendix: HELP!
HELP! While Arduino is a nice little system, there's a lot of bugs. Hopefully they'll be fixed soon, but until then, here's problems you're likely to run into. I'm using Vista and... Sorry pal, but Arduino and the avr-gcc/avrdude backend are pretty much not Vista-ready. Try XP/2000 which is much more likely to work! avrdude: stk500_getsync(): not in sync: resp=0x00 If you get the following error message "avrdude: stk500_getsync(): not in sync: resp=0x00" that means that the Arduino is not responding. There are literally dozens of reasons this could be.

Check the following: If you have a NG Arduino, did you press reset just before selecting Upload menu item? Is the correct Serial Port selected? Is the correct driver installed? Is the chip inserted into the Arduino properly? (If you built your own arduino or have burned the bootloader on yourself) Does the chip have the correct bootloader on it? (If you built your own arduino or have

burned the bootloader on yourself) Note that it is nearly impossible for anyone to debug this, as there are so many possible issues. Try everything. java.lang.NullPointerException at processing.app.Serial.setDTR If you get the following error message java.lang.NullPointerException at processing.app.Serial.setDTR(Serial.java:480)

It means you dont have a serial port selected, go back and verify that the correct driver is installed (lesson 0) and that you have the correct serial port selected in the menu. This is a bug in Arduino and will hopefully be fixed in v10. avrdude: Expected signature for ATMEGA is ... If you get the following error avrdude: Expected signature for ATMEGA is ...

Then you have either the incorrect chip selected in the Tools menu or the wrong bootloader burned onto the chip ser_send(): write error: sorry no info avail (no screenshot as I can't reproduce it) You have the wrong serial port selected. Make sure the driver is installed and you have the correct serial port number, see lesson 0. avrdude: can't open device "COM10": The system cannot find the file specified If you get the following error: avrdude: can't open device "COM10": The system cannot find the file specified (under Windows, COM port value may vary)

It means that you have too many COM ports. Say maybe you've got 9 Arduinos, each one has a unique serial number so when it's plugged in it gets its own COM port. However that COM port sits around even when the Arduinos are not plugged in. Thus every time you plug in a new USB-serial device the COM number goes up and up until its too high. You should make sure that the port is numbered as low as possible. You can use a program like FTClean to clear out old COM ports you aren't using anymore. Once you've cleaned out the ports, you'll have to reinstall the driver again (see lesson 0). Alternately, if you're sure that the ports are not used for something else but are left over from other USB devices, you can simply change the COM port using the Device Manager. Select the USB device in the Device Manager, right click and select Properties

Then click Advanced... and in the next window change the COM port to something like COM4 or COM5.

Don't forget to select the new port name in the Arduino software. The lower port names may say (in use) but as long as the other USB devices aren't plugged in, it shouldn't be a problem using them. This is a little riskier than just using FTClean...so I'd go for that first. This is a bug in Arduino and will hopefully be fixed in v10.