Skip to content

Arduino - Advanced I/O Function

In this chapter, we will explore advanced Input/Output functions that give you finer control over your board’s behavior. We’ll focus on analogReference(), a powerful function for optimizing analog inputs.

By default, Arduino’s analog-to-digital converter (ADC) maps input voltages between 0V and 5V (or 3.3V on some boards) to integer values between 0 and 1023. The analogReference() function allows you to change the upper limit of this voltage range, which can significantly increase the precision of your measurements, especially for sensors that operate at lower voltages.

Reference Options for AVR Boards (e.g., UNO, Mega)

Section titled “Reference Options for AVR Boards (e.g., UNO, Mega)”
  • DEFAULT: The default analog reference. 5V on 5V boards and 3.3V on 3.3V boards.
  • INTERNAL: A built-in reference voltage. On the ATmega328P (UNO), this is a stable 1.1V. On the ATmega2560 (Mega), this is also 1.1V (INTERNAL1V1) or 2.56V (INTERNAL2V56).
  • EXTERNAL: Uses the voltage applied to the AREF pin (0V to 5V only) as the reference.
analogReference(type);

type can be DEFAULT, INTERNAL, INTERNAL1V1, INTERNAL2V56, or EXTERNAL depending on your board.

Do not use a voltage less than 0V or more than 5V for the external reference on the AREF pin. When using an external reference, you must call analogReference(EXTERNAL) before you call analogRead(). Failing to do so can short the internal reference voltage to the AREF pin, potentially causing permanent damage to the microcontroller.

  • Check Your Board’s Documentation: Boards with different microcontrollers (like the ARM-based Arduino Due, Zero, or UNO R4) have different internal reference options and voltage levels. Always consult the official documentation for your specific board before using this function.
  • Use a Stable Reference: When using EXTERNAL, ensure the voltage source is stable and clean. Any noise on your reference voltage will directly impact the accuracy of your readings.

Example: Reading a Sensor with a 3.3V Reference

Section titled “Example: Reading a Sensor with a 3.3V Reference”

Imagine a sensor that outputs a maximum of 3.3V. By setting the analog reference to 3.3V, we use the full 0-1023 resolution of the ADC over this smaller voltage range, resulting in a more precise reading.

/*
This example demonstrates using an external analog reference.
Connect a stable 3.3V source to the AREF pin.
Connect your sensor's output to pin A0.
*/
// Use const for pin definitions for good practice
const int SENSOR_PIN = A0;
void setup() {
Serial.begin(9600);
// Good practice for boards with native USB:
while (!Serial) {
; // wait for serial port to connect.
}
// Set the analog reference to the external voltage on the AREF pin.
// CRITICAL: Ensure your 3.3V source is connected to AREF before running.
analogReference(EXTERNAL);
}
void loop() {
// Read the value from the sensor
int sensorValue = analogRead(SENSOR_PIN);
// Convert the 0-1023 reading into a voltage based on the 3.3V reference
float voltage = sensorValue * (3.3 / 1023.0);
Serial.print("Raw Sensor Value: ");
Serial.print(sensorValue);
Serial.print(", Calculated Voltage: ");
Serial.print(voltage);
Serial.println(" V");
delay(500); // Wait half a second before the next reading
}