Studio 8 - ADC Module
ADC Concepts
Analog-to-Digital Converter (ADC), as its name suggests, is mainly used to convert the continuously varying input voltage (analog signal) into a discrete digital representation that the microcontroller can store and manipulate.

In this studio, we will explore an interesting application between ADC and PWM. While ADC converts an analog voltage into a digital number, PWM performs the inverse operation by generating an analog-like effect from a digital signal. To illustrate this relationship, consider a scenario where a flex sensor is used to control an LED. A flex sensor is a type of variable resistor whose resistance changes when bent. The resistance changes result in a varying voltage when placed in a voltage divider circuit. Since this voltage is an analog signal, it must be digitized before the microcontroller can process it. The ADC module accomplishes this by sampling the voltage and mapping it to a corresponding digital value.
Once the digital value is obtained from the ADC, it can be used to adjust the brightness of an LED through PWM. For example, if the ADC measures a higher voltage, this might correspond to a greater degree of bending in the flex sensor. The microcontroller can then increase the duty cycle of the PWM signal, causing the LED to glow more brightly. Conversely, if the sensor produces a lower voltage, the microcontroller reduces the duty cycle, dimming the LED.
The two most important characteristics to look for in the selection of ADC are sampling rate and resolution. We will introduce them as follows:
Sampling
The continuous real-world analog signals are sampled for conversion into digital. The sampling process can be considered analogous to taking a screenshot of the continuous analog signal at regular intervals.
Nyquist Sampling Theorem
Motivation: Even when a real analog signal is converted into digital for fast processing, we cannot accommodate any loss of data, values, or information. Improper or unscientific sampling can lead to the kind of scenario where a lot of crucial data may get lost.
To better tackle this issue, Nyquist has come up with the following theorem
signals should be sampled with at least twice the bandwidth of the signal to prevent loss of data.
The Nyquist Theorem theoretically sets the minimum limit for the ADC sampling rate.
Resolution
During the Analog-to-Digital Conversion process, we need to quantize and then encode the anlog signal. To do so, we need to determine:
the number of quantization bits
the voltage span
So, with these two values, we can calculate our resolution as
For example, bits allows to divide the input signal range into different quantization levels, and each quantization level is represented as a binary number, thus allowing the quantized signal to be encoded.
Now, we give the formal definition of resolution,
Resolution is the voltage difference between two adjacent quantization levels.
In the modern EE industry, resolution is defined to be the number of quantization bits of the ADC.
Bare Metal Programming
The ADC on ATmega328p converts an analog input voltage to a 10-bit digital value. This means that the quantization bits of the ADC are 10. Thus, we have decided half of the one of the two important characteristics of the ADC Module. The other characteristic — sampling rate, will be determined in the following procedure.
The Programming Procedure
Activate power to the ADC
Write a 0 to bit 0 (PRADC) of the Power Reduction Register (PRR)
Switch on the ADC
Write a 1 to bit 7 (ADEN) of the ADC Control and Status Register (ADCSRA)
Voltage reference and input channel selection will not take effect until ADEN is set.
Configure the sampling frequency
This is done by setting the ADPS[2:0] in ADCSRA.
The ADC Clock frequency () is determined by the prescaler as well as the system clock frequency . The relationship is as follows (which is similar to what we have seen in PWM)
Since a typical conversion takes 13 clock cycles. Thus, we have our sampling frequency () to be
The number of clock cycles taken for one ADC conversion won't change as you change the prescaler. Because this 13 is derived by a fixed characteristic of the ATmega328p’s ADC.
Configure ADC
This is done in the ADC Multiplexer Register ADMUX. It determines two critical settings for the ADC:
Selection of the input channel: This specifies which analog input pin will be used for coversion. This is done by configuring
MUX[3:0](Bit 0-3).Selection of the reference voltage: This defines the voltage range against which the analog signal will be converted into a digital value. This is done by configuring
REFS[1:0](Bit 6-7).
Start the conversion
Write a 1 to bit 6 (ADSC) of ADCSRA.
Wait for the conversion to complete
There are two ways to wait for the conversion to complete:
Polling
Interrupt
Polling
In this approach, we continuously check whether the ADSC bit has returned to 0.
Interrupt
This is allowed thanks to the fact that the ADC Module on ATmega328p provides a status flag called ADIF (ADC Interrupt Flag) in the ADCSRA register (bit 4). It will be set to 1 when the conversion is complete.
To enable ADC interrupts, set the ADIE (ADC Interrupt Enable) bit in the ADCSRA register (bit 3) by writing a 1. So, once the conversion is complete, the ADC_vect interrupt is triggered automatically.
So, we can define an ISR for the ADC_vect interrupt, which will read the values from output value from the ADC.
Read in the converted value
Since the ATmega328p ADC is a 10-bit converter, it produces a 10-bit result, but the ATmega328p only has 8-bit registers. Therefore, the result is split across two registers:
The lower 8 bits are stored in
ADCLThe upper 2 bits are stored in
ADCH
Always read ADCL first! Otherwise, you will lose the data
GOTO step 5 until desired number of values are converted
Register
Power Reduction Register (PRR)
PRR)
ADC Control and Status Register A (ADCSRA)
ADCSRA)
ADC Multiplexer Selection Register (ADMUX)
ADMUX)
ADCL and ADCH
ADCL and ADCHTwo 8-bit registers, nothing special.
Prescaler Selection
These bits are in ADC Control and Status Register A (ADCSRA)

Input Channel Selection
These bits are in ADC Multiplexer Selection Register (ADMUX)
The ATmega328P microcontroller has multiple ADC input channels, numbered ADC0 to ADC7. However, on the Arduino Uno board (which uses the PDIP package), only ADC0 to ADC5 are accessible as A0 to A5. These channels correspond to the physical analog input pins on the board.

Reference Voltage Selection
These bits are in ADC Multiplexer Selection Register (ADMUX)

Sample Code
Below are the sample code to illustrate the difference between Polling and Interrupt with ADC Module during the lab.
Now, the following code may achieve the interesting example we have mentioned at the very beginning.
Last updated