Skip to content

Arduino - Reading Analog Voltage

While Arduino operates in a digital world of HIGH and LOW, the real world is analog. Sensors that measure temperature, light, or position often produce a continuously varying voltage. This tutorial explains how to read these analog signals using Arduino’s Analog-to-Digital Converter (ADC) and convert them into meaningful data.

An ADC is a peripheral on the microcontroller that converts an analog voltage into a digital number. Key concepts include:

  • Resolution: The Arduino UNO has a 10-bit ADC. This means it can represent an analog voltage with 2^10 = 1024 distinct steps, numbered 0 to 1023.
  • Reference Voltage (AREF): This is the maximum voltage the ADC can measure. By default, it’s the board’s operating voltage (5V on an UNO). A reading of 0 corresponds to 0V, and a reading of 1023 corresponds to 5V.

The analogRead(pin) function performs this conversion and returns the integer value from 0 to 1023.

Project: Measuring Voltage with a Potentiometer

Section titled “Project: Measuring Voltage with a Potentiometer”

A potentiometer is a variable resistor that acts as a perfect voltage divider, making it an excellent tool for demonstrating analog input. By turning its knob, we can provide a variable voltage between 0V and 5V to an analog pin.

  • 1 × Arduino UNO R3 or compatible
  • 1 × 10kΩ Potentiometer
  • Jumper Wires
// A potentiometer has 3 pins.
// Connect the two outer pins to power and ground.
// The center pin (the 'wiper') is the output voltage.
Potentiometer Outer Pin 1 --- Arduino 5V
Potentiometer Outer Pin 2 --- Arduino GND
Potentiometer Center Pin --- Arduino Analog Pin A0

Arduino Code: Reading and Converting to Voltage

Section titled “Arduino Code: Reading and Converting to Voltage”

This sketch reads the raw ADC value from pin A0, converts it to a floating-point voltage, and prints the result to the Serial Monitor.

/**
* @file read_analog_voltage.ino
* @brief Reads an analog input, converts it to voltage, and prints it.
* @author Modernized Tutorial
*/
// The analog pin the potentiometer is connected to.
constexpr int ANALOG_IN_PIN = A0;
// The reference voltage of the ADC. On most Arduinos, this is 5.0V.
constexpr float REFERENCE_VOLTAGE = 5.0;
void setup() {
// Initialize serial communication for displaying results.
Serial.begin(9600);
}
void loop() {
// Read the raw integer value from the ADC (0-1023).
int sensorValue = analogRead(ANALOG_IN_PIN);
// Convert the ADC reading to a voltage value.
// The formula is: voltage = (ADC_reading / ADC_resolution) * reference_voltage
// For a 10-bit ADC, resolution is 1023.
float voltage = (sensorValue / 1023.0) * REFERENCE_VOLTAGE;
// Print the results to the Serial Monitor.
Serial.print("Raw Sensor Value: ");
Serial.print(sensorValue);
Serial.print("\t | Voltage: ");
Serial.print(voltage);
Serial.println(" V");
// Use the Serial Plotter (Tools > Serial Plotter) for a graphical view!
delay(100); // Wait a short time before the next reading.
}

Improving Reading Accuracy: Data Smoothing

Section titled “Improving Reading Accuracy: Data Smoothing”

Analog readings can sometimes be ‘noisy’ or unstable due to electrical interference or an unstable power supply. A common technique to fix this is to take multiple readings and average them. This is called smoothing or filtering.

This code modification reads the sensor multiple times in a row and averages the result to produce a more stable output.

// --- Add this code to your loop() for smoothing ---
const int NUM_READINGS = 10; // Number of samples to average
long total = 0;
for (int i = 0; i < NUM_READINGS; i++) {
total += analogRead(ANALOG_IN_PIN);
delay(1); // Small delay between readings
}
int sensorValue = total / NUM_READINGS; // Calculate the average
// ... the rest of your voltage conversion and printing code follows

If you are measuring a sensor that only outputs a small voltage range (e.g., 0-1.1V), using the default 5V reference is inefficient. You can get more precise readings by changing the reference voltage to a lower value using analogReference(). For an UNO, you can choose INTERNAL (1.1V) or provide an external reference voltage via the AREF pin.

void setup() {
Serial.begin(9600);
// Use the internal 1.1V reference.
// IMPORTANT: Do not connect anything to the AREF pin when using this!
// Never use an external reference voltage lower than 0V or higher than 5V.
analogReference(INTERNAL);
}
// In your loop, remember to use 1.1 in your voltage calculation!
// float voltage = (sensorValue / 1023.0) * 1.1;