Trash Can

Note

🌟 Welcome to the SunFounder Facebook Community! Whether you’re into Raspberry Pi, Arduino, or ESP32, you’ll find inspiration, help ideas here.

  • ✅ Be the first to get free learning resources.

  • ✅ Stay updated on new products & exclusive giveaways.

  • ✅ Share your creations and get real feedback.

  • 👉 Need faster updates or support? Click [here] join our Facebook community

  • 👉 Or join our WhatsApp group: Click [here]

Kit purchase

Looking for parts? Check out our all-in-one kits below — packed with components, beginner-friendly guides, and tons of fun.

../_images/esp32_kit.png

Name

Includes ESP32 board

PURCHASE LINK

ESP32 Ultimate Starter Kit

ESP32 WROOM 32E +

BUY

Universal Maker Sensor Kit

BUY

Course Introduction

In this lesson, you’ll learn how to use an ultrasonic sensor module, a digital servo motor, and an ESP32 board to build a smart trash can.

When the ultrasonic sensor module detects trash being thrown in, the digital servo motor opens the lid of the trash can.

Note

If this is your first time working with an ESP32 project, we recommend downloading and reviewing the basic materials first.

Required Components

In this project, we need the following components:

SN

COMPONENT INTRODUCTION

QUANTITY

PURCHASE LINK

1

ESP-WROOM-32 ESP32 ESP-32S Development Board

1

BUY

2

USB Type-C cable

1

3

Breadboard

1

BUY

4

Wires

Several

BUY

5

1kΩ resistor

2

BUY

6

Ultrasonic Sensor Module

1

BUY

7

LED

2

BUY

8

Digital Servo Motor

1

BUY

Wiring

../_images/trash_can_bb1.png

Common Connections:

  • Digital Servo Motor

    • GND: Connect to GND on the ESP32.

    • VCC: Connect to 5V on the ESP32.

    • Connect to GPIO25 on the ESP32.

  • Ultrasonic Sensor Module

    • Trig: Connect to GPIO5 on the ESP32.

    • Echo: Connect to GPIO18 on the ESP32.

    • GND: Connect to GND on the ESP32.

    • VCC: Connect to 3.3V on the ESP32.

Writing the Code

Note

  • You can copy this code into Arduino IDE.

  • Don’t forget to select the board(ESP32 Dev module) and the correct port before clicking the Upload button.

#include <ESP32Servo.h>

// -------- Servo parameters --------
Servo servo;
const int servoPin   = 25;   // Any ESP32 GPIO capable of PWM (avoid 34–39, input-only)
const int openAngle  = 0;
const int closeAngle = 90;

// -------- Ultrasonic sensor parameters (HC-SR04 type) --------
const int trigPin = 5;       // Trigger pin, ESP32 outputs 3.3V
const int echoPin = 18;      // Echo pin (must be level-shifted to 3.3V)
long distance, averageDistance;
long averDist[3];

// Distance threshold (in cm)
const int distanceThreshold = 20;

// Constants
const unsigned long echoTimeoutUs = 30000UL; // 30ms timeout ≈ 5m max range
const int servoMinUs = 500;   // Minimum pulse width for servo (µs)
const int servoMaxUs = 2500;  // Maximum pulse width for servo (µs)

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

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT); // Input (make sure hardware level shifting is done)

  // Initialize servo: attach at 50Hz, move to closed angle, then detach to save power
  servo.setPeriodHertz(50);
  servo.attach(servoPin, servoMinUs, servoMaxUs);
  servo.write(closeAngle);
  delay(200);
  servo.detach();
}

void loop() {
  // Take three consecutive measurements
  for (int i = 0; i < 3; i++) {
    distance = readDistanceCm();
    averDist[i] = distance;
    delay(10);
  }

  // Calculate the average
  averageDistance = (averDist[0] + averDist[1] + averDist[2]) / 3;
  Serial.println(averageDistance);

  // Control the servo based on distance
  if (averageDistance > 0 && averageDistance <= distanceThreshold) {
    // Attach only when needed, reduces idle power and jitter
    if (!servo.attached()) {
      servo.attach(servoPin, servoMinUs, servoMaxUs);
    }
    servo.write(openAngle);
    delay(3500);
  } else {
    if (servo.attached()) {
      servo.write(closeAngle);
      delay(1000);
      servo.detach();
    } else {
      // Maintain loop rhythm even if servo is detached
      delay(50);
    }
  }
}

// Measure distance (in cm); returns -1 if timeout
long readDistanceCm() {
  // Trigger 10µs pulse
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Measure echo pulse width (with timeout)
  unsigned long duration = pulseIn(echoPin, HIGH, echoTimeoutUs);
  if (duration == 0) {
    return -1; // Timeout / no echo
  }

  // Distance (cm) = pulse width (µs) / 58.0
  long dist = (long)(duration / 58.0);
  return dist;
}