Thursday, May 24, 2018

ADC library for AVR microcontrollers (ATmega328P, ATtiny)

Nowadays even the cheapest microcontroller has a build-in ADC (Analog to Digital Converter). An ADC converts analog signals into digital signals and can be used in a wide range of applications like recording a signal from a microphone into a digital format, reading light sensors like an LDR (light dependent resistor), measuring current consumption, reading temperature or humidity sensors, etc. All these requires voltage measurements that an ADC can do.

On ATmega328 there are 8 ADC pins (channels) that can be connected to 8 different analog sources, but only one at a time can be measured. This pins ADC0 to ADC7 can also be used as digital pins. No resistor is required when taking voltage measurements. In case resistors are used, the datasheet recommends that the impedance from VCC should not exceed 10k. Care must be taken that the voltage to this pins must not exceed VCC. If the microcontroller is powered from 5V, don't put more than 5V on the pins. In case that higher voltages are to be measured, use resistor dividers.

The ADC has it's own pin for power supply named AVCC. This pin is recommended to be connected to VCC through an LC filter for noise suppression.

ADC power connections with LC filter and analog ground plane
ADC power connections with LC filter and analog ground plane

Most AVR microcontrollers have 10 bit ADC resolution but can be set to 8 bit resolution. Suppose that the voltage reference is set to VCC 5V and you measure a potentiometer with 10 bit ADC resolution. The minimum value returned by the ADC will be 0 - meaning ground - and the maximum value will be 2^10 = 1024 - 1 = 1023 (meaning 5V). The returned value will be between 0 and 1023. This value can be converted to voltage using the formula in the datasheet, but most of the time this is not needed.
To find out the minimum voltage that can be measured depending on the ADC resolution, divide voltage reference by the maximum ADC value. For 10 bit resolution and 5V Vref

Vref / 2^10
 5 / 1024 = 0.0048V (4.8mV)

On Atmega328 the voltage references that can be used are Vcc, 1.1 internal voltage reference or external voltage reference on Vref pin. The selected voltage reference will appear on Vref pin so be sure not to switch to internal reference if an external voltage is connected to Aref pin, otherwise the internal voltage reference will be shorted. It is recommended to place a 100nF decoupling capacitor between Aref pin and GND for better noise immunity.

ADC Library for AVR

This library uses the ADC interrupt, so the CPU doesn't have to wait for ADC conversion. Defaults to 10 bit resolution and external reference voltage.



How to use

Download the library and place the file inside the folder with the main.c file then include it

#include "adc.h"


Start the ADC conversion. Takes the pin number as an argument. For example if you want to read the pin ADC4, pass 4 to the function.
In this function the ADC is set up, but only the first time it is executed.
This function doesn't return anything.
On devices that supports this feature, the digital mode for the selected pin is disabled in order to safe power.

After the conversion is complete, the ADC value is obtained using this function.
To know when the ADC conversion is complete, check the ADC_COMPLETED variable. If 1, the ADC conversion is done, 0 otherwise.

Disable the ADC to save power. Return void.

Change the ADC resolution. The bit_resolution argument can be 8 or 10. Default 10.

Change the ADC reference voltage. Default Vref (external reference voltage).
reference_voltage can be one of the following defines:

VREF_VCC - AVCC with external capacitor at AREF pin
VREF_INTERNAL_1V1 - Internal 1.1V Voltage Reference with external capacitor at AREF pin (ATmega328)
VREF_INTERNAL_2V56 - Internal 2.56V Voltage Reference with external capacitor at AREF pin (ATmega8)
VREF_EXTERNAL - The voltage connected to AREF pin



Changelog v1.3:
    - Fixed the Digital Input Disable error for ATtiny13

Changelog v1.2:
    + Support for more CPU frequencies

Changelog v1.1
    + Support for ATtiny13

No comments:

Post a Comment