A microcontroller (
uC) is a computing device. Its main job is to perform computations… it takes some data from its memory, manipulates them, and then stores them back to memory. But having data in a uC’s RAM doesn’t do much good. In order to make use of that information, we have to be able to take it out of the uC and realize it in some way. To do that, a uC has
outputs that can transfer out bits of information to devices that can display it, make sound or light, cause something to move, etc.
In many occasions though, we don’t have our data ready in advance. Some times, we want to transfer data in the uC as they become available. Other times, we want to let the user interact with the uC, or we want to sense different aspects of the environment around us. For those reasons, a uC also has
inputs that let it take in information.
We are given access to the inputs and outputs (
IO) of a uC through the pins of its IC package. The circuit behind each IO pin is built such that the user can configure that pin as either input or output.
On an Arduino board, the pins of the uC are broken out and connected to female pin headers so they are more accessible. They are organized into groups and are given new names with which they are going to be referenced in the code.
An analog signal describes a physical variable that varies continuously with another variable (often time). Examples of analog signals are the intensity of light of an LED as its current increases, the current going through a resistor as we vary the voltage, or the temperature in a room as the time passes.
An analog signal can take on infinite values. Unfortunately a uC cannot represent an infinite number of values. So what we do when we want to sample an analog signal is perform an Analog to Digital Conversion (ADC). This basically means that we pick specific values in a region and then we use a series of bits to represent those values only. Any intermediate values are truncated to the closest representable value.
The analog pins on an Arduino board are named
Ax, where x is a number. We use these names to reference the analog pins in the code. We can read a value from an analog input pin with the analogRead function. This function requires a pin number as an argument, and returns an int value (the value read from the A-to-D converter).
An analog output is produced by a process called Digital to Analog Conversion (DAC). A D-to-A converter takes in a binary number and outputs an analog signal (a constant value, e.g. ). Unfortunately, unlike reading analog inputs (ADC), writing analog outputs (DAC) isn’t something that all uC support. If that is the case with your own uC then you will need to buy a DAC module.
On the other hand, a common feature on many uC is the Pulse Width Modulation (PWM) capability. A PWM(odulated) signal is a square wave (shown above), a.k.a. pulse train. It is a periodic signal, so it has a frequency , measured in either or , and a period , measured in either or . A pulse in a PWM signal has an on time and an off time. The on time is the time that the pulse stays HIGH. The off time is the time that the pulse stays LOW. The last but not least parameter that describes a PWM signal is the duty cycle which defines the percentage of time that one pulse stays on, .
The PWM pins on an Arduino board are designated with a
~ symbol. In the code, we use the analogWrite function to output a PWM signal. Its arguments are the pin number to which to write, and the duty cycle defined here as a number between 0 and 255.
A digital signal, unlike an analog signal, cannot take on infinite values. The digital signals of interest to us take only on two values referred to as 0 and 1, or LOW and HIGH, respectively. Examples of digital signals are the on-off state of an oven, the movement-no movement state of a PIR sensor, or the pressed-not pressed state of a push button.
We declare an IO pin as input or output through the use of the pinMode function. This function takes two arguments. A pin number, and one of the following constants to declare the pin’s mode: INPUT, OUTPUT, or INPUT_PULLUP.
We can read a digital input with the digitalRead function. It takes a pin number as argument, and returns HIGH or LOW.
Finally, we get to digital outputs. Not much is left to say. In the code, we declare an IO pin as output with the pinMode function, and we write to a digital output with the digitalWrite function. The digitalWrite function takes two arguments. One is a pin number and the other is the state to write to the pin, HIGH or LOW.
Inputs or outputs, analog or digital, signals of any form… now you know enough to interface them all. Now you have the power. I know these are a lot to take in, but hang in there. The possibilities that open up just with those things alone are countless. Next time, we’ll see already some applications! 😉
Images are CC BY-NC-SA 3.0.