Arduino Analog Input and Outputs (Best Tutorial 2019)

Arduino Analog Input and Outputs

Arduino analog input and outputs control Tutorial 2019

The first thing you should know is that Arduino isn't really able to generate an infinite continuous analog signal, but instead, it uses a little trick to simulate it. Digital devices such as microcontrollers usually incorporate a peripheral called Digital to Analog Converter (DAC), which they use especially to perform this trick.


When working with a microcontroller, we pass a digital value to the DAC, and it converts it to an analog value but in a predefined range of possible values. The DAC is unable to generate an infinite set of output values; it has a finite input range of digital values and can generate a finite output range of analog voltages.


The number of steps the DAC can generate is called the resolution of the DAC. The Arduino DAC has an 8-bit resolution, so it accepts input values ranging from 0 to 255, which will be converted to analog values between 0V and 5V.


If you divide the voltage range between the total number of steps the Arduino DAC accepts, you will conclude that every step of the input range increments the output voltage by almost 0.02V.


To perform this conversion, the DAC uses a method called Pulse Width Modulation (PWM) that consists of turning the output at very high frequencies on and off, resulting in a medium voltage that is the proportion of the on time with respect to the off time.


If you want to learn more about DACs and PWM, you can visit the corresponding pages on Wikipedia at converter and


The analog output circuit

Arduino Analog Input

As you can see in the previous schematic, Interacting with the Environment the Digital Way, to deal digitally with an LEDHowever, in this case, we have to connect it to a PWM pin of the Arduino, pin 11 for this example, so that later in the program we can use the corresponding code to deal with it analogically.


The rest of the circuit is just the same as the blinking LED one, and we will use the same 220 Ohms resistance to limit the current that will flow through the LED to no more than 20 mA.


Connections diagram

If you still see connections better in the connections diagram for the breadboard, here you have the complete diagram for this example:

Analog Input


Complete the fading LED code

Regarding the rest of the code, I'm going to use three variables; two of them, which I've called led and increment, won't really change throughout the execution of the program, but they will greatly increase the readability of the code.


The led variable is going to be used to store the pin number I'll use to control the LED, pin number 11, in this example. Remember that you can use whichever pin you want from those marked as PWM in the Arduino board and that you will have to set this variable as per your choice, accordingly.


The increment variable will hold the step size we will use in the for loops that we will use later. Using a variable just to use the increment value makes it very convenient to make future modifications by just changing its value at the beginning of the code without the hassle of having to search throughout the code for every occurrence of the pretended value.


The other variable, which is intensity, will be the key of this sketch, as it is going to be used as the control variable of two for loops that we are going to use to go all along the range of possible values for the analogWrite() calls we will use to gradually change the brightness of the LED.


Well, let's see this theory in action. Here is the complete code for the LED fading sketch:

// Global variables we will use int led = 11;
int intensity = 0;
int increment = 5;
// Configuration of the board void setup() {
// Set the pin we are going to use as an output pinMode(led, OUTPUT);
// Main loop void loop() {
// fade from minimum to maximum
for(intensity=0; intensity<=255; intensity=intensity+increment){ analogWrite(led, intensity); delay(30); } // fade from maximum to minimum for(intensity=255; intensity>0; intensity=intensity-increment){ analogWrite(led, intensity);


As I have explained previously, we begin by declaring and assigning initial values to the three global variables we are going to use all along the program.


 In the setup() function, we simply set the pin we are going to use as an output. In the loop() function, we have just two for loops: one taking values from 0 to 255 in increments of 5 and the other taking values from 255 to 0 using -5 increments.


In every iteration of each for loop, we simply set the changing value of the control variable, which is intensity in our code, as the analog value we want to output to the LED and wait for 30 milliseconds to allow our eyes to see the change. 


The first loop makes the intensity of the LED increase from 0V to 5V and the second one makes the intensity decrease from 5V to 0V, which is just the opposite.


I'll suggest that you play with this code, and as an exercise, you could make both parts of the fading run at different frequencies simply by setting different values for the increment variable just before entering the for loops, making it 10 when going up and 50 when going down. The resulting code could be as follows:

