Arduino boards have a built-in analog comparator used for different applications. This is noteworthy because digital input/output and pulse width modulation (PWM) are typically used while analog comparators are not.
A built-in analog comparator is useful in microcontrollers, providing voltage comparisons, digital-to-analog conversions, threshold detection, and PWM.
Depending on the Arduino board (there are several options), several hardware features and peripherals are included. Most of the boards have an analog comparator. In this article, we’ll discuss the built-in analog comparator in the ATmega328p microcontroller. The Arduino UNO, Nano, Mini, Pro Mini, Fio, Ethernet, and Lilypad are each based on the ATmega328p.
What is an analog comparator?
An analog comparator is an electronic device that compares the voltage levels of two input signals, producing an output based on their relative magnitudes.
It’s worth noting:
- If the input voltage at the non-inverting input is higher than the voltage at the inverting input, the output of the comparator is considered logical HIGH (1).
- If the voltage at the inverting input is higher than the voltage at the non-inverting input, the output of the comparator is considered logical LOW (0).
ATmega328p’s analog comparator
In all Arduino boards, the analog comparator is implemented through an operational amplifier or a dedicated comparator integrated circuit. Arduino’s analog comparator is used for tasks like threshold detection, digital-to-analog conversion, and PMW.
The ATmega328p microcontroller has a programmable internal analog comparator. The positive input of the comparator is available at pin D6 of the controller, and negative input is present at analog input pins A0 to A7.
The output of the Arduino’s analog comparator can trigger an interrupt, which is the most useful feature of this peripheral in Arduino.
Arduino’s comparator is programmable and can be configured by setting the associated registers. The comparator can be used to get the analog comparison output or to trigger an interrupt.
As seen in the above block diagram, AIN0 (PD6) is the comparator’s positive input, and AIN1 (PD7) is the negative input. The signals applied to these two pins are assessed by the comparator.
If the signal at AIN0 is higher in magnitude than the signal at AIN1, the bit’s ACO output in the ACSR register is set high. Otherwise, the bit is set low.
There can be different sources of signals for the two input pins. For the positive input AIN0, the controller can be configured to use an internal reference band gap voltage. For the negative input AIN1, any of the analog input pins A0~A7 can be used as the source. Also, the output of the comparator can be used as is, or it can trigger the input capture interrupt of the Timer/Counter1.
How to use the analog comparator
Using Arduino’s analog comparator is relatively simple but, first, identify the comparator pins on the board. As each type of Arduino board is different, the pin assignment to positive and negative inputs of the comparator are also different.
Specific pins on each board are designated for analog conversion. These are analog input pins numbered (like A0, A1, etc.) or labeled with ‘~’ or ‘AC.’ Connect the input signals to the comparator pins. One of the input pins must also be connected to a fixed reference signal. The other input is connected to the signal, which will be compared and monitored.
Next, configure the comparator settings, such as the reference voltage, interrupt mode, and input capture. The associated registers are set in the user program or libraries and library functions can be used. Comparator programming with the support of a library is typically easier, as it requires no knowledge of the registers to configure the comparator properly.
Lastly, read the output of the comparator. The output is available through a function or variable of a specific library’s user program. Otherwise, you might have to read the status of an associated register or a bit that indicates the comparator output.
The output clearly indicates whether the input signal is higher or lower in magnitude than the fixed reference voltage. The output can then be used for decision-making or trigger specific actions in the user program. The output can also trigger an interrupt-like input capture of Arduino UNO’s Timer/Counter1.
Arduino’s registers
In ATmega328P, there are five registers of the analog comparator as follows:
1. ACSR (Analog Comparator Control and Status Register)
2. DIDR1 (Digital Input Disable Register 1)
3. ADCSRA (ADC Control and Status Register A)
4. ADCSRB (ADC Control and Status Register B)
5. ADMUX (ADC Multiplexer Selection Register)
ACSR register: the most important register, which is used for configuring the analog comparator and monitoring associated flags. The register has the below bitmap.
The Analog Comparator Disable (ACD) bit enables or disables the analog comparator. If the bit is set, the analog comparator is disabled. Otherwise, the analog comparator is enabled. Disabling the analog comparator reduces the power consumption of the microcontroller.
The Analog Comparator Bandgap Select (ACBG) bit is used to select the positive input of the comparator. If the bit is set, a fixed bandgap reference voltage is used as positive input. Otherwise, input at the AIN0 is used as positive input of the comparator.
The Analog Comparator Output (ACO) is the output flag of the comparator. If the voltage at AIN0 is higher than that at AIN1, the flag is set. Otherwise, it’s cleared.
The Analog Comparator Interrupt Flag (ACI) indicates the state of the analog comparator interrupt. The flag is set whenever an interrupt occurs.
The Analog Comparator Interrupt Enable (ACIE) enables or disables the analog comparator interrupt. If the bit is set, the analog comparator interrupt is enabled. Otherwise, it’s disabled.
The Analog Comparator Input Capture Enable (ACIC) enables or disables the input capture function of the Timer/Counter1 triggered by the analog comparator output. If the bit is set, the input capture is enabled. Otherwise, it’s disabled.
The ACIS1 and ACIS0 are Analog Comparator Interrupt Mode Select bits. These bits are used to configure the type of comparator interrupt. If both bits are cleared, the comparator interrupt on the output toggle is selected. If ACIS1 is cleared and ACIS0 is set, the state is reserved and not used. If ACIS1 is set and ACIS0 is cleared, the comparator interrupt on the falling output edge is selected. If both bits are set, the comparator interrupt on the rising edge is selected.
DIDR1 register: has only two bits, AIN0D and AIN1D, with the following bitmap:
If AIN0D is set, the digital input buffer for AIN0 is disabled. If AIN1D is set, the digital input buffer for AIN1 is disabled. Disabling the digital input buffer for these pins is another way to save the power consumption of the controller.
ADCSRA register: an important bit for analog comparison in this register is ADEN. It has the following bitmap:
The ADEN bit is used to enable or disable Arduino ADC. If it’s set, ADC is enabled. Otherwise, ADC is disabled. The rest of this register’s bits configure analog-to-digital conversions in Arduino and have nothing to do with the analog comparison. (For example, the ADSC bit is used to start analog-to-digital conversion, and ADIF is used as ADC’s interrupt flag, etc.)
ADCSRB register: an important bit for analog comparison in this register is ACME. It has the following bitmap:
The ACME bit determines whether or not to use the analog multiplexed input. If ADEN is cleared (i.e., ADC is disabled and ACME is set), the analog input pins A0~A7 are used for negative input of the comparator. The rest of this register’s bits relate the analog-to-digital conversion and have nothing to do with the analog comparator.
ADMUX register: the MUX3:1 bits of the ADMUX register are used to select which analog input A0~A7 must be used as a negative input for the comparator. It has the following bitmap:
The analog source is selected based on the status of MUX3:1 bit, as per the table below.
The rest of this register’s bits relate to the analog-to-digital conversion and have nothing to do with the analog comparator.
Applications of an analog comparator
Arduino’s analog comparator is typically used for the following tasks…
Threshold detection: the analog comparison in Arduino is often used to detect if a voltage exceeds a certain threshold level. The input voltage is compared to a fixed reference voltage. Then, the analog comparator output is monitored to check whether the input voltage exceeds the fixed reference voltage. Threshold detection is commonly used to detect an analog sensor’s output, and if it has surpassed a predefined value.
Digital-to-Analog conversion: the Arduino comparator is used in conjunction with a resistor-ladder network, which is connected between the output pin of the comparator and a fixed reference voltage. The intermediate connection points are then used to create the desired digital voltage levels. This technique is typically used to generate analog reference voltages for the ADC.
PWM: an analog comparator can generate pulse width modulated signals to control a motor, a fading LED, or other PWM applications.
How to configure ATmega328P’s analog comparator
When using an analog comparator, only certain registers must be configured. It depends on the comparator’s sources of positive and negative input and the application of its output.
In normal operation, when signals to the comparator’s positive and negative are applied through AIN0 and AIN1 respectively, only the ACSR and DIDR1 registers must be configured in the user program.
For positive input of the comparator, the bandgap reference voltage can be used instead of the external input. When using the bandgap reference voltage as a positive input, the ACSR must be configured. The ACSR must also configure the comparator’s interrupt, interrupt mode, and input capture.
For negative input of the comparator, the analog input pins A0~A7 can be used. To set the external analog input source A0~A7 to a negative input, the ADCSRA, ADCSRB, and ADMUX registers must be configured.
In all cases, the DIDR1 register may be configured to enable or disable the digital input buffer for positive and negative input of the comparator.
Comparing signals
Now, let’s program a normal analog voltage comparison using Arduino. To do so:
- Connect two voltage sources to Arduino UNO’s PD6 and PD7 pins. The voltage can be applied through 10K potentiometers or voltage divider circuits.
- Connect an LED to Arduino’s PD4 pin to check the status of the analog comparator.
- Note: the anode of the LEDs must be connected to the pin and the cathode must be connected to the ground via a series resistor.
Upload the following sketch to the Arduino UNO.
void setup () {
DDRD |= (1<<PD4);
DIDR1 |= (1<<AIN0D) | (1<<AIN1D); // Disable Digital Inputs at AIN0 and AIN1
ADCSRB &= ~(1<<ACME); //Clear ACME bits in ADCSRB to use external input at AIN1 -ve input
ACSR =
(0 << ACD) | // Analog Comparator: Enabled
(0 << ACBG) | // Clear ACBG to use external input to AIN0 +ve input
(0 << ACO) |
(1 << ACI) | // Clear Pending Interrupt by setting the bit
(0 << ACIE) | // Analog Comparator Interrupt Disabled
(0 << ACIC) | // Analog Comparator Input Capture Disabled
(0 << ACIS1) | (0 << ACIS0); // Analog Comparator Interrupt Mode: Comparator Interrupt on Output
Toggle
}
void loop() {
if (ACSR & (1<<ACO))
PORTD |= (1<<PD4);
else
PORTD &= ~(1<<PD4);
}
When uploading the above sketch, if the voltage at the positive input (INV0/PD6) is higher than the voltage at the negative input, (INV1/PD7), the comparator output bit ACSR is set and the digital output at pin PD4 is set to HIGH, causing the LED to glow.
If the voltage at the positive input (INV0/PD6) is lower than the voltage at the negative input, (INV1/PD7), the comparator output bit ACSR is cleared and the digital output at pin PD4 is set to LOW, causing the LED to turn off.
You may also like:
Filed Under: Boards, Tutorials
Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.
Tell Us What You Think!!
You must be logged in to post a comment.