Digilent
    
Products
Support
Classroom
Services
Showcase
About Us
My Cart
Products
Services
Academic Kits
Enter Value Code:

Blinking an Onboard LED
Blinking an Onboard LED:

Creation of a Sketch to Blink an LED





Introduction

Related material:
In the Introduction to MPIDE project, you used an example sketch that was provided in MPIDE to blink one of the on-board LEDs (light emitting diodes). The LED that blinked on the Uno32 board is depicted in Fig. 1. (Although Fig. 1 shows an Uno32, the code you write for this project can be used equally well with the uC32 and Max32 chipKIT boards.) In this project, the goal is once again to obtain a sketch that will blink the same on-board LED, but rather than loading an example, we now want to write the sketch ourselves—and understand what we wrote! You will also become more familiar with MPIDE along the way. Before beginning, you should be aware that chipKIT boards are digital devices. If you don't know what distinguishes digital devices and digital signals from analog ones, please read the material available via the box on the right.



Figure 1. Uno32 with pin 13 set to HIGH. This causes the LED tied to this pin to be illuminated.
Before you begin, you should:   After you're done, you should:
  • Work through the Introduction to MPIDE project.
  • Understand how to download a sketch from MPIDE to a chipKIT board.
  • Understand the difference between digital and analog signals.
 
  • Understand basic C syntax.
  • Understand the minimum requirements for a sketch.
  • Be familiar with some of the common functions used interact with the chipKIT board, such as pinMode() and delay().
  • Know how to access the chipKIT reference material.
  • Be able to blink an onboard LED at different rates.

Programming Basics

The language that MPIDE uses is based on the C++ programming language (read C++ as “C-plus-plus”). C++ was developed from the language C, which dates back to the late 1960's. C++ subsumes C, meaning that everything you can do in C, you can do with equivalent statements in C++. However, the converse is not true. If you are not familiar with either C or C++, you should read the introductory material available via the boxes to the right.

In C++, every program must have a function named main(). However, unlike in C++, in MPIDE you do not write a main() function yourself because one has already been written for you. In fact, not only has one been written for you, but you do not have access to it. Instead, you must write two functions: setup() and loop(). (When we write the name of a function, the name will be followed by a set of parentheses. As you will see, when you “call” or invoke a function in your sketches, the function name must be followed by parentheses [that may or may not include something]. Thus, in the text, we use parentheses to emphasize that we are talking about a function.)

The setup() function is run once at the start of execution of your sketch (when your sketch first starts to run). The statements in this function are typically used to perform “one-time” set-up operations, such as specifying which pins should be used for input or output or specifying the speed of communication between your chipKIT board and the computer.



Figure 3. Depiction of the flow of execution in a sketch.
In contrast, the loop() function is called “repeatedly.” By repeatedly, we mean that after all the statements in the function have been executed and the function returns, the function is immediately called again. This cycle repeats until the board loses power or until it is reprogrammed. The flow of execution of a sketch is illustrated in Fig. 3. Each rectangular box represents a function. After all the statements in the setup() function have been executed, the flow of execution moves to the loop() function. After all the statements in this function have been executed, they are executed again. As you will soon see, functions can be “called” from within other functions. So, for example, any number of functions can be called from within the loop() function and thus these functions will be executed each time loop() is executed.

You have undoubtedly noticed that certain words or pieces of computer code have been highlighted using different colors. This highlighting is done within MPIDE to help indicate the way in which the particular term is used. For example, the blue that is used for HIGH and LOW indicates that these are “constants” whose values cannot be changed. The highlighting used within MPIDE is used throughout the text of these projects as well. (Although the details of the highlighting are somewhat outside of the scope of our current interests, roughly speaking, blue is used for “literals” [information that is entered directly into the sketch], red is used for keywords in the C++ language unrelated to “type” [type specifies the way in which data is stored], orange is used for keywords related to type as well as for various functions, and currently purple is used for the loop() and setup() functions as well as some other items related to serial communication that will be discussed elsewhere.)

Step 1: Writing the setup() Function

