Community project

Three-Button LED Control

ESP32
Photo of Three-Button LED Control
Generated with AI

GmailVeng

Last updated October 10, 2026

This project demonstrates how to control three LEDs independently using push buttons on an ESP32 microcontroller. Each button toggles its corresponding LED on and off, with brightness controlled by a potentiometer. The system also monitors temperature data from six MCP9808 sensors connected via I2C, reading values at regular intervals while managing button debouncing for reliable input detection.

The guide provides a complete wiring diagram showing how to connect the three push buttons, three LEDs with current-limiting resistors, the potentiometer for brightness adjustment, and all six temperature sensors to the ESP32. Assembly steps cover power rail setup, component connections, I2C address configuration, and firmware installation with debounce logic and PWM brightness control.

Wiring diagram

Wiring diagram for Three-Button LED Control

Gather all the parts

QtyComponent
1

Push Button

Momentary push button switch

1

Push Button

Momentary push button switch

1

Push Button

Momentary push button switch

1

LED

LED 5 mm สีแดง

Standard 3mm/5mm through-hole LED. A current-limiting series resistor is added automatically.

1

LED

LED 5 mm สีเขียว

Standard 3mm/5mm through-hole LED. A current-limiting series resistor is added automatically.

1

LED

LED 5 mm สีฟ้า

Standard 3mm/5mm through-hole LED. A current-limiting series resistor is added automatically.

1

10kΩ Potentiometer

A three-terminal adjustable resistor used to set LED brightness.

1

Resistor

220 Ω

Through-hole resistor (current-limiting in series with an LED)

1

Resistor

220 Ω

Through-hole resistor (current-limiting in series with an LED)

1

Resistor

220 Ω

Through-hole resistor (current-limiting in series with an LED)

1

MCP9808 Temperature Sensor (I2C 0x18)

A digital temperature sensor module configured to use I2C address 0x18.

1

MCP9808 Temperature Sensor (I2C 0x19)

A digital temperature sensor module configured to use I2C address 0x19.

1

MCP9808 Temperature Sensor (I2C 0x1A)

A digital temperature sensor module configured to use I2C address 0x1A.

1

MCP9808 Temperature Sensor (I2C 0x1B)

A digital temperature sensor module configured to use I2C address 0x1B.

1

MCP9808 Temperature Sensor (I2C 0x1C)

A digital temperature sensor module configured to use I2C address 0x1C.

1

MCP9808 Temperature Sensor (I2C 0x1D)

A digital temperature sensor module configured to use I2C address 0x1D.

Assemble it in 7 steps

1. ทำรางไฟ 3.3 โวลต์และกราวด์

วาง ESP32-S3 ข้างเบรดบอร์ด แล้วต่อขา 3V3 ของบอร์ดเข้ารางบวกด้วยสายสีแดง และต่อขา GND เข้ารางลบด้วยสายสีดำ เพื่อให้ทุกชิ้นส่วนมีกราวด์ร่วมกัน.

  • ใช้ราง 3V3 สำหรับเซ็นเซอร์ ตัวปรับ และสายสัญญาณ I2C ทั้งหมด
  • อย่าต่อราง 3V3 เข้ากับขา 5V หรือ VIN เพราะไฟเกินอาจทำให้เซ็นเซอร์และขารับสัญญาณเสียหาย

2. ต่อปุ่มกด 3 ปุ่ม

เสียบปุ่มแต่ละตัวคร่อมร่องกลางของเบรดบอร์ด: button_1 ขาหนึ่ง → GPIO4 (สัญญาณ), อีกขา → GND (กราวด์); button_2 ขาหนึ่ง → GPIO5 (สัญญาณ), อีกขา → GND (กราวด์); button_3 ขาหนึ่ง → GPIO6 (สัญญาณ), อีกขา → GND (กราวด์).

  • ขาปุ่มสองขาด้านเดียวกันมักเชื่อมกันอยู่แล้ว ให้เลือกต่อคนละด้านของปุ่ม
  • ต้องวางปุ่มคร่อมร่องกลาง มิฉะนั้นปุ่มอาจต่อวงจรค้างและกดไม่ทำงาน

