Analog Inputs & PWM on Arduino

Analog Inputs & PWM on Arduino

Read sensors with analogRead and control brightness with analogWrite.

Analog vs Digital

Digital signals are either fully ON or fully OFF. Analog signals vary continuously ߀” like the position of a potentiometer, the light level hitting a photoresistor, or a temperature sensor's voltage output.

The Arduino Uno has a 10-bit ADC (Analog-to-Digital Converter) on pins A0߀“A5. It converts voltages between 0 V and 5 V into numbers from 0 to 1023.

Reading an Analog Pin ߀” analogRead()

int value = analogRead(A0);  // Returns 0߀“1023

No pinMode() call is needed for analog inputs ߀” they are always configured as inputs.

Converting to Voltage

int raw = analogRead(A0);
float voltage = raw * (5.0 / 1023.0);

Reading a Potentiometer

A potentiometer (pot) is a variable resistor. Wire its outer legs to 5 V and GND, and the middle wiper to A0.

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

void loop() {
  int pot = analogRead(A0);
  Serial.println(pot);   // Print raw value (0߀“1023)
  delay(100);
}

Open Tools ߆’ Serial Monitor to see the values change as you turn the knob.

PWM ߀” Simulating Analog Output

The Arduino Uno cannot output a true analog voltage, but it can simulate one using PWM (Pulse Width Modulation). PWM rapidly switches a pin on and off; the ratio of on-time to off-time is the duty cycle.

Only pins marked with ~ support PWM on the Uno: 3, 5, 6, 9, 10, 11.

Writing PWM ߀” analogWrite()

analogWrite(pin, value);  // value: 0 (always off) to 255 (always on)
analogWrite(9, 0);    // LED fully off
analogWrite(9, 128);  // LED at ~50% brightness
analogWrite(9, 255);  // LED fully on

LED Dimmer with a Potentiometer

Map the 0߀“1023 pot reading to the 0߀“255 PWM range using map():

void setup() {
  pinMode(9, OUTPUT);
}

void loop() {
  int pot = analogRead(A0);
  int brightness = map(pot, 0, 1023, 0, 255);
  analogWrite(9, brightness);
}

map(value, fromLow, fromHigh, toLow, toHigh) rescales a number from one range to another.

The map() Function

long map(long x, long in_min, long in_max, long out_min, long out_max);

Examples:

map(512, 0, 1023, 0, 255)   // ߆’ 127
map(0,   0, 1023, 0, 255)   // ߆’ 0
map(1023,0, 1023, 0, 255)   // ߆’ 255

Common Sensors

Sensor Reads Typical range
Potentiometer Rotation 0߀“1023
LDR (photoresistor) Light level 0߀“1023
TMP36 Temperature Voltage ߉? 0.5 V at 0 ?°C
Soil moisture Moisture 0߀“1023

Reading Temperature with TMP36

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

void loop() {
  int raw = analogRead(A0);
  float voltage = raw * (5.0 / 1023.0);
  float tempC = (voltage - 0.5) * 100.0;   // TMP36 formula
  Serial.print("Temp: ");
  Serial.print(tempC);
  Serial.println(" C");
  delay(1000);
}