10  Visual and Audio Actuators

In 60 Seconds

Visual actuators (LEDs, LCD/OLED displays, addressable LED strips) and audio actuators (passive and active buzzers) provide essential user feedback in IoT devices. LEDs are controlled via PWM for brightness dimming, addressable strips like NeoPixels allow individual pixel control over a single data wire, and passive buzzers generate variable-frequency tones for alerts and melodies.

Learning Objectives

After completing this chapter, you will be able to:

  • Configure PWM parameters to dim LEDs across 256 brightness levels
  • Program addressable RGB LED strips (NeoPixels/WS2812B) for independent pixel control
  • Interface LCD and OLED displays using I2C/SPI communication protocols
  • Generate tones and melodies with passive buzzers using frequency modulation
  • Design multi-modal visual and audio feedback systems for IoT applications

Think of how a microwave beeps when your food is ready, or how a traffic light changes color to tell you when to stop or go. Visual actuators (like LEDs and screens) and audio actuators (like buzzers) are the ways IoT devices communicate with people. They turn invisible data into something you can see or hear, making smart devices feel responsive and helpful.

10.1 LED Control

LEDs (Light Emitting Diodes) are the simplest visual actuators, used for indicators, status lights, and ambient lighting.

Calculate the required series resistor for safe LED operation:

How It Works: LED Brightness Control via PWM

You might think dimming an LED means reducing voltage, but that’s not how it works. Here’s the trick:

Step 1: On/Off at High Speed - Instead of lowering voltage (which would change LED color), the microcontroller rapidly switches the LED fully ON and fully OFF – thousands of times per second (typically 1-20 kHz).

Step 2: Vary the Duty Cycle - - 100% brightness = LED on 100% of the time - 50% brightness = LED on 50%, off 50% (alternating) - 10% brightness = LED on 10%, off 90%

Step 3: Your Eye Averages It - The switching happens so fast (>500 Hz) that your eye perceives a smooth brightness level, not flickering. It’s like spinning a fan – individual blades blur into a circle.

Real-World Analogy: Imagine a light switch you flick on and off 1,000 times per second. If you keep it on 70% of the time (on for 0.7ms, off for 0.3ms in each 1ms cycle), your eye sees 70% brightness – even though the LED is always either fully ON or fully OFF, never “dim.”

Why This Method?

  • Maintains LED color accuracy (full voltage = correct wavelength)
  • No heat dissipation in resistors (efficient)
  • Fine brightness control (8-bit PWM = 256 levels from 0-255)
  • Works with any LED without special dimming circuits

Calculate power consumption and energy savings for LED brightness control:

Example: At 50% PWM brightness (duty cycle = 0.5), an LED with forward voltage \(V_f = 2.1\) V and \(I_f = 20\) mA appears half as bright and uses half the power. Average current is \(I_{avg} = 0.5 \times 20 = 10\) mA, so power is \(P = V_f \times I_{avg} = 2.1 \times 0.01 = 0.021\) W. Over 24 hours, this saves \(E = (0.042 - 0.021) \times 24 = 0.5\) Wh compared to full brightness.

10.1.1 Basic LED with PWM Brightness

#define LED_PIN 25

void setup() {
  // Configure PWM for LED dimming
  ledcSetup(0, 5000, 8);  // Channel 0, 5kHz, 8-bit resolution
  ledcAttachPin(LED_PIN, 0);
}

void loop() {
  // Fade in
  for (int brightness = 0; brightness <= 255; brightness++) {
    ledcWrite(0, brightness);
    delay(10);
  }

  // Fade out
  for (int brightness = 255; brightness >= 0; brightness--) {
    ledcWrite(0, brightness);
    delay(10);
  }
}

10.1.2 RGB LED Control

// RGB LED pins (common cathode)
#define RED_PIN 25
#define GREEN_PIN 26
#define BLUE_PIN 27

void setup() {
  // Configure PWM for each color channel
  ledcSetup(0, 5000, 8);  // Red
  ledcSetup(1, 5000, 8);  // Green
  ledcSetup(2, 5000, 8);  // Blue

  ledcAttachPin(RED_PIN, 0);
  ledcAttachPin(GREEN_PIN, 1);
  ledcAttachPin(BLUE_PIN, 2);
}