3. ต่อ LED พร้อมตัวต้านทาน

ต่อ resistor_1 ขาหนึ่ง → GPIO14 (สัญญาณ), อีกขา → ขายาวของ led_1; ขาสั้นของ led_1 → GND (กราวด์). ต่อ resistor_2 ขาหนึ่ง → GPIO15 (สัญญาณ), อีกขา → ขายาวของ led_2; ขาสั้นของ led_2 → GND (กราวด์). ต่อ resistor_3 ขาหนึ่ง → GPIO16 (สัญญาณ), อีกขา → ขายาวของ led_3; ขาสั้นของ led_3 → GND (กราวด์).

  • ขายาวของ LED คือด้านบวก และตัวต้านทาน 220 Ω ใส่กลับด้านได้
  • อย่าต่อ LED ตรงเข้าขา GPIO โดยไม่มีตัวต้านทาน 220 Ω เพราะกระแสสูงอาจทำให้ LED หรือบอร์ดเสียหาย

4. ต่อตัวปรับความสว่าง

ต่อขานอกด้านหนึ่งของ potentiometer_1 → 3V3 (ไฟเลี้ยง), ขากลาง → GPIO1 (สัญญาณปรับความสว่าง), และขานอกอีกด้าน → GND (กราวด์).

  • หากหมุนแล้วสว่างเพิ่มในทิศที่ไม่ชอบ ให้สลับเฉพาะสายขานอกสองขา
  • ห้ามใช้ 5V กับขานอกของตัวปรับ เพราะ GPIO1 รับแรงดันได้ไม่เกิน 3.3V

5. ตั้งที่อยู่ของเซ็นเซอร์ทั้ง 6 ตัว

ใช้ MCP9808 แบบที่มีจัมเปอร์เลือกที่อยู่ แล้วตั้งให้ไม่ซ้ำกัน: temperature_1 ใช้ 0x18 ไม่ต้องเชื่อมจัมเปอร์; temperature_2 เชื่อม A0 → 3V3 เพื่อใช้ 0x19; temperature_3 เชื่อม A1 → 3V3 เพื่อใช้ 0x1A; temperature_4 เชื่อม A1 และ A0 → 3V3 เพื่อใช้ 0x1B; temperature_5 เชื่อม A2 → 3V3 เพื่อใช้ 0x1C; temperature_6 เชื่อม A2 และ A0 → 3V3 เพื่อใช้ 0x1D.

  • จัมเปอร์ A0/A1/A2 มักอยู่ด้านหลังโมดูลและอาจต้องบัดกรีหยดตะกั่วเพื่อเชื่อม
  • การตั้งที่อยู่จะถูกอ่านตอนเปิดไฟ ดังนั้นให้ถอดและเสียบ USB ใหม่หลังเปลี่ยนจัมเปอร์
  • หากเซ็นเซอร์สองตัวใช้ที่อยู่เดียวกัน บอร์ดจะอ่านค่าไม่ได้อย่างถูกต้อง

6. ต่อสายร่วมของเซ็นเซอร์อุณหภูมิ

ต่อเซ็นเซอร์ทุกตัวแบบขนานเข้ารางและสายชุดเดียวกัน: VCC ของ temperature_1 ถึง temperature_6 → 3V3 (ไฟเลี้ยง); GND ของ temperature_1 ถึง temperature_6 → GND (กราวด์); SDA ของ temperature_1 ถึง temperature_6 → GPIO8 (ข้อมูล); SCL ของ temperature_1 ถึง temperature_6 → GPIO9 (จังหวะสื่อสาร). ไม่ต้องต่อขา ALERT.

  • ต่อ GPIO8 และ GPIO9 เป็นเส้นยาวสองเส้นบนเบรดบอร์ด แล้วแตกสายไปยังเซ็นเซอร์ทั้งหกตัว จะต่อได้เป็นระเบียบ
  • โมดูล MCP9808 breakout ปกติมีตัวต้านทานช่วยดึงสายสัญญาณอยู่แล้ว
  • VCC และ GND ที่สลับกันสามารถทำให้โมดูลเสียหายได้; ตรวจชื่อขาบนแผงของแต่ละตัวก่อนเสียบ USB

