Today we are going to learn how to control digital outputs. This is fundamental feature found in most microcontrollers and forms the basis for more advanced applications. We will start with taking a look at what the General-Purpose Input Output pins are, we will discuss some considerations we need to keep in mind when using the GPIO and we will learn how to write a sketch to control the digital outputs.
The parts you will need to follow along with this video are:
- 1x Arduino Uno or compatible board
- 1x breadboard
- 2x jumper wires
- 1x LED
- 1x 220 ohm resistor
- 1x USB cable compatible with your development board
Before we get started with programming, let’s take a look at the microcontroller. The Atmega 328P microcontroller has a total of 23 GPIO lines. These can be used for both digital inputs and outputs. Some of these pins provide additional functionality that we will learn about in the future. Now the Arduino Uno development board provides us with convenient pin headers for accessing most of these GPIO lines. I say most because the Arduino developers made some engineering decisions when designing the board.
What this means is that one of the pins is used for the reset button and two more are used with the 16 MHz crystal or resonator. This leaves us with 20 usable GPIO lines. But wait a second, there are only 14 pins on the Arduino board that say “digital”. Something that’s not evident up front is that all the pins labeled “analog” are just GPIO pins and we can use them as digital inputs and outputs just like the rest. They have the added capability of being used for analog inputs as well.
We will first connect the ground pin of the Arduino board to the ground bus of the bread board using one of the jumper wires. Then we connect pin number 6 to one of the available rows on the breadboard. Next, we will connect the longer leg or Anode of the LED to the same row we connected pin 6 to. The shorter leg or Cathode of the LED will go into a row next to the Anode. It is important to connect the LED up correctly because it is polarized. Meaning the positive lead, the Anode, should always be connected to a positive voltage source and the negative lead, the Cathode, should always be connected to the return path or ground. Finally, we connect one leg of a 220 ohm resistor to the row with the Cathode. And other leg of the resistor will get connected to the ground bus. A resistor doesn’t have a specific polarity, so it doesn’t matter which leg of the resistor you use.
This circuit will use pin 6 to drive the connected LED with a positive 5 volts from the microcontroller. Logically, current will flow from the Anode to the Cathode of the LED turning it on, then flow over the current limiting resistor before reaching the return path, which is the ground bus.
The Arduino IDE has several useful features and as we progress through these tutorials, we will explain them in more detail. For today we will start with the main text editing field, where all the code will live. Here you will see that some default text is already present when we opened the application. This includes two blocks of code.
The first is the setup() function and second is the loop() functions. The setup function is a block of code that will run a single time when the Arduino starts. This means when power is applied or when the reset button is pressed, the setup function will execute once.
Then the Loop function begins to execute, and this section of code does exactly what you may think, it executes over and over until the reset button is pressed.
Most microcontrollers usually require a peripheral to be initialized before it can be used. This process of “initializing first” and “then using” corresponds well with the two main functions already created for us. We will need to first initialize the pin we want to use; this will let the microcontroller know that we want to use the GPIO as an output. Then we can use the pin in the loop function to turn on and off.
Starting off inside the setup(), we need to initialize our pin with the function “pinMode()”, giving it two arguments. The first is the pin number and the second is the mode. The possible modes we can use are “OUTPUT”, “INPUT”, or “INPUT_PULLUP”. For this application we will use OUTPUT. For the pin number we can simply use the number 6, which will correspond to the Arduino Pin #6.
Don’t forget to put a semi-colon at the end of each statement to avoid compiling errors.
Then inside the loop(), we can use the function “digitalWrite()”, again giving it two arguments this time defining the pin and value. We again use the number 6 for the pin, and we can use the values HIGH or LOW to identify the state we want the pin to be in at a given moment. The value HIGH will output 5 volts on the corresponding pin and LOW will set the pin’s output to 0 volts.
You may have noticed that some of the letters are capitalized while other are not. It is important to remember that the C programming language is case sensitive. The Arduino Core will usually capitalize the second word in a function name as a standard naming convention. Arduino also using all CAPS for constants like HIGH, LOW, OUTPUT etc.
You might think, great all I need to do is use digitalWrite to set the pin’s output as HIGH and LOW, then loop function will repeat this forever. The LED should flash on and off just like we want. Well, this is technically correct, but the microcontroller is so fast at executing our instructions, the LED just appears to be on all the time. Lets look at it with an Oscilloscope. Here we can see that the pin is in fact turning on and off, but with a frequency of about 4 microseconds. So, we need something to help slow the process down and allow us to flash the LED at a rate we can actually see.
This is where the delay() function comes in handy. Here we can define a single value which corresponds to time in milliseconds.
If we want to add a small delay of say half a second, we can use 500 as the value in the delay function.
The smaller the number, the shorter the delay. And of course the larger we make the number the longer the delay will be.
Delay is a great function to help control how fast things are happening in our microcontroller, but it isn’t the only tool we have available. In the future we will learn how timers can be used in place of the delay function and why you would want to use them.
Now with all of the code in place the setup() function will run one time, then our loop will repeat over and over effectively blinking the LED.
With the code written we first want to verify it. However, before we can verify the code, the IDE needs to know what development board will be used, so it knows what compiler to use.
To set the board type, select Tools>Boards>Arduino AVR Boards>Arduino Uno. This can be done even without a board connected to computer yet.
Next we use the verify button, which looks like a check mark, in the main tool bar. The Arduino IDE will attempt to compile the code without uploading. You will see a message that states “Compiling” and a progress bar will appear. After a few moments, the message will change to “Done compiling” and the progress bar will go away. The results will be displayed at the bottom of the IDE. There is useful information in the results such as the amount of memory and RAM that will be used by the sketch.
To compile and upload our code, first connect the Arduino Uno to the computer via the USB port. This will provide both the needed 5 volt power and a way of programming the board.
Next we need to let the compiler know which communication port on the board is using. You can set the port by navigating to Tools>Port and then select the appropriate port your board is on.
Finally, we can press the Upload button, which looks like an arrow pointing to the right. The IDE will again compile the program and then upload the executable to the board.
Now we can see the LED blinking on and off using the 500 milli second interval we programmed.