Understanding Analog Inputs and Simulated Analog Outputs with PWM in Arduino
Understanding Analog Inputs and Simulated Analog Outputs with PWM in Arduino
🧭 Overview:
This week focuses on the fundamentals of analog electronics in the context of Arduino: how
we read variable environmental inputs (like light or knob position), and how we simulate
variable outputs like brightness or sound intensity using Pulse Width Modulation (PWM).
These concepts are central to creating responsive systems that can smoothly interact with the real
world.
From reading how much light is shining through a window to gradually dimming an LED,
mastering analog inputs and PWM gives your Arduino the ability to go beyond simple ON/OFF
logic. By the end of this week, students will be capable of designing interactive devices that
adjust behavior based on nuanced sensor inputs.
The Arduino is great at digital logic (HIGH or LOW, 1 or 0), but many real-world variables—
light, sound, temperature, pressure—change continuously, not in just two states.
A digital signal is binary: it’s either HIGH (5V) or LOW (0V). Example: a push button.
An analog signal is variable, with values that can change in a continuous range.
Example: brightness from a lamp or twist of a knob.
6 analog input pins (A0–A5) that read voltages between 0 and 5V and convert them into a
digital number (0 to 1023) using a process called analog-to-digital conversion (ADC).
Digital output pins that can simulate analog-like behavior through PWM (discussed
below).
0 corresponds to 0V
1023 corresponds to 5V (assuming default reference voltage)
Syntax:
cpp
CopyEdit
int sensorValue = analogRead(A0);
Potentiometer: A variable resistor that acts as a voltage divider. Turning the knob
changes the resistance and thus the voltage at the output pin. Great for user-adjustable
controls.
LDR (Light Dependent Resistor): Changes its resistance based on ambient light. Bright
light → low resistance → higher voltage; darkness → high resistance → lower voltage.
plaintext
CopyEdit
+5V ---[LDR]---[Resistor]--- GND
|
A0
Pulse Width Modulation (PWM) is a clever technique used to simulate analog output on
digital pins. Since Arduino cannot output true analog voltage (like 2.3V or 3.7V), it uses PWM
to vary the average voltage by rapidly switching a pin ON and OFF.
The duty cycle (percentage of time the signal is HIGH in each cycle) determines the
average voltage.
o 100% duty cycle → always ON → full brightness
o 50% duty cycle → ON half the time → medium brightness
o 0% duty cycle → always OFF → no brightness
Arduino PWM pins are marked with a ~ (e.g., pins 3, 5, 6, 9, 10, 11 on Uno).
value ranges from 0 (0% duty cycle) to 255 (100% duty cycle)
The frequency is fixed (typically 490 Hz or 980 Hz depending on the pin)
Example:
cpp
CopyEdit
analogWrite(9, 128); // Send ~50% duty cycle to pin 9
Use cases:
Dimming LEDs
Controlling motor speed
Generating tones on buzzers
Adjusting brightness or sound intensity gradually
Hands-On Activities:
Steps:
cpp
CopyEdit
int pot = analogRead(A0);
int brightness = map(pot, 0, 1023, 0, 255);
analogWrite(9, brightness);
Observe how the LED brightness varies smoothly as the potentiometer is turned.
Objective: Use an LDR to detect ambient light and provide real-time feedback via Serial
Monitor.
Steps:
cpp
CopyEdit
int lightLevel = analogRead(A1);
Serial.println(lightLevel);
Objective: Create a loop that gradually increases and decreases an LED's brightness using
analogWrite().
Sample code:
cpp
CopyEdit
for (int i = 0; i <= 255; i++) {
analogWrite(9, i);
delay(10);
}
for (int i = 255; i >= 0; i--) {
analogWrite(9, i);
delay(10);
}
Use analogWrite() to drive a passive buzzer. Lower duty cycles will result in softer tones. This
introduces the idea that PWM isn't just for light—it's also useful in sound modulation.
Bonus: Use the tone() function to play melodies using mapped analog input values.
🎯 Learning Goals:
📝 Homework / Practice:
Objective: Use an LDR to detect darkness and gradually increase LED brightness using PWM.
Requirements:
Code Hint:
cpp
CopyEdit
int light = analogRead(A0);
int brightness = map(light, 1023, 0, 0, 255); // Inverse relationship
analogWrite(9, brightness);
Bonus: Add a second LED that acts as a high-brightness warning (e.g., flashes in pitch black).
Prompt: "Explain in your own words the difference between analog and digital pins in
Arduino. Give an example of when you'd use each type in a real-world project."
Suggestions: