Adc arduino

Analog to Digital Conversion


The Analog World

Microcontrollers are capable of detecting binary signals: is the button pressed or not? These are digital signals. When a microcontroller is powered from five volts, it understands zero volts (0V) as a binary 0 and a five volts (5V) as a binary 1. The world however is not so simple and likes to use shades of gray. What if the signal is 2.72V? Is that a zero or a one? We often need to measure signals that vary; these are called analog signals. A 5V analog sensor may output 0.01V or 4.99V or anything inbetween. Luckily, nearly all microcontrollers have a device built into them that allows us to convert these voltages into values that we can use in a program to make a decision.

Here are some topics and concepts you may want to know before reading this tutorial:

What is the ADC?

An Analog to Digital Converter (ADC) is a very useful feature that converts an analog voltage on a pin to a digital number. By converting from the analog world to the digital world, we can begin to use electronics to interface to the analog world around us.

alt text

Not every pin on a microcontroller has the ability to do analog to digital conversions. On the Arduino board, these pins have an ‘A’ in front of their label (A0 through A5) to indicate these pins can read analog voltages.

ADCs can vary greatly between microcontroller. The ADC on the Arduino is a 10-bit ADC meaning it has the ability to detect 1,024 (2^10) discrete analog levels. Some microcontrollers have 8-bit ADCs (2^8 = 256 discrete levels) and some have 16-bit ADCs (2^16 = 65,536 discrete levels).

The way an ADC works is fairly complex. There are a few different ways to achieve this feat (see Wikipedia for a list), but one of the most common technique uses the analog voltage to charge up an internal capacitor and then measure the time it takes to discharge across an internal resistor. The microcontroller monitors the number of clock cycles that pass before the capacitor is discharged. This number of cycles is the number that is returned once the ADC is complete.

Relating ADC Value to Voltage

The ADC reports a ratiometric value. This means that the ADC assumes 5V is 1023 and anything less than 5V will be a ratio between 5V and 1023.

alt text

Analog to digital conversions are dependant on the system voltage. Because we predominantly use the 10-bit ADC of the Arduino on a 5V system, we can simplify this equation slightly:

alt text

If your system is 3.3V, you simply change 5V out with 3.3V in the equation. If your system is 3.3V and your ADC is reporting 512, what is the voltage measured? It is approximately 1.65V.

If the analog voltage is 2.12V what will the ADC report as a value?

alt text

Rearrange things a bit and we get:

alt text
alt text

Ahah! The ADC should report 434.

Arduino ADC Example

To show this in the real world let’s use the Arduino to detect an analog voltage. Use a trimpot, or light sensor, or simple voltage divider to create a voltage. Let’s setup a simple trimpot circuit for this example:

alt text

To start, we need to define the pin as an input. To match the circuit diagram we will use A3:

and then do the analog to digital version by using the analogRead() command:

The value that is returned and stored in x will be a value from 0 to 1023. The Arduino has a 10-bit ADC (2^10 = 1024). We store this value into an int because x is bigger (10 bits) than what a byte can hold (8 bits).

Let’s print this value to watch it as it changes:

As we change the analog value, x should also change. For example, if x is reported to be 334, and we’re using the Arduino at 5V, what is the actual voltage? Pull out your digital multimeter and check the actual voltage. It should be approximately 1.63V. Congratulations! You have just created your own digital multimeter with an Arduino!

Hooking Things Up Backward

What happens if you connect an analog sensor to a regular (digital) pin? Nothing bad will happen. You just won’t be able to do an analogRead successfully:

This will compile but x will be filled with a nonsensical value.

What happens if I connect a digital sensor to an analog pin? Again, you will not break anything. If you do an analog-to-digital conversion on a button, you will most likely see ADC values very close to 1023 (or 5V which is binary 1) or very close to 0 (or 0V which is binary 0).

Resources and Going Further

Doing analog digital conversions is a great thing to learn! Now that you have an understanding of this important concept, check out all the projects and sensors that utilize analog to digital conversion.



New version v1.2

  • 16-bit resolution
  • Maximum of 860 samples per second
  • Up to 4 inputs per module
  • Up to 4 modules simultaneously - 16 inputs total
  • Internal amplifier for low amplitude signals
  • RC filter in all channels
  • Analog inputs protected against accidental connections up to ±24V

The ADC Nanoshield offers a solution for applications that need high resolution analog-to-digital conversion, or when it is necessary to expand the number of analog inputs beyond what's available in the microprocessor. Implemented with the IC ADS1115, the ADC Nanoshield is ideal for applications such as reading temperature, pressure or humidity industrial sensors, among other types. It can also be used to monitor batteries, supply voltages, or any other project that needs analog to digital conversion with high quality.

The ADC Nanoshield has the following features:

  • Factory configuration for reading voltage between 0V and 5V.
  • Each of the 4 inputs can be easily converted for reading voltages from 0V to 10V.
  • One of the inputs (A0) can be converted for reading voltages from 0V to 24V.
  • Possibility of direct measurement of the power supply voltage (VIN or VCC).

Check the Available Configurations section for more information about the usage scenarios.

!Connecting the analog inputs

The ADC Nanoshield features four independent analog inputs. They can be used both for reading absolute voltages (the voltage read on the channel is measured relative to the GND of the module), as well as for reading the channels in differential mode (one channel is read relative to the other).

Absolute measurements (Single Ended)

In order to measure absolute voltage, you must connect the the signal to be measured on the GND pin and in one of the 4 inputs of the module via the screw terminal block. The inputs are named A0, A1, A2 and A3 and have a measurement range from 0V to 5V. In this kind of connection, the measurement has a 15-bit resolution.

The figure below shows the connection of four sensors with absolute measurement:


Connecting of four sensors in single ended mode

Differential mode measurements

In differential mode, it is possible to read channels relative to each other, instead of using them in relation to GND. For instance, if the two channels that are being measured present the same voltage, then the measurement will be equal to zero. This mode is useful for reading sensors that work using a Wheatstone Bridge, for example. Keep in mind that, even though the measurement is not done directly in relation to GND, the allowed voltage range in each channel is still from 0V to 5V relative to GND. With this kind of connection, it is possible to use all 16 bits of resolution.

The figure below shows an example of two sensors being read in differential mode:


Connection of two sensors read in differential mode

!Connecting to an Arduino via Base Board Uno

The easiest way to use the ADC Nanoshield along with an Arduino is using the Base Board Uno or Base Board L Uno. You just need to plug the boards together (no wiring needed!) and then load our sample code in order to check the system is working. See the sample code section at the bottom of the page for more information. This assembly option can be used with Arduino UNO, Mega R3, Duemilanove, and other compatible boards. The figure below shows how the setup looks like.

Connecting to an Arduino using the Base Board Uno (click on the image to zoom)

!Connecting to a Base Boarduino

It is also possible to connect the ADC Nanoshield directly to our Arduino-compatible board, the Base Boarduino. The connection is done the same way it is done with the Base Board, such as illustrated below. You just have to assemble the boards and then load our sample code to check the system working. See the sample code section at the bottom of the page for more information.

Connecting to a Base Boarduino (click on the image to zoom)

!Direct connection to an Arduino

It is also possible to use the module with a direct assembly, using a breadboard and jumper wires to make the connection to an Arduino or another similar microcontroller board. Use the following schematics to connect the ADC Nanoshield to an Arduino UNO or Arduino Mega.

Direct connection to an Arduino UNO (click on the image to zoom)

Direct connection to an Arduino MEGA (click on the image to zoom)

!Using several modules simultaneously

The ADC Nanoshield communicates with the microcontroller via an I2C communication bus. One of the advantages of the I2C bus is the possibility to use several modules simultaneously with only 2 microcontroller pins: one for clock (SCL) and one for data (SDA).

Each module connected to an I2C bus needs a unique address. The ADC Nanoshield features 4 options of addresses that are selectable via jumpers at the upper part of the board. This way, it is possible to use up to 4 modules simultaneously, featuring 16 independent channels using only 2 microcontroller pins. The figure below shows where the address selection jumpers are located.

Jumpers for I2C address selection

The module address on the I2C bus has 5 fixed bits (10010) and two other bits that are configurable. By using the jumpers, it is possible to individually select these last two bits for each module. The options are: 00, 01, 10 and 11. In order to make the selection, just close the jumper corresponding to the desired address, leaving the others open (the factory default is 00). This way, the complete address of the module can be 1001000 (default), 1001001, 1001010 or 1001011.

