0 and 1023. What now? Pretty
much the same as you would have
done in the Arduino IDE: Either act on the value, or
convert the value to a voltage. It’s really only useful
converting the value to a voltage if you need to report a
specific voltage; for example, if you’re building a simple
voltmeter project. Otherwise, it’s normally enough to work
with the value between 0 and 1023 itself.
Simply write a 1 to bit 6 of the ADCSRA register. Bit 6 is
named ADSC (ADC Start Conversion), so we enter:
ADCSRA |= (1<<ADSC);
B) Wait for the Conversion
In our “human” time, the conversion happens
ridiculously fast: about 13 clock cycles, or running using a
16 MHz crystal — about 0.0000008125 seconds!
As a quick reminder, we convert the value to a
voltage using the formula:
However, in microcontroller land, this is a fair amount of
time, and we need to wait for the conversion to complete.
Voltage = (ADCValue / 1023) VoltageReference
The datasheet notes that the ADSC bit (the one we
used to initiate the conversion) will remain at a value of 1
until the conversion is complete. Once complete, the
Let’s Get Physical
ADSC bit switches to a 0. That makes it pretty easy for us.
All we need to do is hang around until the ADSC bit goes
low. I’m sure that you can figure that out in code. Here’s
how I do it using a while loop and. of course, bit masking
(because we’re now reading a value):
Hopefully, you’ve found that we’ve covered some
new ground this month. I’m sure you didn’t read through
these pages purely for the theory behind the operation, so
let’s get physical and build a little project. I thought that a
simple game would be a good way to pull together all that
we’ve done over the past three articles.
while (ADCSRA & (1<<ADSC));
C) The Final Play: Read the Value
Finally, a simple register name – this one is simply
called ADC. The ADC register (ADC Result Register)
returns a 10-bit value from 0 to 1023. You’ll need to make
sure that the variable you’re reading the value into is large
enough to handle 10 bits. Otherwise, you’ll have the value
wrapping around back through 0. Something like an
unsigned long or uint16_t will do the trick:
We’ll build an analog guessing game. Player 1 turns a
potentiometer and then presses a button to set a value.
Player 2 needs to try to guess the value the first player set.
Player 2 turns the potentiometer, and then presses a
second button to “guess.” A red LED will light if the guess
is too high; a green LED will light if the guess is too low.
When the player guesses close enough to the value, then
the LEDs flash.
unsigned long ADCValue;
. . .
ADCValue = ADC;
Very straightforward! You may have spotted
something strange here, though. The ATmega328P is an
eight-bit microcontroller, meaning that all its registers are
eight bits (from 7 to 0). How are we then reading in a 10-
bit value? The ADC result is actually stored in two
registers: ADCL and ADCH (low byte and high byte
registers). Thankfully, these can be read through a single
register — the ADC register that we used above. If you
choose to read the underlying
registers, read the ADCL first, then
the ADCH, and finally combine
them into a single value by shifting
the ADCH eight bits. This adds
extra work we don’t need to be
The goal, of course, is to guess the value in as few
turns as possible. This probably won’t keep you
entertained for hours (although my son and I played a
good number of rounds), but does hopefully illustrate the
concepts we’ve discussed so far. Figure 7 gives a quick
overview of the LED indications through the game play.
The schematic in Figure 8 shows the connections
needed, excluding the detail of the power supply and
programming connections in order to keep the diagram
focussed. Figure 9 shows how the schematic translates
into the final project on the breadboard.
Enter, compile, and upload the code in Listing 2 that
is available at the article link (it is not shown here due to
I won’t go through it in detail
here, as it’s pretty well commented
and only includes the concepts
we’ve covered so far. It makes a
good exercise for you to work
through to consolidate the theory
Step 3: Do
If you would like to discuss the
project in more detail, then hop
over to the Nuts & Volts Forum
So, we have a reading between
( http://forum.nutsvolts.com) – it’s
a great place for readers to
connect with each other and
authors to discuss the theory and
projects in articles.
May 2015 43
Figure 7: Guessing Game Project:
Understanding the LEDs.