OC
OceanRemote
Low-code IoT platform
← Back to Course

PWM - Analog Output for Dimming and Speed Control

🎛️ PWM - Analog Output for LED Dimming and Motor Speed

PWM (Pulse Width Modulation) creates analog-like output by rapidly turning pins on and off. Perfect for dimming lights, controlling pump speed, or adjusting fan speed.

📊 How PWM Works:

  • 0% duty cycle: Always OFF (0V average)
  • 50% duty cycle: ON half the time (1.65V average)
  • 100% duty cycle: Always ON (3.3V average)
  • Frequency: 5000Hz is good for LEDs, 100-1000Hz for motors

🔧 ESP32 LEDC (LED Controller) - 16 channels!

#include   // Alternative library

// Method 1: Using built-in LEDC
const int ledPin = 4;
const int freq = 5000;
const int resolution = 8;  // 8-bit = 0-255

void setup() {
    ledcSetup(0, freq, resolution);
    ledcAttachPin(ledPin, 0);
}

void loop() {
    // Fade LED smoothly up and down
    for (int duty = 0; duty <= 255; duty++) {
        ledcWrite(0, duty);
        delay(5);
    }
    delay(1000);
    for (int duty = 255; duty >= 0; duty--) {
        ledcWrite(0, duty);
        delay(5);
    }
}
    

💧 Agricultural Applications:

  • Variable Speed Water Pump: Slow flow for seedlings, faster for mature plants
  • Greenhouse Light Control: Simulate sunrise/sunset for better plant growth
  • Fan Speed Control: Adjust ventilation based on temperature
  • Dosing Pumps: Precise control for fertilizer injection

🚀 Complete Example: PWM Water Pump Control

// Control pump speed based on soil moisture
// Wire: PWM pin (GPIO4) → motor driver → pump

#define PWM_PIN 4
#define SOIL_DRY 20    // Moisture % to trigger pump
#define SOIL_WET 60    // Moisture % to stop pump

void setup() {
    ledcSetup(0, 1000, 8);  // 1kHz for motor
    ledcAttachPin(PWM_PIN, 0);
    ledcWrite(0, 0);  // Start pump OFF
}

void loop() {
    int moisture = readSoilMoisture();  // Your sensor function
    
    if (moisture < SOIL_DRY) {
        // Very dry - full speed
        ledcWrite(0, 255);
        Serial.println("Pump: FULL SPEED");
    } 
    else if (moisture < SOIL_WET) {
        // Moderately dry - half speed
        int speed = map(moisture, SOIL_DRY, SOIL_WET, 255, 50);
        ledcWrite(0, speed);
        Serial.print("Pump speed: ");
        Serial.println(speed);
    } 
    else {
        // Wet enough - pump off
        ledcWrite(0, 0);
        Serial.println("Pump: OFF");
    }
    delay(60000);  // Update every minute
}
    
💡 Pro Tip: For water pumps, use a MOSFET or motor driver, not a direct relay. PWM can damage standard relays. A simple IRLZ44N MOSFET costs $2 and works perfectly!
💡 Key Takeaways:
  • Apply these concepts directly to your farm or project.
  • Take notes on important details for the quiz.
  • Use the button below to track your progress.