The figure below shows a setup with 4 modules being used simultaneously. In this example we use a [Base Board UNO][nanoshield:base-board-uno] along with an Arduino Mega.

Using several modules simultaneously (click on the image to zoom)

!Available Configurations

Reading sensors with output from 0 to 10V

Each one of the 4 inputs on the ADC Nanoshield can be easily configured to read voltages from 0V to 10V. This is done through a voltage divider circuit, which comes factory-implemented, and only needs to be enabled by closing a solder jumper on the board. Each one of the inputs has its own voltage divider circuit and therefore can be configured independently.

Four solder jumpers are used for this purpose: JP0, JP1, JP2 and JP3, They correspond to the A0, A1, A2 and A3 inputs, respectively. When closed, each jumper enables the voltage divider for the given input, setting the reading range to be 0-10V. The table below shows the usage modes (for more details, check the schematics of the module available at the bottom of the page):

JP0A0: 0 to 5VA0: 0 to 10V
JP1A1: 0 to 5VA1: 0 to 10V
JP2A2: 0 to 5VA2: 0 to 10V
JP3A3: 0 to 5VA3: 0 to 10V


Select measurement range to be 0-5V or 0-10V

The voltage divider circuit divides the input voltage by 2.5. Thus, the 10V voltage becomes 4V. In order to maximize the measurement range, use gain 1 on the internal amplifier (which corresponds to a full scale range of 4.096V). Check the Internal Amplifier section for more information.

The figure below shows a typical connection of a 0-10V sensor to the ADC Nanoshield.


Connecting a 0-10V sensor to the ADC Nanoshield

Measuring voltages up to 24V with the A0 input

Input A0 differs from the other ones by being capable of reading voltages up to 24V. This is done by a second voltage divider circuit that already comes factory-implemented and that can be enabled by closing a solder jumper on the board. The jumper that enables this function is the JP0A (see the figure below).

JP0AA0: 0 to 5VA0: 0 to 24V


Jumper to enable reading up to 24V on the A0 input

The voltage divider circuit divides the voltage by 5.84 and thus 24V are transformed to 4.1V. In order to maximize the measuring range, use gain 1 on the internal amplifier (which corresponds to a full scale range of 4.096V). Check the Internal Amplifier section for more information.

Measuring the supply voltage with A0

It is also possible to directly measure the supply voltage on Arduino through the A0 input. This function is enabled though the solder jumper SUP_MSR located at the bottom of the board (see the figure below). You can choose to directly measure the voltage from the power supply, indicated as VIN on Arduino, or the voltage indicated as 5V on Arduino, which is provided by the USB port in the case when there is no external power supply.


Measuring the power supply voltage with the A0 input

Use the SUP_MSR jumper along with J0 or JP0 to maximize the measurement range. For example, in case the external power supply voltage is about 9V, you can use the SUP_MSR to select the VIN voltage and close the jumper J0. This way the full scale voltage becomes 10V and it is possible to measure the external power supply voltage with good precision. In case the external power supply voltage is about 12V, you can use the SUP_MSR to select the VIN voltage and close the jumper JP0, getting a full scale measurement range of 24V.

Operation at 3.3V

The ADC Nanoshield can also be configured to work with a 3.3V power supply. This configuration is useful when the module is used with other boards that work with 3.3V, such as the Arduino Zero, Arduino DUE and others.

In order to change the module’s main supply voltage, it is necessary to change the solder jumper caller POWER, located on the top side of the board. The figure below shows how to change this:


Power supply configuration for the ADC Nanoshield

This change is necessary only if the module is being used along with a Base Board or Base Board L. In case you are using the module connected with jumper wires, just connect the VCC pin of the module directly to the supply voltage of 3.3V.

If the module is powered with 3.3V, the maximum reading range allowed is from 0V to 3.3V. The measuring options for signals from 0V to 10V and 0V to 24V cannot be used with a 3.3V power supply.

!Additional Resources

Internal Amplifier

The chip features an internal amplifier with adjustable gain, which can be used to increase the resolution when the input signal has a low amplitude. The amplifier gain can be set to 2/3, 1, 2, 4, 8 or 16. The table below shows which is the full scale voltage for each amplifier gain (full scale voltage is the higher voltage value that can be read).

GainFull Scale Voltage (V)

Full scale voltage for each internal amplifier gain setting

¹For the 2/3 gain, although the full scale voltage equals 6.144V, the maximum reading range is from 0V to 5V.

The input voltage can be higher than full scale without the module being damaged. For example, even using gain 16, for which the full scale voltage is 0.256V, the maximum voltage supported by the analog inputs is still ±24V.

Internal Comparator

The chip features a programmable internal comparator that can be configured to generate an alert when the voltage value on the analog input exceeds some user-configurable limit. Therefore, the module can "notify" the microcontroller about a desired event through an interrupt. This way, it is not necessary to measure the input continuously.

The alert signal is sent through pin 3 on Arduino (on the ADC Nanoshield, this pin is called "ale"). This function is disable in the factory default setting. In order to activate it, it is necessary to close the solder jumper caller ALERT, located at the top side of the board.

Block Diagram

The ADC Nanoshield communicates with the processor through an I2C bus that uses only 2 pins. The block diagram below shows how the module works.


ADC Nanoshield Block Diagram

Each input on the ADC Nanoshield features a low-pass RC filter with:

  • Anti-aliasing and noise attenuation on the analog inputs
  • Protection on the analog inputs against accidental connections up to ±24V
  • Configurable circuit, enabling sensors' readings from 0V to 5V or 0V to 10V, among other applications

The filter has cutoff frequency of approximately 480Hz.

Electrical Characteristics

  • Power supply: is provided via the VCC pin with a range from 4.5 to 5.5V (5V typical). Optionally, the board can be powered using the 3V3 pin with range from 3V to 3.6V. For this purpose it is necessary to change the POWER jumper (see instructions on the schematics).

  • Current consumption: the maximum current consumption is 300uA.

  • Logic Levels: the I2C communication and the output signal ALERT (optional) come factory-configured to work with 5V. The analog inputs work with voltage up to 5V and are protected against accidental connections up to ±24V.


The table below describes the function of each one of the used signals and the correspondence to the pins on Arduino UNO and Arduino MEGA.

SignalArduino UNOArduino MEGAFunction
ale33Alert pin: comparator output or end of conversion (optional)
SDAA420I2C data
SCLA521I2C clock
VCCVCCVCC5V power supply input
GNDGNDGNDReference voltage (ground)

Pin descriptions

!Sample Code

  1. Hafiz quotes
  2. Torah cafe
  3. Terraria drill
  4. Lamborghini canvas



Reads the value from the specified analog pin. Arduino boards contain a multichannel, 10-bit analog to digital converter. This means that it will map input voltages between 0 and the operating voltage(5V or 3.3V) into integer values between 0 and 1023. On an Arduino UNO, for example, this yields a resolution between readings of: 5 volts / 1024 units or, 0.0049 volts (4.9 mV) per unit. See the table below for the usable pins, operating voltage and maximum resolution for some Arduino boards.

On ATmega based boards (UNO, Nano, Mini, Mega), it takes about 100 microseconds (0.0001 s) to read an analog input, so the maximum reading rate is about 10,000 times a second.

BoardOperating voltageUsable pinsMax resolution


5 Volts

A0 to A5

10 bits

Mini, Nano

5 Volts

A0 to A7

10 bits

Mega, Mega2560, MegaADK

5 Volts

A0 to A14

10 bits


5 Volts

A0 to A11*

10 bits


5 Volts

A0 to A11*

10 bits


3.3 Volts

A0 to A5

12 bits**


3.3 Volts

A0 to A11

12 bits**

MKR Family boards

3.3 Volts

A0 to A6

12 bits**

*A0 through A5 are labelled on the board, A6 through A11 are respectively available on pins 4, 6, 8, 9, 10, and 12
**The default resolution for these boards is 10 bits, for compatibility. You need to use analogReadResolution() to change it to 12 bits.



: the name of the analog input pin to read from (A0 to A5 on most boards, A0 to A6 on MKR boards, A0 to A7 on the Mini and Nano, A0 to A15 on the Mega).


