Introduction: ESP32 PWM LED Brightness Control With IoT, OLED Display, and Fade Effect

Objective

Control an LED's brightness using a potentiometer, display the brightness level on an OLED display, and control it remotely via a web interface with smooth fading effects.

System Overview

  1. LED Brightness Control: Adjust brightness using a potentiometer and display the brightness on an OLED.
  2. Smooth Fade: The LED brightness transitions smoothly as the potentiometer value changes.
  3. Remote Control: Control the brightness from a web page hosted by the ESP32.
  4. Serial Monitor Feedback: Logs brightness levels to the Serial Monitor for tracking and debugging.


Supplies

Required Components

  1. ESP32: Buy on Amazon
  2. LED: Buy on Amazon
  3. Resistor (220Ω or 330Ω for LED): Buy on Amazon
  4. Potentiometer (10KΩ): Buy on Amazon
  5. OLED Display (SSD1306): Buy on Amazon
  6. Jumper Wires: Buy on Amazon
  7. Breadboard: Buy on Amazon
Affiliate Link Disclaimer: The above links are affiliate links, and purchases made through them help support free tutorials.


Step 1:

Circuit Connection

  1. LED Connections:
  2. Positive Pin (longer leg) → Connect to GPIO16 via a 220Ω resistor.
  3. Negative Pin (shorter leg) → Connect to GND on ESP32.
  4. Potentiometer Connections:
  5. VCC Pin → Connect to 3.3V on ESP32.
  6. GND Pin → Connect to GND on ESP32.
  7. Output Pin (middle pin) → Connect to A0 on ESP32.
  8. OLED Display Connections:
  9. SDA → GPIO21 on ESP32.
  10. SCL → GPIO22 on ESP32.
  11. VCC → 3.3V on ESP32.
  12. GND → GND on ESP32.

Circuit Connection Analysis

  1. LED Brightness Control: Adjusts PWM duty cycle based on potentiometer reading.
  2. OLED Display: Displays the current brightness level as a percentage.
  3. ESP32 Web Server: Allows control of brightness through a simple web interface.
  4. Smooth Fade: Fades LED brightness smoothly as potentiometer changes.

Setting Up the ESP32

  1. Install ESP32 Board Support in Arduino IDE:
  2. Go to File > Preferences.
  3. Add the following URL in "Additional Boards Manager URLs":
https://dl.espressif.com/dl/package_esp32_index.json
  1. Go to Tools > Board > Boards Manager, search for "ESP32", and click Install.
  2. Required Libraries:
  3. Adafruit SSD1306 and Adafruit GFX for the OLED display.
  4. WiFi for ESP32’s WiFi capability.
  5. Install these libraries through Sketch > Include Library > Manage Libraries....

Building the Web Interface Code (HTML)

This web interface allows you to control the LED brightness via a slider.


<!DOCTYPE HTML>
<html>
<head>
<title>ESP32 LED Brightness Control</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html { font-family: Arial; display: inline-block; text-align: center; }
body { margin-top: 50px; }
h1 { font-size: 2em; color: #333; }
.slider { width: 300px; }
</style>
</head>
<body>
<h1>ESP32 LED Brightness Control</h1>
<p>Brightness: <span id="brightness">0</span>%</p>
<input type="range" min="0" max="100" value="0" class="slider" id="brightnessSlider" oninput="updateBrightness(this.value)">
<script>
function updateBrightness(value) {
document.getElementById("brightness").innerText = value;
fetch(`/setBrightness?value=${value}`);
}
</script>
</body>
</html>

Arduino Board and Library Configuration

  1. Select the ESP32 Board: Go to Tools > Board and select ESP32 Dev Module.
  2. Ensure Proper Libraries are Installed: Make sure the Adafruit SSD1306 and Adafruit GFX libraries are installed for the OLED display.

Arduino Code

The following code combines potentiometer-based brightness control with web-based control, OLED display, and a smooth fade effect.


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

const int ledPin = 16; // GPIO16 for LED
const int potPin = A0; // Analog pin for potentiometer
const int freq = 15000; // PWM frequency
const int ledChannel = 0; // PWM channel
const int resolution = 13; // PWM resolution (0-8191)
int targetBrightness = 0; // Target brightness from potentiometer
int currentBrightness = 0; // Current brightness for smooth fading

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

const char* ssid = "YourSSID";
const char* password = "YourPassword";

WiFiServer server(80);

void setup() {
Serial.begin(115200);

// Setup PWM
ledcSetup(ledChannel, freq, resolution);
ledcAttachPin(ledPin, ledChannel);

// Setup WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
server.begin();

// Setup OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
}

void loop() {
// Read potentiometer and map to 0-100%
targetBrightness = map(analogRead(potPin), 0, 4095, 0, 100);

// Smoothly fade brightness
if (currentBrightness < targetBrightness) {
currentBrightness++;
} else if (currentBrightness > targetBrightness) {
currentBrightness--;
}
int dutyCycle = map(currentBrightness, 0, 100, 0, 8191); // Map to 13-bit resolution
ledcWrite(ledChannel, dutyCycle);

// Display brightness on OLED
display.clearDisplay();
display.setCursor(0, 0);
display.print("Brightness: ");
display.print(currentBrightness);
display.println("%");
display.display();

// Web server to handle remote brightness adjustment
WiFiClient client = server.available();
if (client) {
String request = client.readStringUntil('\r');
client.flush();

if (request.indexOf("/setBrightness") != -1) {
int valueIndex = request.indexOf("value=");
if (valueIndex != -1) {
String valueStr = request.substring(valueIndex + 6);
targetBrightness = valueStr.toInt();
Serial.print("Web Brightness Set to: ");
Serial.println(targetBrightness);
}
}

client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
client.println("<!DOCTYPE HTML><html><body><h1>Brightness Set</h1></body></html>");
client.stop();
}

// Log brightness to Serial Monitor
Serial.print("Potentiometer Brightness: ");
Serial.print(targetBrightness);
Serial.print(" | Current Brightness: ");
Serial.println(currentBrightness);

delay(10);
}

Steps to Upload

  1. Connect ESP32 via USB.
  2. Go to Tools > Board > ESP32 Dev Module and select the correct port.
  3. Click Upload to transfer the code to the ESP32.

Running the Project

  1. Adjust the Potentiometer: Observe the LED brightness changing smoothly and the OLED displaying the current brightness percentage.
  2. Access Web Interface: In a browser on the same WiFi network, enter the ESP32’s IP address to open the web page. Use the slider to adjust brightness remotely.
  3. Serial Monitor Feedback: Open Serial Monitor to see the brightness levels.

Check Output

  1. OLED Display: Shows the real-time brightness percentage.
  2. Web Interface: Adjusts brightness with a slider.
  3. LED Brightness: Smoothly fades according to potentiometer and web interface input.
  4. Serial Monitor: Logs potentiometer and current brightness values.

FAQ

  1. What if the web interface doesn’t load?
  2. Check the ESP32’s IP address in the Serial Monitor and ensure the device is connected to the same network.
  3. How can I change the fade speed?
  4. Adjust the delay at the end of the loop() function to control fade speed.
  5. Why is the OLED display blank?
  6. Check wiring and ensure the display is set to address 0x3C.

Recommended Book

Arduino Programming for Absolute Beginners

This book covers Arduino basics and practical projects, ideal for those starting with microcontrollers.

For more tutorials on Arduino, ESP8266, ESP32, and Raspberry Pi, visit: MechatronicsLab.net