7. ตรวจสายและจ่ายไฟ

ตรวจว่า LED หันถูกด้าน ตรวจว่าจัมเปอร์ที่อยู่ของ MCP9808 ทั้ง 6 ตัวไม่ซ้ำกัน และทุกโมดูลต่อกับ 3V3 ไม่ใช่ 5V จากนั้นเสียบ USB เข้าบอร์ด.

  • หลังแฟลช โปรแกรมจะแสดงค่าอุณหภูมิของแต่ละจุดทุก 1 วินาทีในหน้าต่างข้อความของบอร์ด
  • หากบอร์ดหรือเซ็นเซอร์ร้อนผิดปกติ ให้ถอด USB ทันที แล้วตรวจสาย 3V3 และ GND ใหม่

Review all connections

1. Connections between "button_1" and "ESP32"

Functionbutton_1ESP32
groundGNDGND
digitalSIGNALGPIO 4

2. Connections between "button_2" and "ESP32"

Functionbutton_2ESP32
groundGNDGND
digitalSIGNALGPIO 5

3. Connections between "button_3" and "ESP32"

Functionbutton_3ESP32
groundGNDGND
digitalSIGNALGPIO 6

4. Connections between "potentiometer_1" and "ESP32"

Functionpotentiometer_1ESP32
powerEnd1 (VCC side)3V3
analogWiper (middle)GPIO 1
groundEnd2 (GND side)GND

5. Connections between "resistor_1" and "ESP32"

Functionresistor_1ESP32
digitalP1GPIO 14
digitalP2 → LED ANODEEXT

6. Connections between "led_1" and "ESP32"

Functionled_1ESP32
groundGNDGND

7. Connections between "resistor_2" and "ESP32"

Functionresistor_2ESP32
digitalP1GPIO 15
digitalP2 → LED ANODEEXT

8. Connections between "led_2" and "ESP32"

Functionled_2ESP32
groundGNDGND

9. Connections between "resistor_3" and "ESP32"

Functionresistor_3ESP32
digitalP1GPIO 16
digitalP2 → LED ANODEEXT

10. Connections between "led_3" and "ESP32"

Functionled_3ESP32
groundGNDGND

11. Connections between "temperature_1" and "ESP32"

Functiontemperature_1ESP32
powerVCC3V3
groundGNDGND
i2cSDAGPIO 8
i2cSCLGPIO 9

12. Connections between "temperature_2" and "ESP32"

Functiontemperature_2ESP32
powerVCC3V3
groundGNDGND
i2cSDAGPIO 8
i2cSCLGPIO 9

13. Connections between "temperature_3" and "ESP32"

Functiontemperature_3ESP32
powerVCC3V3
groundGNDGND
i2cSDAGPIO 8
i2cSCLGPIO 9

14. Connections between "temperature_4" and "ESP32"

Functiontemperature_4ESP32
powerVCC3V3
groundGNDGND
i2cSDAGPIO 8
i2cSCLGPIO 9

15. Connections between "temperature_5" and "ESP32"

Functiontemperature_5ESP32
powerVCC3V3
groundGNDGND
i2cSDAGPIO 8
i2cSCLGPIO 9

16. Connections between "temperature_6" and "ESP32"

Functiontemperature_6ESP32
powerVCC3V3
groundGNDGND
i2cSDAGPIO 8
i2cSCLGPIO 9

Deploy the firmware

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_MCP9808.h>