The analog reading on the pin. Although it is limited to the resolution of the analog to digital converter (0-1023 for 10 bits or 0-4095 for 12 bits). Data type: .


Read Analog Voltage

Tutorials > Examples > Basics > ReadAnalogVoltage

This example shows you how to read an analog input on analog pin 0, convert the values from analogRead() into voltage, and print it out to the serial monitor of the Arduino Software (IDE).

Hardware Required

  • Arduino Board

  • 10k ohm potentiometer



Connect the three wires from the potentiometer to your board. The first goes to ground from one of the outer pins of the potentiometer. The second goes to 5 volts from the other outer pin of the potentiometer. The third goes from the middle pin of the potentiometer to analog input 0.

By turning the shaft of the potentiometer, you change the amount of resistance on either side of the wiper which is connected to the center pin of the potentiometer. This changes the voltage at the center pin. When the resistance between the center and the side connected to 5 volts is close to zero (and the resistance on the other side is close to 10 kilohms), the voltage at the center pin nears 5 volts. When the resistances are reversed, the voltage at the center pin nears 0 volts, or ground. This voltage is the analog voltage that you're reading as an input.

The microcontroller of the board has a circuit inside called an analog-to-digital converter or ADC that reads this changing voltage and converts it to a number between 0 and 1023. When the shaft is turned all the way in one direction, there are 0 volts going to the pin, and the input value is 0. When the shaft is turned all the way in the opposite direction, there are 5 volts going to the pin and the input value is 1023. In between, analogRead() returns a number between 0 and 1023 that is proportional to the amount of voltage being applied to the pin.




In the program below, the very first thing that you do will in the setup function is to begin serial communications, at 9600 bits of data per second, between your board and your computer with the line:

Next, in the main loop of your code, you need to establish a variable to store the resistance value (which will be between 0 and 1023, perfect for an datatype) coming in from your potentiometer:

To change the values from 0-1023 to a range that corresponds to the voltage the pin is reading, you'll need to create another variable, a , and do a little math. To scale the numbers between 0.0 and 5.0, divide 5.0 by 1023.0 and multiply that by sensorValue :

Finally, you need to print this information to your serial window as. You can do this with the command Serial.println() in your last line of code:

Now, when you open your Serial Monitor in the Arduino IDE (by clicking on the icon on the right side of the top green bar or pressing Ctrl+Shift+M), you should see a steady stream of numbers ranging from 0.0 - 5.0. As you turn the pot, the values will change, corresponding to the voltage coming into pin A0.

See Also:

Last revision 2015/07/29 by SM

Last revision February 05, 2018, at 08:43 PM


Arduino adc

Arduino ADC

The Arduino ADC or Analogue to Digital Converter takes an input voltage and converts it into a digital value. With the standard setup you can measure a voltage between 0V and 5V with a resolution of 4.9mV so you can get a lot of detail when measuring analogue voltages.

Arduino Analog Pins

There are six pins on the Arduino Uno (shown below A0 ~ A5) that can be selected for an ADC measurement; A multiplexor feeds one of the six analogue input pins into the ADC.

To read an analogue voltage from pin A4 you use the following code and function:

int val;
val = analogRead(A4);

Setting of the multiplexor is done in that function for you automatically.

arduino uno analogue pins

Arduino ADC Specification

Arduino Uno/Nano
  Voltage Supply (Vs)
 1V8 ~ 5V5
Built in
8 bit
Absolute Accuracy(Including INL, DNL,
  quantization error, gain & offset error) [1]
  Offset error (ADC, DAC) [1]
INL [1]
0.50 LSB
DNL [1]
0.25 LSB
Gain error [1]
  Sampling frequency
9.6Hz [2]
  Operating temperature
-40°C ~ 85°C
            [1] for 4V operation and 200kHz ADC sampling clock.
            [2] for 5V operation and 125kHz ADC sampling clock (See below).

Arduino ADC size

The Arduino ADC has a 10 bit converter, and that means there are 1024 distinct values that can be returned as a result from the ADC:

since  pow(2,10) = 2^10 = 1024

Divide by 1023 or 1024?

There is always some confusion about whether to divide by 1024 or 1023 to get the voltage value for each bit.

However the ATMega328P datasheet gives the following formula:

ADC= (Vin*1024)/Vref