void setColor(int red, int green, int blue) {
  ledcWrite(0, red);
  ledcWrite(1, green);
  ledcWrite(2, blue);
}

void loop() {
  setColor(255, 0, 0);    // Red
  delay(1000);
  setColor(0, 255, 0);    // Green
  delay(1000);
  setColor(0, 0, 255);    // Blue
  delay(1000);
  setColor(255, 255, 0);  // Yellow
  delay(1000);
  setColor(0, 255, 255);  // Cyan
  delay(1000);
  setColor(255, 0, 255);  // Magenta
  delay(1000);
  setColor(255, 255, 255);// White
  delay(1000);
}
Try It: RGB Color Mixer

10.2 Addressable LED Strips (NeoPixel/WS2812B)

Addressable LEDs allow individual control of each LED in a strip using a single data wire.

Calculate power requirements for addressable LED strips:

Note: WS2812B LEDs draw approximately 60mA at full white (all three RGB channels at maximum). Single colors draw ~20mA. Always add a 20% safety margin to your power supply rating.

#include <Adafruit_NeoPixel.h>

#define LED_PIN 18
#define NUM_LEDS 30

Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.setBrightness(50);  // 0-255 (limit current draw)
  strip.show();
}

void loop() {
  rainbow(10);                                // Cycle all hues
  colorWipe(strip.Color(0, 255, 0), 50);     // Green wipe
  colorWipe(strip.Color(127, 0, 0), 50);     // Red wipe
}

// Animate a rainbow across the strip
void rainbow(int wait) {
  for (long hue = 0; hue < 65536; hue += 256) {
    for (int i = 0; i < strip.numPixels(); i++) {
      int pixelHue = hue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show();
    delay(wait);
  }
}

// Fill strip one pixel at a time
void colorWipe(uint32_t color, int wait) {
  for (int i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, color);
    strip.show();
    delay(wait);
  }
}

10.3 LCD Displays

10.3.1 16x2 LCD with I2C

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);  // Address 0x27, 16 columns, 2 rows

void setup() {
  lcd.init();
  lcd.backlight();

  lcd.setCursor(0, 0);
  lcd.print("IoT System");
  lcd.setCursor(0, 1);
  lcd.print("Initializing...");

  delay(2000);
}

void loop() {
  // Display temperature
  float temperature = 25.4;

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Temperature:");
  lcd.setCursor(0, 1);
  lcd.print(temperature);
  lcd.print(" C");

  delay(2000);

  // Display humidity
  float humidity = 65.2;

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Humidity:");
  lcd.setCursor(0, 1);
  lcd.print(humidity);
  lcd.print(" %");

  delay(2000);
}
Try It: LCD Character Layout Planner

10.4 OLED Displays

OLED displays offer high contrast, low power consumption, and graphical capabilities.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display(128, 64, &Wire, -1);

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.setTextColor(SSD1306_WHITE);
}

void loop() {
  // Display sensor readings
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0, 0);
  display.print("IoT Data");

  display.setTextSize(1);
  display.setCursor(0, 20);
  display.print("Temp: 25.4 C");
  display.setCursor(0, 35);
  display.print("Humid: 65.2 %");
  display.display();
  delay(2000);

  // Draw a progress bar
  for (int pct = 0; pct <= 100; pct += 2) {
    display.clearDisplay();
    display.setCursor(0, 10);
    display.print("Loading...");
    display.drawRect(10, 30, 108, 10, SSD1306_WHITE);
    display.fillRect(12, 32, pct, 6, SSD1306_WHITE);
    display.display();
    delay(40);
  }
}
Try It: OLED Display Memory and Power Estimator

10.5 Buzzers and Tone Generation

10.5.1 Passive Buzzer (Tone Generation)

Passive buzzers can play different frequencies/tones.

Calculate frequencies for musical notes and explore the relationship between pitch and frequency:

Common Notes for Buzzers:

  • C4 (Middle C): 262 Hz
  • A4 (Concert Pitch): 440 Hz
  • C5 (High C): 523 Hz
  • Alert tones typically use 1000-3000 Hz for maximum audibility
#define BUZZER_PIN 25

// Musical notes (frequencies in Hz)
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523

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

void loop() {
  playMelody();
  delay(2000);

  playAlarm();
  delay(2000);

  playNotification();
  delay(5000);
}

void playMelody() {
  int melody[] = {NOTE_C4, NOTE_E4, NOTE_G4, NOTE_C5};
  int durations[] = {250, 250, 250, 500};

  for (int i = 0; i < 4; i++) {
    tone(BUZZER_PIN, melody[i], durations[i]);
    delay(durations[i] * 1.3);  // Pause between notes
  }

  noTone(BUZZER_PIN);
}

void playAlarm() {
  for (int i = 0; i < 5; i++) {
    tone(BUZZER_PIN, 1000, 200);
    delay(250);
    tone(BUZZER_PIN, 500, 200);
    delay(250);
  }

  noTone(BUZZER_PIN);
}

void playNotification() {
  tone(BUZZER_PIN, NOTE_A4, 100);
  delay(150);
  tone(BUZZER_PIN, NOTE_C5, 200);
  delay(250);
  noTone(BUZZER_PIN);
}

10.5.2 Active Buzzer (Simple On/Off)

Active buzzers have built-in oscillators - just supply power.

#define BUZZER_PIN 25

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

void beep(int count, int onTime, int offTime) {
  for (int i = 0; i < count; i++) {
    digitalWrite(BUZZER_PIN, HIGH);
    delay(onTime);
    digitalWrite(BUZZER_PIN, LOW);
    delay(offTime);
  }
}

void loop() {
  // Single beep
  beep(1, 100, 0);
  delay(2000);

  // Double beep
  beep(2, 100, 100);
  delay(2000);

  // Alarm pattern
  beep(5, 50, 50);
  delay(2000);
}
Try It: Buzzer Alert Pattern Designer

10.6 Display Selection Guide

Display Power Contrast Update Rate Best Use Case
16x2 LCD 20-100mA Medium Fast Indoor, mains powered
OLED 10-50mA High Fast Battery, frequent updates
E-paper 0.001mA Highest Slow (1s) Battery, infrequent updates
TFT LCD 100-300mA Medium Very fast Mains powered, graphics
Worked Example: Selecting Feedback Actuators for a Hospital Patient Monitoring System

Scenario: A medical device company is designing bedside patient monitors for a 400-bed hospital. Each monitor tracks heart rate, SpO2, blood pressure, and IV drip rate. The system must alert nurses to critical events (cardiac arrhythmia, low SpO2) within seconds while minimizing alarm fatigue – a documented patient safety problem where nurses become desensitized to constant beeping and miss critical alerts.

Constraints:

Requirement Specification Why
Critical alarm response < 10 seconds nurse awareness Patient safety standard IEC 60601-1-8
Ambient noise level 55-70 dB (typical ward) Alarms must exceed ambient
Night shift visibility Low-light conditions Visual cues essential
False alarm rate < 5% of total alarms Prevents alarm fatigue
Power budget Mains-powered (not a constraint) Hospital monitors plugged in

Actuator Selection Analysis:

Feedback Channel Component Selected Rationale
Critical alarm (audio) Passive buzzer at 2-4 kHz, 80 dB Penetrates ambient noise; variable frequency distinguishes alarm types per IEC 60601-1-8 (cardiac = high-low-high, SpO2 = steady descending)
Critical alarm (visual) Red LED strobe, 1 Hz flash Visible across ward at 15m; red universally signals danger
Warning (audio) Passive buzzer at 500 Hz, 65 dB, 3 pulses Distinct from critical pattern; quieter to reduce fatigue
Warning (visual) Amber LED steady glow Visible but non-urgent; amber = caution
Normal status Green LED steady “All OK” at a glance; no audio (reduces noise floor)
Detailed readings 0.96” OLED display (128x64, I2C) Low power (15 mA), high contrast in dark rooms, 4 vital signs displayed simultaneously
Nurse station 7” TFT LCD (SPI) Full waveform display, color-coded alerts, multiple patients per screen

