# analogRead and the ADC — Arduino & Embedded C

Source: https://www.geekswithgeeks.com/en/arduino-embedded-c/adc-read

> Resolution and reference voltage.

## Turning a voltage into a number

An **analog-to-digital converter (ADC)** measures a voltage relative to a **reference voltage** and returns an integer. On the Arduino Uno R3 (ATmega328P at 5 V), `analogRead(A0)` returns 0 to 1023 (**10-bit** resolution), with the default reference being the 5 V supply, so one step is about 4.9 mV. Other boards differ: many ESP32 boards have 12-bit ADCs (0 to 4095) referenced near 3.3 V, with known non-linearity near the ends of the range; some newer boards let you change resolution with `analogReadResolution()`. Never apply a voltage above the board's supply or reference limits to an analog pin; check your board's datasheet/pinout.

## Between HIGH and LOW

The ADC turns voltages into numbers; PWM fakes analog output by switching fast.

![Three ideas: the ADC, PWM output, reading real sensors.](assets/figures/arduino-embedded-c/section-3-map.svg) — Figure 3.1 — Sensor voltage to ADC value to PWM output.

## Read a potentiometer and convert to volts

Uno R3: potentiometer ends to 5 V and GND, wiper to A0.

```cpp
const float VREF = 5.0;      // Uno R3 default reference; check your board
const int ADC_MAX = 1023;     // 10-bit ADC on the ATmega328P

void setup() {
  Serial.begin(9600);
}

void loop() {
  int raw = analogRead(A0);
  float volts = raw * VREF / ADC_MAX;
  Serial.print(raw);
  Serial.print(" -> ");
  Serial.print(volts, 3);
  Serial.println(" V");
  delay(200);   // fine for a simple demo
}
```

## Average noisy readings

Analog readings jitter by a count or two. Averaging several samples, or a simple exponential moving average, gives steadier values at the cost of slower response.

**Quiz:** What range does analogRead return on an Arduino Uno R3 by default?

- [x] 0 to 1023
- [ ] 0 to 255
- [ ] 0 to 4095
- [ ] -512 to 511

*Answer:* 0 to 1023. The ATmega328P ADC has 10-bit resolution.
