Analog Input (thanks to Dan O'Sullican & Tom Igoe)

While a digital input can tell us about discrete changes in the physical world, such as whether the cat is on the mat, or the cat is off the mat, there are times when this is not enough. Sometimes we want to know how fat the cat on the mat is. In order to know this, we'd need to be able to measure the force the cat exerts on the mat as a variable quantity. When we want to measure variably changing conditions like this, we need analog inputs. Many transducers are available to convert various changing conditions to changing electrical quantities. There are photocells that convert the amount of light falling on them to a varying resistance; flex sensors that change resistance as they are bent; Force-sensitive resistors (FSRs) that change resistance based on a changing force applied to the surface of the sensor; thermistors that change resistance in response to changing heat; and many more.

In order to read these changing resistances, we put them in a circuit and pass a current through them, so that we can see the changing voltage that results. There are a few variations on this circuit; the simplest uses a variable resistor. In the diagram on the left, we use a potentiometer (variable resistor with three connections). The center of the potentiometer (pot) is connected to the microcontroller. The other two sides are attached to power and ground. The resulting circuit is called a voltage divider. The ratio of the resistance on one side of the center of the pot to the resistance on the other side provides a varying voltage at the center of the pot.

In the diagram on the above, we use a variable resistor from our voltage supply to the microcontroller pin, and a fixed resistor to ground. The 10K variable resistor feeds a varying voltage to the microcontroller pin. The fixed resistor provides a path to ground. The current will follow the path of least resistance, from the 5V source through the variable resistor to the microcontroller pin. The higher the fixed resistor, the higher the bottom of the voltage range will be. Use a fixed resistor that's in the same order of magnitude as the the range of the variable resistor. For example, if your variable resistor measures from 10 kilohms to 100 kilohms, use a 10kilohm fixed resistor. If you build these circuits as shown above, and place your multimeter leads at the point that would go to the microcontroller and at ground, and measure for voltage, you should see a changing value.

Since a microcontroller's inputs can read only two values (typically 0 volts or 5 volts), we need an extra component to read this changing, or analog voltage, and convert it to a digital form. An analog-to-digital converter (ADC) is a device that does this. It reads a changing input voltage and converts it to a binary value, which a microcontroller can then store in memory.

ADCs are a common tool, and many microcontrollers have ADCs built in to them. The Atmega8, which is the heart of the Arduino module, has 6. Many other microcontrollers have varying numbers of ADCs built in.

When the ADC circuitry attached to an ADC pin on these microcontrollers senses a varying voltage, it converts that voltage to a 10-bit number (0 to 1024). If you choose to read these pins using the ADC command instead of the getPin() command that we used to read them as a digital input, you will get that 10-bit number.


The command in Wiring is the analogRead() command, and it looks like this:

analogVar = analogRead(pin)
         Pin is the analog input pin you are using;
         analogVar is an integer variable containing the result from the ADC..

The number produced in analogVar is will be between 0 and 1024. Its maximum may be less, depending on the variable resistor you're using. We have to use a word (an integer on the BX-24,, or an int on the Wiring and Arduino modules) to store the value, because it is the smallest data type that will fit ten bits. Remember, a word (and an integer) is sixteen bits of memory. A byte, the next size down, is only eight bits, and would not fit the 10-bit value coming from the ADC.

Decoupling Analog Inputs

If you find the readings from your analog inputs are inconsistent (for example, you see changes on one channel when the sensor on a different channel is the one sensing action), it helps to decouple your input circuit. Decoupling means smoothing out the dips and spikes going into the circuit from the rest of your microcontroller circuit. To do this, place a 0.1microfarad capacitor from voltage to ground as close to where the analog input connects to voltage, like so:

A capacitor used this way is referred to as a decoupling capacitor. You'll see them a lot in electronic circuits. Think of them as tiny surge protectors.

The resolution of an ADC changes from one ADC to another. However, Arduinos with ADCs on board typically have 10-bit resolution.


Physical computing interaction Design

Processing + Arduino

Sensor & components

Essential Viewing