🔌

Arduino Intermediate

Go beyond on/off. Use PWM to dim LEDs, read a potentiometer with analogRead, scale values with map(), build a button toggle, and play tones on a buzzer — all on the simulated Uno R3.

6 lessons 8 tasks
Lessons Arduino Lab Quiz Certificate

📚 Lessons

1 PWM — faking analog with fast switching

PWM (Pulse-Width Modulation) is how a digital pin pretends to be analog. The pin switches HIGH and LOW very fast — the fraction of time it stays HIGH is the duty cycle. A 50 % duty cycle makes an LED glow at half brightness; 100 % is fully on.

On the Uno R3, only the pins marked ~ can do PWM: 3, 5, 6, 9, 10, 11. The call analogWrite(pin, value) sets the duty cycle — value runs from 0 (always LOW) to 255 (always HIGH). You do not need to call pinMode first, though it doesn't hurt.

Path for this lesson: pin 9 → 220 Ω → LED anode → LED cathode → GND. Pin 9 is a PWM pin (~9), so we can dim the LED with analogWrite(9, 128) for roughly half brightness.

void setup() {
  pinMode(9, OUTPUT);          // pin 9 is a PWM (~) pin
}

void loop() {
  analogWrite(9, 0);           // off
  delay(500);
  analogWrite(9, 64);          // ~25 % brightness
  delay(500);
  analogWrite(9, 128);         // ~50 % brightness
  delay(500);
  analogWrite(9, 255);         // fully on
  delay(500);
}

2 Fading an LED with a for-loop

Instead of jumping between fixed levels, we can smoothly sweep the duty cycle with a for loop. Counting up from 0 to 255 fades the LED in; counting down fades it out.

Each step calls analogWrite(9, brightness) then waits a few milliseconds so the eye sees a smooth ramp. The total fade-in time is 256 × delayMs.

Keep the same circuit: pin 9 → 220 Ω resistor (current limiter) → LED anode (+) → LED cathode (–) → GND. The resistor is essential — without it the LED would draw too much current when the duty cycle is high.

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

void loop() {
  // fade in
  for (int b = 0; b <= 255; b++) {
    analogWrite(9, b);
    delay(8);
  }
  // fade out
  for (int b = 255; b >= 0; b--) {
    analogWrite(9, b);
    delay(8);
  }
}

3 Reading a potentiometer with analogRead

A potentiometer (pot) is a variable voltage divider. It has three terminals:

  • Left leg (a) → connect to 5V (the reference high voltage).
  • Right leg (b) → connect to GND (the reference low voltage).
  • Wiper (w) — the middle terminal — outputs a voltage between 0 V and 5 V depending on the knob position. Connect this to A0.

analogRead(A0) converts that voltage to an integer from 0 (0 V) to 1023 (5 V) using the Uno's 10-bit ADC. Turn the knob fully left → 0; fully right → 1023.

We print the value to the Serial Monitor with Serial.println(val) so you can see it change.

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

void loop() {
  int val = analogRead(A0);   // 0 – 1023
  Serial.println(val);
  delay(100);
}

4 map() and constrain() — scaling sensor values

Raw analogRead values (0–1023) rarely match what you need directly. map() re-scales a number from one range to another using linear interpolation:

map(value, fromLow, fromHigh, toLow, toHigh)

To convert a pot reading to a PWM duty cycle:
int brightness = map(analogRead(A0), 0, 1023, 0, 255);

This means: when the pot is at 0 → brightness is 0 (LED off); at 1023 → brightness is 255 (LED fully on). Any mid-point scales proportionally.

constrain(x, lo, hi) clamps a value so it never goes outside a range — useful as a safety net after map().

Circuit: pot wiper (w) → A0; pot left leg (a) → 5V; pot right leg (b) → GND. LED anode (+) through 220 Ω → pin 9; LED cathode (–) → GND.

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

void loop() {
  int raw = analogRead(A0);                     // 0 – 1023
  int brightness = map(raw, 0, 1023, 0, 255);  // scale to PWM range
  brightness = constrain(brightness, 0, 255);  // safety clamp
  analogWrite(9, brightness);
  delay(10);
}

5 Button toggle — state variables

Holding a button is easy, but toggling something on and off with each press requires a state variable. We remember whether the LED is currently on or off, and flip it every time the button is newly pressed.

The trick is edge detection: we track the previous button state and only act when the button transitions from not-pressed to pressed. This prevents the LED from flickering while the button is held.

Wiring: button lead apin 2; button lead bGND. We use INPUT_PULLUP so no external resistor is needed — the pin idles HIGH and reads LOW when pressed. LED anode (+) through 220 Ω → pin 9; LED cathode (–) → GND.

bool ledState = false;
bool lastBtn  = HIGH;

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

void loop() {
  bool btn = digitalRead(2);          // LOW when pressed
  if (btn == LOW && lastBtn == HIGH) {
    ledState = !ledState;              // flip the state
    digitalWrite(9, ledState ? HIGH : LOW);
  }
  lastBtn = btn;
  delay(20);                          // simple debounce
}

6 tone() — playing notes on a buzzer

A passive buzzer contains a membrane that vibrates when driven with an alternating signal. tone(pin, frequency) generates a square wave on the pin at the given frequency (in Hz), making the buzzer produce a note. noTone(pin) stops it.

Middle A is 440 Hz; Middle C is roughly 262 Hz. You can play simple melodies by calling tone() for different durations.

Wiring: buzzer anode (+, longer leg) → pin 11; buzzer cathode (–, shorter leg) → GND. Pin 11 is a PWM pin and works with tone(). No resistor is required for a buzzer.

void setup() {
  // nothing needed
}

void loop() {
  tone(11, 262);   // C4 (~262 Hz)
  delay(400);
  tone(11, 330);   // E4 (~330 Hz)
  delay(400);
  tone(11, 392);   // G4 (~392 Hz)
  delay(400);
  noTone(11);
  delay(600);
}

🔌 Arduino Lab — simulated Uno R3

Build the circuit (connect each lead to the correct port), then write a sketch, press Upload & Run, and watch the simulated board react — LEDs glow, motors spin, the serial monitor prints. Pass every challenge to earn your certificate.

Three challenges using PWM and analog I/O. The LED anode goes through a 220 Ω resistor to pin 9 (a PWM pin); the cathode returns to GND. The potentiometer's wiper connects to A0, left leg to 5V, right leg to GND.

📝 Tasks

8 tasks across 3 pages — multiple-choice and fill-in (type the answer). Score 70% or higher to earn your certificate.

🎓 Certificate of Completion

🔒 Pass the quiz above (70%+) to unlock your downloadable certificate.