After starting MPIDE, you begin this project by creating the setup() function. The setup() function doesn't return anything, so its return type is void. Also, the setup() function has no inputs, so nothing should go between the parentheses that follow the functions name. Thus, a template for the setup() function in which the body is empty simply is:
1
2
3
4
void setup()
{
  // Body of function.
}
Within the setup() function, you will use the function pinMode() to tell the board that you wish to use a pin in a certain way. This function takes two input parameters, called arguments, corresponding to a pin (we must specify the pin number) and the mode for that pin. The mode is either INPUT or OUTPUT. When set to INPUT, we can “read” signals from the pin. Conversely, when the mode is set to OUTPUT, we can “write” to the pin. Keep in mind that the only output we can write is HIGH or LOW. When we write one of these values (using a function we'll describe below), that establishes the pin's state. If we write HIGH, the pin will be maintained at a “high” voltage of 3.3V. On the other hand, if we write LOW, the pin will be maintained at a “low” voltage of 0V. These voltages are maintained until a different value is written to the pin.

On the chipKIT boards, one of the onboard LEDs is tied to pin 13. (When pin 13 is HIGH, this LED is illuminated. When pin 13 is LOW, this LED is off.) We want to configure pin 13 for OUTPUT so that you can effectively “write” to the LED. Thus, we must have the following statement in the body of the setup() function:
pinMode(13, OUTPUT);
Within MPIDE, like HIGH and LOW, OUTPUT and INPUT are also constants. Hidden from us is the fact that they have numerical values that cannot be changed while the program is running. Instead of using these named constants, we could use the underlying numerical values directly in our program. However, by using these named constants, the code is more descriptive, i.e., more readable or self-documenting. The use of named constants in this way is considered good programming style.

Note that we are using the numeric value 13 in our program and it might be difficult for a person reading this code to know what this particular number represents or means. In the Blink External LED project we demonstrate how we can provide our own names for numeric values.

With the addition of the statement above to the body of the setup() function, the complete function is as follows:
1
2
3
4
void setup()
{
  pinMode(13, OUTPUT);
}
Be sure you have entered this function into MPIDE as it appears here. However, you are, of course, free to add comments as you see fit. Furthermore, since the amount of whatspace that is included in a sketch does not affect what it ultimately does, you could include or excluded blank spaces. Nevertheless, it is considered good programming style to indent the body of a function, as shown in line 3.

At some point you may notice that the sketch we are writing is slightly different from the Blink sketch provided as an example with MPIDE. The example sketch uses a predefined label for the pin associated with the LED (PIN_LED1), but we don't rely on that definition here.

Obtaining Help: MPIDE Reference Material

As you start to learn how to program in MPIDE, the number of things you have to keep track of can often feel rather overwhelming. That's a perfectly normal feeling! But, if you stick with it, you will find that many things that were hard to remember at first soon become second nature. Also, a very useful resource for keeping track of everything is the reference material that is provided with MPIDE. You access this material by clinking on the Help menu and then clicking on Reference. You will find entries there for numerous things such as setup(), pinMode(), and HIGH.

Step 2: Writing the loop() Function

Now that you've finished writing the setup() function, you can focus on creating the loop() function that the board will run repeatedly (after first running the setup function once). To make the LED blink, you will need two more functions. The first is digitalWrite() and the second is delay(). The digitalWrite() function requires two arguments. The first argument is the pin to which you're writing, and the second argument is the pin's state, which is either HIGH or LOW. Thus, the function call that sets pin 13 to HIGH should look like this:
digitalWrite(13, HIGH);
And similarly, to set pin 13 to LOW, it should look like this:
digitalWrite(13, LOW);
The delay() function has only a single argument, which specifies the amount of delay in milliseconds. By “delay” we mean the board simply does nothing for the specified amount of time. There are one thousand milliseconds in one second. Thus, to obtain a delay of one second, you would write:
delay(1000);
We can now combine these functions in the body of the loop() function such that the LED attached to pin 13 blinks at a two-second interval (i.e., it is on for one second, then off for one second):
1
2
3
4
5
6
7
void loop()
{
  digitalWrite(13, HIGH); // Turn on the LED.
  delay(1000);            // LED remains on for 1 second.
  digitalWrite(13, LOW);  // Turn off the LED.
  delay(1000);            // LED remains off for 1 second.
}

Step 3: Putting It All Together

At this point we have all the code necessary to obtain a blinking LED. The following is the complete sketch that is now ready to be uploaded to your chipKIT board:
1
2
3
4
5
6
7
8
9
10
11
12
13
void setup()
{
  // Set pin 13, the LED, to OUTPUT.
  pinMode(13, OUTPUT);
}
 
void loop()
{
  digitalWrite(13, HIGH); // Turn on the LED.
  delay(1000);            // LED remains on for 1 second.
  digitalWrite(13, LOW);  // Turn off the LED.
  delay(1000);            // LED remains off for 1 second.
}
If you need a refresher on how to upload your sketch to the board, see the Introduction to MPIDE project.
Test your knowledge!

After you have completed this project, you should:

  • Change the amount of delay so that the LED is off for a quarter second (but still on for one second; there are 250 milliseconds in a quarter second). Keep in mind that after modifying the code in MPIDE, you will have to download it to the board.
  • Change the amount of delay so that the LED blinks with a half-second interval (on for a quarter second; off for a quarter second).
  • While using the same amount of time both for how long the LED is on and for how long it is off, experiment with the delay to determine how short the delay has to be before you can no longer detect that the LED is actually blinking.
  • Have the LED turn on for one second, then turn off for a half second, then turn on for a half second, then turn off for a half second, and then repeat. This will require that you add two statements to the loop() function (another digitalWrite() and delay()).
  • In the listing in Step 3, remove (or comment out) the delay() function in line 10. What happens? Try to anticipate what happens and then test your guess by downloading the modified sketch to the board. Then, restore the delay() function in line 10 but comment out or remove the one in line 13. Again, try to anticipate what will happen and test your guess.


Core Concepts
   
Core Concepts:
  • Digital signals.
  • Functions required to be in every sketch: setup() and loop().
Functions Introduced:
  • setup()
  • loop()
  • pinMode(pin, mode)
  • digitalWrite(pin, value)
  • delay(milliseconds)

Digilent, Inc.    |    P.O. Box 428 Pullman, WA 99163-0428    |    (509) 334-6306 (voice)    (509) 334-6300 (fax)    |    Contact us