|
Introduction
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:
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:
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:
And similarly, to set pin 13 to LOW, it should look like this:
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:
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 );
delay (1000);
digitalWrite (13, LOW );
delay (1000);
}
|
|
|
 |
|
 |
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 ()
{
pinMode (13, OUTPUT );
}
void loop ()
{
digitalWrite (13, HIGH );
delay (1000);
digitalWrite (13, LOW );
delay (1000);
}
|
|
|
 |
|
 |
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)
|
|
|
|