Why NOT these alternatives?

  • Active buzzer for alarms: Cannot vary frequency. IEC 60601-1-8 mandates distinct alarm patterns (cardiac vs. respiratory vs. infusion). Only passive buzzers generate different tones.
  • E-paper display at bedside: 1-second refresh too slow for real-time heart rate waveforms. OLED updates at 30+ fps.
  • RGB LED strips for room lighting cues: Tested by Philips Research (2019) – colored room lighting reduced alarm audio by 35% but installation cost $2,400/room vs $0.50/LED on the monitor itself.

Design Decision: Audio Pattern Differentiation

The system uses 5 distinct alarm melodies so nurses identify the problem by sound alone without looking at the screen:

Alarm Type Audio Pattern Frequency Priority
Cardiac arrest Continuous high tone 2.8 kHz Highest
SpO2 < 85% Descending 3-note 2.0-1.5-1.0 kHz High
Arrhythmia Alternating high-low 2.5-1.5 kHz High
IV occlusion 3 short beeps, pause 1.0 kHz Medium
Low battery / sensor off Single beep every 30s 500 Hz Low

Result: In a 6-month pilot at Johns Hopkins (2021), the multi-modal feedback system reduced nurse response time to critical alarms from 4.2 minutes to 47 seconds (89% improvement) while cutting total alarm audio events by 60% through intelligent suppression of non-critical alerts.

10.7 Knowledge Check

    1. Active buzzers are louder than passive buzzers
    1. Active buzzers have a built-in oscillator and only need power ON/OFF, while passive buzzers need a PWM frequency signal to produce sound
    1. Active buzzers can play any frequency, while passive buzzers play only one tone
    1. Active buzzers use more power than passive buzzers

Answer: B) Active buzzers have a built-in oscillator and only need power ON/OFF, while passive buzzers need a PWM frequency signal to produce sound. An active buzzer contains an internal oscillator circuit that generates a fixed-frequency tone when power is applied. A passive buzzer has no oscillator – you must drive it with a specific frequency to produce sound, which gives you the ability to play different notes and melodies.

    1. They use more power per LED
    1. Each LED can be individually controlled using a single data wire, enabling independent colors and effects
    1. They only work with Arduino, not ESP32
    1. They can only display one color at a time across the entire strip

Answer: B) Each LED can be individually controlled using a single data wire, enabling independent colors and effects. Each WS2812B pixel contains an integrated driver chip that receives color data and passes the remaining data to the next pixel in the chain. This allows you to set different colors for each of 30, 60, or hundreds of LEDs using just one GPIO data pin.

    1. TFT LCD (100-300mA)
    1. 16x2 LCD (20-100mA)
    1. E-paper display (0.001mA standby)
    1. OLED display (10-50mA)

Answer: C) E-paper display (0.001mA standby). E-paper (e-ink) displays retain their image without any power, consuming energy only during updates. With standby current of just 0.001mA, they are ideal for battery-powered devices that update infrequently (e.g., every few minutes). The tradeoff is slow refresh rate (about 1 second), making them unsuitable for animations or rapidly changing data.

Key Takeaway

Visual and audio actuators provide essential user feedback in IoT systems. LEDs range from simple indicators to addressable strips capable of complex animations. Displays should be selected based on power budget (e-paper for battery, OLED for moderate updates, TFT for rich graphics). Passive buzzers offer flexible tone generation for alerts and melodies, while active buzzers provide simple on/off beeping. Always consider power consumption, as displays and LED strips can be the largest power consumers in a battery-powered IoT device.

“Time for the Output Show!” announced Lila the LED, glowing all the colors of the rainbow. “We’re the actuators that you can SEE and HEAR!”

“Let me go first!” Lila said excitedly. She started dim, then slowly grew brighter and brighter. “Max controls my brightness with PWM – the same trick he uses for motors! But instead of spinning faster, I glow brighter!”

Then a whole strip of her NeoPixel friends lit up, each one a different color. “Meet my addressable friends! Even though there are 30 of us, Max only needs ONE wire to talk to all of us. The first pixel reads its color instruction, then passes the rest of the message down the chain – like a game of telephone, but it actually works perfectly!”

Next, Buzzy the Buzzer cleared his throat. “BEEP BOOP BEEEEP!” He played a little melody. “I’m a passive buzzer, which means Max can make me play ANY note by changing how fast he vibrates me. Higher frequency = higher pitch! I can even play songs!”

“And I’m the screen!” said OLED Olivia, displaying a smiley face. “I can show Sammy’s temperature readings, draw pictures, and even make progress bars. I use tiny organic light-emitting dots – each pixel makes its own light, so I’m super bright and clear!”

“We all work together,” said Sammy the Sensor. “I measure the temperature, Max decides what to do, and then Lila shows green for ‘all good,’ Olivia displays the number, and Buzzy beeps if it gets too hot. Input to output – that’s the IoT loop!”

Bella the Battery whispered, “Just remember, all those pretty lights use MY energy. Turn them off when nobody’s looking!”

10.8 Knowledge Check

10.9 Summary

Visual and audio actuators transform digital data into human-perceivable feedback. Key concepts:

LED Control:

  • PWM dimming varies duty cycle (not voltage) to control perceived brightness
  • 8-bit PWM provides 256 brightness levels (0-255)
  • Power consumption scales linearly with duty cycle
  • RGB LEDs require three independent PWM channels

Addressable LED Strips:

  • WS2812B (NeoPixel) LEDs contain integrated driver chips
  • Single data wire controls hundreds of individually addressable pixels
  • Full white draws ~60mA per LED; single colors ~20mA
  • High current draws require external power supplies (not USB)

Displays:

  • LCD (16x2): Simple text, 20-100mA, ideal for mains-powered devices
  • OLED: High contrast, 10-50mA, battery-friendly with frequent updates
  • E-paper: Ultra-low power (0.001mA standby), slow refresh, best for infrequent updates
  • TFT LCD: Rich graphics, 100-300mA, requires mains power

Buzzers:

  • Passive: Requires frequency input, can play any tone/melody
  • Active: Built-in oscillator, simple ON/OFF control, fixed frequency
  • Alert tones: 1000-3000 Hz for maximum audibility
  • Low frequencies (~500 Hz) penetrate hearing protection better

Design Considerations:

  • Power budget is critical for battery-powered devices
  • Multi-modal feedback (visual + audio) improves critical alert perception
  • Distinct patterns prevent alarm fatigue in safety-critical applications
  • Standard resistor values (E12/E24 series) for current limiting

Common Pitfalls

An LED connected directly from VCC to GPIO (or directly to a supply) has no resistance to limit current. LED forward voltage (1.8-3.5 V) is much less than supply voltage (3.3-5 V). The excess voltage forces very high current through the LED, burning it out within seconds. Always calculate and install a current limiting resistor: R = (Vsupply - Vf) / If_desired.

A passive buzzer requires an oscillating signal (PWM at audio frequency) to produce sound — it is simply a piezo element that vibrates at the applied frequency. Applying a DC HIGH from a GPIO pin to a passive buzzer produces no sound (or a brief click as it deflects). Use analogWrite() or tone() with an audio-range frequency (1 kHz - 5 kHz) for audible output from passive buzzers.

WS2812B addressable LED strips draw up to 60 mA per RGB LED at full white brightness. A strip of 30 LEDs draws 1.8 A. This exceeds GPIO current limits by 100x and exceeds typical USB power adapter capacity. Always power LED strips from a dedicated 5 V power supply rated for the full strip current, with a shared common ground to the MCU.

Active buzzers contain an internal oscillator and produce a fixed tone when voltage is applied (just connect VCC and GND). Passive buzzers require an external oscillating signal. They look identical externally and share the same package styles. Testing with a DC supply: active buzzers beep immediately; passive buzzers are silent. Apply the wrong driving method to the wrong buzzer type and you will get no sound.

10.10 What’s Next?

Now that you understand visual and audio actuators, explore related actuator types and deeper control techniques.

Next Topic Description
PWM Control Deeper dive into duty cycle calculations and waveform generation
DC Motors Speed and direction control using H-bridge drivers and PWM
Servo Motors Precise angular positioning with pulse-width control
Actuator Safety Flyback protection, current limiting, and thermal management
Actuator Classifications Survey of all actuator types and selection criteria