re arranging that gives:

Vin = (Vref/1024)*ADC

Arduino ADC resolution at 5V

So for Vref=5V, an ADC value of 1 would result in a Voltage step of 4.88mV - the value of voltage for one LSB - this is the Arduino ADC resolution for a 5V Vref.

Note however that the maximum ADC value is 1023 so the maximum ADC value that can ever be reported is:

1023 * (5/1024) = 4.9951V

As it states in the datasheet:

"0x000 represents analog ground, and 0x3FF represents the selected reference voltage minus one LSB."

The reason that you will see the wrong equation on the web is so that the output "feels" right i.e. 1023*(5/1023) = 5.000. This is the wrong equation to use and means there is an offset added to all values.

This ADC is known as a successive approximation ADC and requires several clock cycles to zoom in on the correct ADC output.

The ADC converter compares the input analogue voltage to a portion of the Vref voltage using a divide by two sequence. The sample and hold capacitor is charged to the input voltage and then the input disconnected so that the same voltage is measured throughout the conversion process.

It first checks whether the input voltage is higher or lower than half of the Vref voltage, by using a DAC to generate half the reference voltage. The DAC voltage is the fed into a comparator.

The output of the DAC forms the high bit of the result (stored in a shift register). If the input voltage is higher then the bit is one, otherwise the bit zero.

If the input is lower than half of the Vref voltage then control logic generates a DAC voltage that is 1/4 the reference voltage. The comparison is made again and this forms the next bit in the ADC output.

The process continues until all the bits are collected.

ADC clock

For the Arudino the conversion process takes 13 cycles of the ADC clock - which you set using a prescaler in the ADC module. The ADC clock must be between 50kHz and 200kHz so you choose the prescaler value to get a valid ADC clock.

The ADC clock prescaler can be set as a 2n division from 2 to 128. You obviously want the fastest conversion rate for the clock in use so for a 16MHz system clock you would calculate 16e6/200e3 = 80 so the closest could be 64.

However 16e6/64 is 250kHz and is too big. Therefore choosing a divisor of 128 must be used so the ADC clock will be 16e6/128 = 125kHz.

A conversion will take 13 ADC clock cycles :

    13 * 1.0/(125e3) = 104us

Check that these settings are used in the Arduino Source code! - I have not - they are extremely likely though.

Arduino Uno sampling rate (16MHz crystal)

1.0 / ( 13 * 1.0/125e3) = 9615Hz

Actually, reading the Arduino reference page it says the sample rate is about 10kHz so this calculation matches that information.

So the maximum Arduino ADC sampling rate is:


The above rate is the maximum sampling rate but to reproduce a sinewave requires double the sampling rate (Nyquist theorem). Another way of looking at it is that the bandwidth of the signal you can safely reproduce is half the sampling rate.

Warning: 9.615kHz the sample rate, the bandwidth is half (4.8kHz).

However this is only dealing with sinewaves and not "real signals". You cannot reproduce a square wave at 4.8kHz because the edges of the signal are at a far higher frequency (Fourier analysis) - in fact you would end up with a 4.8kHz sine wave if trying to reproduce a 4.8kHz square wave by converting it with and ADC with a 9.615kHz ADC clock. This is why digital oscilloscopes have sample rates about 10 times higher than the maximum desired operational frequency.

Changing the Arduino Sampling Rate

ADC clock calculations

If you set the system clock to 20MHz you get 20e6/128 = 156250.0 - for a bit faster conversion.

Interestingly if you go the other way as a design decision you want the fastest ADC clock rate of 200kHz, then you have to ask the question:

"What crystal clock results in a 200kHz rate after ADC prescaling?" i.e.

Xtal = 200e3 * prescale - trying 64 gives 12800000 or 12.8Mhz

12.8e6/64 = 200e3

So reducing the Xtal clock allows a faster conversion rate of 200kHz!

Giving a max samping rate of:

1.0 / ( 13 * 1.0/200e3) = 15384Hz (THIS IS FOR  A 12.8MHz XTAL)

...and yes you can get crystals made to your spec! - but you'll probably use a 12MHz crystal, as its easier to get, so the sample rate above will be a bit lower.

This is a diagram of the action or the successive approximation ADC using Vref as 5V. Here a 4 bit ADC is shown but the principle is the same however many bits are used.

4 bit ADC Operation

Initially the input voltage (Vin) is greater than the starting value of the DAC voltage (set by initial DAC value of B1000) so this bit is kept. In the next processing period the DAC output is set to B1100 but in this case the DAC voltage becomes greater than Vin (and that bit is discarded).

The next two DAC values are kept because the DAC voltage is always lower than Vin and you end up with an ADC output value of B1011 - the ADC successively approaches the final value.

Example of successive approximation 4bit ADC

The final output DAC voltage is 2.5 + 0.625 + 0.3125 = 3.4375V

The advantage of the successive approximation ADC is that it is deterministic i.e. it always takes the same amount of time. Consider using a binary counter as the input to the DAC that always started at zero and counted up. For a low Vin it would take a few counts to find the value and for a high Vin it would take lots of counts (possibly 255 cycles for an 8 bit DAC) i.e. it would take different times depending on the input voltage!

Note: As the number of bits in the ADC increases so does the acquisition time.

As we saw earlier the resolution of the ADC, when Vref=5V is 4.88mV per step.

The Arduino analogRead resolution which is the same as the resolution of the ADC is governed by two things

  1. The ADC size - 10bits for the Uno.
  2. The ADC reference voltage - You can feed in your own voltage as well or use the internal reference.

Note: You can use an oversampling trick to increase the number of bits.

ADC bits

Note: The arduino function analogReadResoution() allows the analogRead() function to return a different number of bits.

Some of the Arduinos e.g. DUE have 12 bit ADCs built in, so returning 10bits will keep the code in these boards compatible with other Arduino boards that only have a 10 bit ADC. This is the default operation - to get 12 bits you will need to use analogReadResoution(12).

Using an ADC with more bits makes the the minimum step size (LSB) smaller to give higher resolution. The Arduino Uno is fixed at 10 bits but there is a way of increasing the number of apparent bits; see this page: Arduino ADC bit increasing.

ADC Reference voltage

You can use three sources of ADC reference voltage:

  1. The power supply.
  2. The internal reference diode (nominally 1.1V).
  3. An external voltage reference.

The reference voltage is the full-scale voltage applied to the ADC converter operating as described above.

Say you changed the Vref value to 1V then the minimum LSB you could detect would be 1/1024 or


TIP: You can select the internal 1.1V reference and this will give a step size of about 0.1V: Exact calculation is 1.1/1024 = 0.00107V ~0.11mV per step . This does mean the ADC can't read voltages above 1.1V - they will just return 1023.

Warning: Never turn on the internal reference while applying an external voltage to the reference pin.

Before turning on the internal reference check that there is no external voltage applied. If there is it is likely you will blow something up (see the ADC block diagram below).

Arduino ADC MUX showing internal voltage reference

Reason for the smoke problem

The problem is that you might create a direct path from AREF to AVCC, or the internal reference, by turning on the FET while there is a voltage at AREF. To avoid this problem don't fiddle with the Analogue reference if there is any voltage applied to Aref.

The 'Internal 1V1 reference' voltage and the AVCC voltage are controlled though a MUX, and then through a MOSFET, and are then connected to AREF. If an external voltage is applied and the reference or AVCC selected then the MOSFET (and MUX) offers a path (its resistance Rds) to the voltage difference = heat and possible smoke!

The default state of the ADMUX bits REFS1 and REFS0 is zero, meaning that AREF and "Internal Vref" are turned off (from datasheet). So from power up the reference source is from the AREF pin i.e. it is "safe".

What Reference voltage does Arduino Code use?

If you examine the code in the example below you will see that the analogue reference AREF is not mentioned at all. For the ADC to measure voltage it must have a reference!

In fact if you use the analogread() function then the it will activate the selected reference source. The default reference source is AVCC (the power supply).

When writing Arduino code this makes it easy to use the analogue read function as the default state is to use the power supply for the reference voltage.

This presents a problem if you want to use the AREF input pin as the reference source. The solution is always, at the start of code - in the setup() function - to select the reference source before any analogue read function is used.

Setting the Arduino reference source

The Arduino function to use the internal 1V1 reference is:


The Arduino function to use the voltage at the AREF pin as the reference is:


This function sets the ADC to use the Supply (VCC) as the reference.


NOTE: The reference is updated just during analogread(<n>).

NOTE: Some boards have other internal voltage reference levels available. See the Arduino page on analogReference for more information.

You can find out much more about the internal (1V1) reference here.

Connect a 10k potentiometer with wiper (middle) to pin A0 and one end to 5V, and the other end to Ground. This example simply uses the arduino analog read function analogRead() to read data from the specified analogue pin.

Start the serial monitor, and observe the led period. The on-off time is twice the value of the analogue value so it varies from 2s to ~0.

You can use an ADC pin as an:

  • Analogue input,
  • A digital input,
  • A digital output.

Note: Other functions can be shared by a pins e.g. A5 is also SCL.

The internal structure of an ADC input pin allows the pin to be multi functional. Some people get confused using an ADC pin as a digital input or output but it is perfectly valid to do so (as long as it has digital logic driving the input signal).

The only caution on using ADC pin as a digital input is that if you have designed the external circuit for measuring an analogue voltage, that voltage could cause the digital input to overload.

In CMOS circuits there are two FETS, a high fet and a low fet,  connected to the a common output - their inputs are also connected. These act as current source and sinks - to allow a large fan out. In normal use the logic driving these inputs is logic high or low. If you drive them at the mid range voltage (think analogue input at Vcc/s) then you are turning both on at the same time. Therefore lots of current flows!

To avoid this situation for a "digital only" input you tie the input to the high voltage using a pull-up, and of course the Arduino has internal pull-ups provided for just this operation.

The reason for the pull-up is that bias voltages in the CMOS circuit (FET circuit) will set the input to some floating value which could turn on both FETs. So to be certain this does not happen, enable the pull-up on each digital input pin.

You can see that if external analogue circuitry drives the inputs to mid range, there will be a problem if you set the pin to digital input. So avoid doing this!

Privacy Policy | Contact | About Me

Site Map | Terms of Use


The ADS1115 is an external digital analog converter (ADC) that we can connect to a processor like Arduino to measure analog signals. Arduino has internal ADCs that we use when we use the Arduino analog inputs. On the Arduino Uno, Mini and Nano models, we have 6 ADC of 10 bits. The ADS1115 provides 4 16-bit ADCs, 15 for the measurement and one last for the sign. The ADS1115 is connected by I2C, so it is easy to read. It has 4 addresses, which is chosen by connecting the ADDRESS pin. The interest of using an ADC such as the ADS1115 is to obtain greater precision, in addition to freeing the processor from this burden. In addition, in certain configurations, it is possible to measure negative voltages.

ADS1115 16 bit ADC Arduino Tutorial

The connection is simple. On the one hand, we feed the module from Arduino through GND and 5V and connect the SDA and SCL pin of Arduino with the corresponding pins of the sensor. The ADDR pin determines the I2C address of the device, according to the following table. The default mode is to connect the ADDR pin to GND, which results in the address 0x48.

We need:
1 x Arduino NANO/UNO: LINK eBay
1 x ADS1115 sensor: LINK eBay
1 x i2c LCD: LINK eBay
1 x Jump wires: LINK eBay
1 x Breadboard: LINK eBay

ADS1115 ADC arduino connection schematic

The following code shows the use of single end mode. We read the four channels and show the value per serial port. To convert the value to voltage it is necessary to use a multiplier, which at the same time depends on the gain of the PGA that we have set. We print the values on the serial monitor or LCD. See codes below.

Download serial monitor example code:
Download Adafruit_ADS1015 library:

Upload the code and make the connections. Then open the serial monitor at 9600 bauds and you will have the results printed to the serial monitor. Or go below and download the code with the i2c LCD.

Download LCD example code:
Download i2c LCD library:

Upload the code and make the connections. Then open the serial monitor at 9600 bauds or just see the results on the LCD screen.

Help me by sharing this post



Now discussing:

The scandal was just not enough. At this tense moment, a third companion appeared at the door. A tall, stout and slightly drunk man of about thirty-five. Making an inarticulate sound, which apparently should have meant a greeting, he climbed onto the top shelf, wrapped himself in a blanket and.

Fell asleep.

1575 1576 1577 1578 1579