const int BUTTON_1_PIN = 4;
const int BUTTON_2_PIN = 5;
const int BUTTON_3_PIN = 6;
const int POT_PIN = 1;
const int LED_1_PIN = 14;
const int LED_2_PIN = 15;
const int LED_3_PIN = 16;
const int I2C_SDA_PIN = 8;
const int I2C_SCL_PIN = 9;

const uint32_t PWM_FREQUENCY = 5000;
const uint8_t PWM_RESOLUTION = 8;
const uint32_t DEBOUNCE_MS = 35;
const uint32_t TEMPERATURE_INTERVAL_MS = 1000;
const uint8_t SENSOR_COUNT = 6;
const uint8_t SENSOR_ADDRESSES[SENSOR_COUNT] = {0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D};

struct ButtonState {
  int pin;
  bool ledOn;
  int lastReading;
  int stableState;
  unsigned long lastChangeMs;
};

ButtonState buttons[] = {
  {BUTTON_1_PIN, false, HIGH, HIGH, 0},
  {BUTTON_2_PIN, false, HIGH, HIGH, 0},
  {BUTTON_3_PIN, false, HIGH, HIGH, 0}
};

const int ledPins[] = {LED_1_PIN, LED_2_PIN, LED_3_PIN};
Adafruit_MCP9808 temperatureSensors[SENSOR_COUNT];
bool sensorPresent[SENSOR_COUNT] = {false, false, false, false, false, false};
uint8_t brightness = 0;
unsigned long lastTemperatureReadMs = 0;

void updateLeds() {
  for (int i = 0; i < 3; i++) {
    ledcWrite(ledPins[i], buttons[i].ledOn ? brightness : 0);
  }
}

void readButtons() {
  unsigned long now = millis();

  for (int i = 0; i < 3; i++) {
    int reading = digitalRead(buttons[i].pin);

    if (reading != buttons[i].lastReading) {
      buttons[i].lastChangeMs = now;
      buttons[i].lastReading = reading;
    }

    if ((now - buttons[i].lastChangeMs) >= DEBOUNCE_MS && reading != buttons[i].stableState) {
      buttons[i].stableState = reading;
      if (buttons[i].stableState == LOW) {
        buttons[i].ledOn = !buttons[i].ledOn;
        updateLeds();
      }
    }
  }
}

void readBrightness() {
  int rawValue = analogRead(POT_PIN);
  uint8_t newBrightness = map(rawValue, 0, 4095, 0, 255);

  if (abs((int)newBrightness - (int)brightness) >= 2) {
    brightness = newBrightness;
    updateLeds();
  }
}

void startTemperatureSensors() {
  Serial.println("Starting MCP9808 temperature sensors");
  for (uint8_t i = 0; i < SENSOR_COUNT; i++) {
    sensorPresent[i] = temperatureSensors[i].begin(SENSOR_ADDRESSES[i], &Wire);
    Serial.printf("Sensor %u at 0x%02X: %s\n", i + 1, SENSOR_ADDRESSES[i],
                  sensorPresent[i] ? "found" : "not found");
  }
}

void readTemperatures() {
  unsigned long now = millis();
  if (now - lastTemperatureReadMs < TEMPERATURE_INTERVAL_MS) {
    return;
  }
  lastTemperatureReadMs = now;

  for (uint8_t i = 0; i < SENSOR_COUNT; i++) {
    if (!sensorPresent[i]) {
      continue;
    }
    float temperatureC = temperatureSensors[i].readTempC();
    Serial.printf("Temperature %u: %.2f C\n", i + 1, temperatureC);
  }
  Serial.println();
}

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

  for (int i = 0; i < 3; i++) {
    pinMode(buttons[i].pin, INPUT_PULLUP);
    ledcAttach(ledPins[i], PWM_FREQUENCY, PWM_RESOLUTION);
    ledcWrite(ledPins[i], 0);
  }

  Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);
  startTemperatureSensors();
}

void loop() {
  readButtons();
  readBrightness();
  readTemperatures();
}

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik