Day 3 of 5
⏱ ~60 minutes
Arduino in 5 Days — Day 3

Analog Sensors

The physical world is analog. Today you'll read real sensor values — light, temperature, position — and convert them to meaningful data.

The ADC and analogRead

Arduino Uno has a 10-bit ADC on pins A0–A5. analogRead(A0) returns 0–1023 corresponding to 0–5V. Resolution: 5V/1024 ≈ 4.9mV per step. The ADC samples at about 10,000 readings/second on a 16MHz Arduino. Use map(value, fromLow, fromHigh, toLow, toHigh) to rescale readings. Example: map(reading, 0, 1023, 0, 100) converts to percentage.

Common Analog Sensors

Potentiometer: variable resistor (10kΩ). Wire: one end to 5V, other to GND, wiper to analog pin. Gives 0–1023 for full rotation — perfect for manual control. LDR (photoresistor): resistance decreases with light (1kΩ bright, 10kΩ dark). Use a voltage divider: LDR + 10kΩ resistor to GND, junction to analog pin. Thermistor (NTC): resistance decreases with temperature. Same voltage divider circuit. Use Steinhart-Hart equation or lookup table for accurate temperature.

Noise and Averaging

Analog readings are noisy — a steady voltage reads slightly different values each sample. Fix: take N samples and average them. A rolling average (keep last N in a circular buffer) responds faster than a batch average. Also add decoupling capacitors (100nF) near the sensor power pins to reduce power-supply noise. For the thermistor, multiple samples in rapid succession give a stable temperature reading.

cpp
// Analog sensors: pot, LDR, thermistor
#include <math.h>

const int POT_PIN  = A0;
const int LDR_PIN  = A1;
const int THERM_PIN = A2;

// Thermistor constants (NTC 10k, B=3950)
const float R_NOMINAL  = 10000.0;  // 10kΩ at 25°C
const float T_NOMINAL  = 25.0;     // °C
const float B_COEFF    = 3950.0;
const float R_SERIES   = 10000.0;  // series resistor

float readThermistor() {
  // Average 10 samples for stability
  float sum = 0;
  for (int i = 0; i < 10; i++) {
    sum += analogRead(THERM_PIN);
    delay(1);
  }
  float adc = sum / 10.0;

  // Convert ADC to resistance
  float R = R_SERIES * (1023.0 / adc - 1.0);

  // Steinhart-Hart simplified: B parameter equation
  float steinhart = R / R_NOMINAL;
  steinhart = log(steinhart);
  steinhart /= B_COEFF;
  steinhart += 1.0 / (T_NOMINAL + 273.15);
  steinhart = 1.0 / steinhart;
  return steinhart - 273.15;  // Kelvin to Celsius
}

void setup() {
  Serial.begin(9600);
  Serial.println("Sensor readings:");
}

void loop() {
  int pot  = analogRead(POT_PIN);
  int ldr  = analogRead(LDR_PIN);
  float temp = readThermistor();

  int pot_pct   = map(pot, 0, 1023, 0, 100);
  int light_pct = map(ldr, 0, 1023, 100, 0); // invert: low ADC = bright

  Serial.print("Pot:");   Serial.print(pot_pct);   Serial.print("%  ");
  Serial.print("Light:"); Serial.print(light_pct); Serial.print("%  ");
  Serial.print("Temp:");  Serial.print(temp, 1);   Serial.println("°C");

  delay(500);
}
💡
Always average multiple ADC samples for sensors that need accuracy. For a thermistor, 10 samples with 1ms delay between them reduces noise significantly. For faster feedback (like a pot controlling audio), 2–4 samples is usually enough.
📝 Day 3 Exercise
Build an Analog Dashboard
  1. Wire all three sensors. Upload the sketch. Verify readings in Serial Monitor.
  2. Warm the thermistor with your fingers — does the temperature reading change within 5 seconds?
  3. Cover the LDR — does light percentage drop to near 0?
  4. Use analogWrite(LED_PIN, map(ldr, 0, 1023, 0, 255)) to make an LED brightness follow ambient light automatically.
  5. Add smoothing: implement a 5-element rolling average for the potentiometer reading. Compare noisy vs smoothed output in Serial Plotter (Tools → Serial Plotter).

Day 3 Summary

  • analogRead() returns 0–1023 for 0–5V (10-bit ADC on Arduino Uno)
  • Use map() to rescale: map(val, 0, 1023, 0, 100) converts to percentage
  • LDR and thermistor both need a voltage divider circuit — fixed resistor in series
  • Average multiple samples to reduce ADC noise; rolling average balances noise vs responsiveness
Challenge

Build a simple thermostat. If temperature exceeds a threshold (set by the potentiometer, mapped to 20–40°C), turn on a red LED and a buzzer. Below threshold: green LED, no buzzer. Add hysteresis: don't turn off until temperature drops 2°C below the threshold. This prevents rapid on/off cycling near the setpoint.

Finished this lesson?