void loop() {
// fade from minimum to maximum in increments of 10 increment = 10;
for(intensity=0; intensity<=255; intensity=intensity+increment){ analogWrite(led, intensity); delay(30); } // fade from maximum to minimum in decrements of 50 increment=50; for(intensity=255; intensity>0; intensity=intensity-increment){ analogWrite(led, intensity);


[Note: You can free download the complete Office 365 and Office 2019 com setup Guide for here]


Motor driver

This kind of circuit usually uses a transistor as an intermediate device that receives the Arduino signal and provides a proportional current coming from an external power source to the device. In the following schematic, you can see a typical assembly when operating a DC motor from Arduino:


The key element of this circuit is the transistor component, the one with the arrow pointing out that has three legs:

  • Base: This is the leg that we connect to the Arduino board through a resistor and that acts as the control element
  • Collector: This, simply said, is the leg where the current comes into the transistor
  • Emitter: This is the leg through which current flows out of the transistor


Regarding its operation, I like to compare a transistor with a water tap, where we turn the handle and, more or less, water comes out of it. In the transistor case, we set a variable voltage on the base, which allows more or less current to flow from the collector to the emitter and consequently, through all components we connect in between.


Keeping this in mind and taking a closer look at the previous schematic, we can realize that by connecting the base to an Arduino analog output, we can make a varying current flow through the motor, thus making its speed vary.


When dealing with transistors, it is important that you know which of the three legs is the base, collector, and emitter of your transistor. You should refer to its datasheet, which you can easily find on sites such as


There are two more components on the circuit that deserve a short explanation:

• The resistor: This allows the connection between the Arduino pin and the transistor base. Without going into too much detail, we will use a 1K resistance here.


• The diode: Without going into too much detail, you should know that a motor acts much like a big electromagnet and thus, when turned off, generates what is called a back Electromagnetic Force (EMF), which can even be 100 volts and with an opposite direction from the main voltage applied to the motor, which could damage your circuit.


By placing a diode in the opposite direction of the main voltage, you help suppress this dangerous back EMF. Any protection diode will do, such as the 1N4007, but if you don't have one to hand, you could even use an LED as long as you connect it correctly.


Power source considerations

There is the last question to consider before going hands-on with our motor control circuit, and that is the powering of the motor. For the purposes of this example, I'll suppose that you are going to connect a small DC motor that consumes no more than 250 mA when operating without a load.


This way, we could take current directly from the 5V pin of the Arduino board. It's important to keep this in mind because the power regulator present in your Arduino board takes current in the last instance from your USB port, which can't typically support more than 500 mA.


You should take some precautions before connecting a bigger motor to your Arduino board by measuring its typical power consumption. You can do this by placing an ammeter in the serial with a battery or another external power source and take note of the current it needs to run.


If the motor doesn't need more than the maximum 500 mA that your USB port and Arduino voltage regulator can give, then you can safely power it from the 5V Arduino pin. In other cases, you will have to provide another power source for the motor and connect both grounds: the one for your external power source and the one for your Arduino board.


The complete circuit

Well, that is enough theory for the moment; let's go into the real nuts and bolts of our circuit. Here, you have the complete schematic of the motor speed control circuit we are going to assemble for this example:


Arduino Analog  Outputs 2018

A motor speed control circuit Connections diagram

For the breadboard connections, we can save some wires by placing the diode just in contact with the transistor collector.

Notice that for the transistor used in this diagram, the legs are looking at it with the plain side in front from the left to the right, collector, base, and emitter, or, as you will usually find, CBE.


A breadboard connections diagram for the motor speed control circuit


Motor varying speed code

The code for this circuit is very similar to the LED fading one, but instead of using the for loop to go all over the range of values of the analog output, we will just use it to generate a three-iteration loop that will give us just three different speeds for the motor, which will make its changing state more evident.


Further, I couldn't make my motor spin with a voltage lower than 1V, so I will configure the loop to take the values 150, 200, and 250, which made my transistor deliver voltages of 1.5V, 2.5V, and 3.5V.


Here, you have the complete code I used for this example:

Global variables we will use int base = 6;

int speed = 0;
// Configuration of the board void setup() {
// Set the pin that we will connect to the transistor base as an output
// Main loop
void loop() {
// Increment the speed of the motor in three steps, each for 3 seconds
for (speed=150; speed<=250; speed=speed+50){ analogWrite(base, speed);
// Stop the motor for 1 second and begin again analogWrite(base, 0);

Notice that every change in speed lasts three seconds and that once the three steps' loop ends, we stop the motor for one second before beginning all over again.


The assembled circuit


I'd like to show you a picture of the complete assembly that could perhaps clarify even more what we are doing:

A real assembly for the motor speed control circuit, As you can see, I've used a little piece of tape around the motor axle in order to make it clear when it changes its speed.


Bigger power motors

As I told you previously, when dealing with motors, this can consume more current than the maximum 500 mA your USB port can give. You will have to provide another power source just for the motor, such as an external battery or DC transformer.


I have used an excellent and totally recommendable free software called EAGLE ( to prepare a schematic for this kind of circuit that can perhaps help you understand what we pretend.


Here, you can see how the motor gets its current from the big battery and the only component between both circuits is the transistor, which is connected through its base to the Arduino board, its collector to the external power source, and the emitter to both grounds: the battery one and the Arduino one.


This way, you can not only provide a bigger current but also a different voltage to the motor that could, for example, operate at 12V as opposed to the 5V of the Arduino board.


One final consideration with respect to this circuit is that you should look for an appropriate transistor, because every transistor has a maximum current that it can support, so be careful if you don't want to see little fireworks show on your desktop.


Sensing the Real World through Digital Inputs

Dealing with outputs is really just half of the pie. Inputs are the other half, and if I may, I'd say they are the most interesting part of any project you will work on.


In this blog, I'll introduce you to the use of digital inputs as a way to make your project sense their environment through the assembly and programming of two different examples that I'm sure you will like.


Sensing by using inputs

Nowadays, we can find almost a different sensor for every physical variable we want to measure and an endless number of devices that allow humans to interact with electronic devices.


So, the first thing we will have to consider is the type of sensor we will need for our project and, most importantly, from the point of view of connection and programming, the type of signal it generates, digital or analog.


This is because it will affect the way in which we have to connect it to our Arduino board, by way of a digital or analog input, and program our sketch accordingly.



Digital sensors usually give us a 0V or 5V voltage or any way to obtain it, which can be easily traduced into HIGH or LOW values in the Arduino code. In other cases, they provide a different value that we will have, by means of additional circuitry, to adapt to the Arduino digital input allowed voltage, that is, 0V to 5V.


Regarding analog sensors, their main characteristic is that they provide a continuous value between a range, and we will also have to adapt them to our Arduino allowed range, Analog Inputs to Feel between All and Nothing. At the moment, let's see the simplest digital input circuit, a switch, and how to program it.


A basic switch connection to Arduino

Although it is a simple circuit, it may deserve some explanation. It basically exposes two different states: the button or switches pressed or released:


• Released: When the button is not pressed, the two parts of the circuit remain unconnected, thus not flowing any current through that branch of the circuit.


In this case, the Arduino board only senses a GND or 0V value through the digital input by which we connect this circuit to it due to the fact that it is physically connected to the ground through the resistor.


• Pressed: When we press the button or close the switch, what we are internally doing is connecting both parts of the circuit, that is, the 5V upper side to the GND lower side, allowing current to flow from one to the other through the 10K resistor. This is precisely why we use the 10K resistor:


To provide some load to this branch of the circuit, preventing the short-circuiting of the power source. From the point of view of the Arduino board, it senses a 5V signal in the pin we use to connect this circuit to the board.


The momentary push button


• The printed circuit board (PCB) soldering: These used to be smaller, really tiny in some cases, and they come with little legs that allow them to be soldered through holes in a PCB. In the screenshot, they are the three on the left-hand side.


• Panel mounting: These are the three on the right-hand side in the picture. Usually, they come in a much bigger size than the PCB kind and come with bigger connections so that wires can be soldered to them. They usually come with some kind of nuts that they can be fixed to a panel.


Different momentary push buttons

Physical differences apart and looking at them from the connection point of view, we have to notice an important difference between both groups.

If you take a closer look at the PCB group or, even better, if you perform a simple search on the Internet, you will notice that these kinds of momentary buttons usually come with a total of four legs instead of simply two.


Usually, the reason is to give a stronger union to the PCB group by allowing up to four soldering points, but also because they have their connections duplicated to provide a more reliable connection between both points of the switch.


This simple feature has to be taken into serious consideration when connecting one of these buttons through a breadboard because if we connect them in the wrong way, we could easily short-circuit the Arduino board, with subsequent bad consequences.


The first thing you should do when using one of these momentary push buttons is to identify every leg so that you know which of them are internally connected. They usually come with some kind of indication or a diagram, but if they don't, you could always use a voltmeter or continuity tester to find out.


Once you have determined which legs are connected, you should always connect the momentary push button just above the centerline of the breadboard.

Which divides the two groups of holes in such a way that you leave two of the replicated connections out of use and ensure that the other two corresponding to the two contact points of the switch is always connected in different columns of the breadboard connections block.


This way, they prevent a short circuit when you connect them to the positive rail (5V) and ground.


Also, remember that this kind of circuit needs a current limiting resistor in a part of the branch that gets closed between V+ and the ground to prevent a short circuit again. A value of 10K is more than sufficient.


A blink or fade circuit schematic diagram



Configuring and reading a digital input

From the point of view of programming, there are basically two main new concepts in this example regarding the use of a digital input:


• pinMode(button, INPUT): In the setup() function, we have to set the pin we are going to sense as an input so that Arduino can read from it. The function is just the same pinMode() function we have been using so far, but instead of using the OUTPUT constant, this time, we use INPUT to set the pin accordingly.


• digitalRead(button): When we deal with an input whether it is a digital or analog one, we are going to receive the real value instead of setting a value like how we have been using outputs.


This means that we only pass a parameter indicating the pin to be read to the reading function, analogRead() in this case, but it also means that this function, as opposed to writing functions, is going to return us a value that we have, in some cases, to store in a variable for later use.


Being realistic, in this example, it isn't really necessary to store the real value in a variable because we are not going to use it anymore in the rest of the code, and we could simply have used the digitalRead() function inside the if parentheses like if(digitalRead(button) == LOW), but for the sake of clarity in this first example, I preferred to use a variable this time.


The world through Digital Inputs

In the following couple of images, you can see the schematic of the internal structure of a typical optocoupler and a real picture of the one I used for my own assembly of the next project.


The internal structure of an optocoupler and a real one. If you take a closer look at the picture, you may even notice the indications on the plastic housing of the emitter part with its diode sign to reference the anode and cathode and the collector and emitter markings on the phototransistor part.


If we connect the phototransistor part to our Arduino board, we could easily detect whether it is being excited or not, thus indicating whether there is something placed just in the middle of the plastic housing or not.


This was the same principle that used the first mechanical computer mice to detect and count the X and Y movement, and for that, they used a very recognizable small slotted wheel that allowed for its internal microcontroller to account for every step the mouse took in every axis.


If you are too young, perhaps you have never seen one of this kind of mice, but you could take a look at the Wikipedia entry for mouse under the Mechanical mice section at wiki/Mouse_(computing). In the next example, we will use an optocoupler as a light barrier that when interrupted, triggers a digital input.


Using an optocoupler as a coin detector


If we take advantage of the fact that there is a small space between the emitter and receptor part of a typical optocoupler that allows a coin to pass through, we could easily use one of them to create a simple coin detector that could be used for a bigger project—who knows, perhaps a candy vending machine or your next arcade game cabinet.


From the point of view of the circuit, we will have to provide little additional circuitry—only a pair of resistors: one to limit the current through the infrared LED and another to act as a load for the phototransistor between its emitter and collector.


A real working project

Finally, here you have a real picture of the complete circuit assembled with the optocoupler I had and a coin being detected:

Analog Inputs to Feel Between All and Nothing

We have come a long way up to this point, learning to deal with digital and analog outputs and also digital inputs. It is now the moment to show you how to manage analog inputs, as they are what enrich the microcontroller field of application the most.


In this blog, I have prepared two projects to help you understand how to connect, configure, and program analog inputs and what kind of things we can do with them. I'm sure you will be totally amazed once you get the point.


Sensing analog values

In this blog, we need to know about the DAC cousin, the Analog to Digital Converter (ADC). An ADC is a device with just the opposite mission of a DAC, that is, a device that takes a signal that can theoretically have an infinite number of states and convert it to just a few concrete values, or in Arduino jargon, takes an analog signal and converts it to a digital value.


Just like the DAC, the Arduino board comes with a six-channel ADC with a 10-bit resolution for each channel. This means that we can deal with up to six different analog signals ranging from 0V to 5V that will be converted to values between 0 and 1024.


Controlling Outputs Softly with Analog Outputs, the DAC had just an 8-bit resolution, allowing for values between 0 and 255, so we will have to keep this little difference in mind when working on projects that sense and act in an analog way, and we will have to make some kind of correspondence between the 1024 possible input values and the 255 maximum output values: a usual operation commonly called mapping.


A real photocell and its most common schematic symbols

Unlike any other resistor, a photocell doesn't have a polarity, which means that you don't have to observe the way you connect it in your circuit. It does its job equally in one way or the other, but being a variable device it makes us give some considerations when connecting it to our Arduino board.


Connecting a variable resistor to Arduino

As mentioned previously, a photocell can decrease its internal resistance up to only a few ohms when exposed to a bright light and theoretically, it could even reduce it to zero when in the presence of a very bright light;


In this case, it acts like just a simple wire with 0 ohms resistance. With this in mind, we need to modify our circuit to prevent a short circuit in case this situation arrives.


Given those connecting variable resistors as analog input sensors to Arduino is a very common case, let's see a simple circuit that will ensure we will never damage the Arduino board.

  • A general variable resistor circuit to connect to Arduino can be like what is shown in the following diagram:
  • A typical circuit to connect a variable resistor to an Arduino analog input


As you can see, in some way, the circuit is very similar to the one used when connecting a digital input to Arduino. It also uses a 10K ohm load resistor to prevent a short circuit in case the photocell internal resistance decreases down to zero.

This is not a typical situation but it could happen, especially when connecting other types of variable resistors.


Voltage divider

This kind of circuit is commonly known in the electronic jargon as a voltage divider, because it splits the provided voltage in two steps according to the proportion of the value of the first resistor to the other. We should keep this in mind when selecting the resistance we are going to use as protection.


We should always try to select a protection resistor of a value lower than the main variable resistor; this way, the main voltage drop will be placed just in the variable resistor acting as a sensor, that is, the photocell in our case.


This way, we allow Arduino to sense what is happening in the variable resistor with greater precision and use only the load resistor as protection.


Breadboard connections

At this point in our work, I assume that you will be very accustomed to working with the breadboard, but in case you still have some doubts or the schematic is not clear enough for you, here you have the breadboard connection diagram of the ambient light meter project: A breadboard connections diagram of the ambient light meter circuit


Programming to sense the light

  • From the point of view of programming, dealing with an analog input is not that different when compared to dealing with a digital one.
  • Just like when reading a digital input, we are going to receive a value from the reading function, analogRead(pin) in this case.
  • We will read from a pin that we have previously set as an input in the setup() function of our sketch by a call to the pinMode() function.


Interacting with the Environment the Digital Way, the Arduino board has different pin headers for digital and analog input connections.


When connecting something to your board that is going to be read in an analog way, you have to mandatorily use one of the Analog In pins of the Arduino board—those on the lower side of the board close to the Power pin headers.


You can only read an analog value through the use of the analogRead(pin) function from one of the Analog In pins of your board; definitely take this into consideration.


Due to the fact that the analog inputs have their own exclusive pins, it is not compulsory to configure them as INPUT in the setup() function, because they are always inputs, but for the sake of clarity and learning purposes.