Arduino UNO Smart Waste Sorting System Using Ultrasonic Sensor, Moisture Sensor, Servo, Stepper Motor and LCD

Arduino UNO Smart Waste Sorting System | Automatic Garbage Segregation Project | MakeMindz
♻️ Part of the Industrial & Automation Projects series — View all on MakeMindz →
Industrial · Automation
♻️ Smart City · Eco-Automation

Arduino UNO Smart Waste Sorting System — Automatic Garbage Segregation Using Sensors

🟡 Intermediate–Advanced 📅 February 2026 ⏱ 15 min read 🛠 HC-SR04 · Moisture · Inductive · Servo · Stepper

Build an automated garbage segregation system that classifies waste into wet, dry, and metal categories using sensor-based detection and motorized mechanisms — all controlled by an Arduino UNO. Ideal for smart city projects, STEM exhibitions, and environmental engineering demos. Full code, wiring tables, and diagram.json included.

Simulate on Wokwi (Free)

What This System Does

The Arduino UNO Smart Waste Sorting System is an automated garbage segregation machine that uses three sensors to classify waste into separate bins — completely hands-free. An HC-SR04 detects when waste is placed, a moisture sensor identifies wet waste, and an inductive proximity sensor catches metal objects. The stepper motor then rotates the bin platform to the correct compartment, and the servo motor opens the chute to drop waste in.

💧 Wet Waste

  • Moisture sensor reads LOW (wet detected)
  • Inductive sensor reads LOW (no metal)
  • Stepper → 120° (wet bin)
  • Servo sweeps 0° → 180°

📦 Dry Waste

  • Moisture sensor reads HIGH (no moisture)
  • Inductive sensor reads LOW (no metal)
  • 3 consecutive detections confirm dry
  • Stepper stays at 0° (dry bin)

🔩 Metal Waste

  • Inductive sensor reads HIGH
  • Processed immediately — takes priority
  • Stepper → 240° (metal bin)
  • Servo sweeps 0° → 180°

Key Features

✔ Auto wet/dry/metal detection ✔ Contact-based moisture sensing ✔ Inductive metal detection ✔ Motorised rotating bin (stepper) ✔ Chute servo mechanism ✔ Real-time I2C LCD feedback ✔ Dry confirmation threshold ✔ IoT-expandable design

How the Waste Sorting Works

1️⃣

Object Detection

HC-SR04 ultrasonic sensor detects waste placed within 5cm of the input chute.

2️⃣

Waste Classification

Moisture sensor and inductive sensor read simultaneously to classify the waste type.

3️⃣

Automated Sorting

Stepper rotates the bin platform. Servo opens the chute. LCD updates the status.

Priority Logic

Metal detection takes priority — if the inductive sensor fires, the system immediately processes metal waste regardless of the moisture reading. If no metal is found, the moisture sensor determines wet vs dry. Dry waste requires 3 consecutive detections (configurable via dryThreshold) to avoid false positives.

LCD Status Messages

ConditionLCD Row 1 Message
No waste detected (>5cm)"Put Waste"
Metal detected"Metal Detected"
Wet waste (moisture LOW)"Wet Object"
Dry waste (moisture HIGH × 3)"Dry Object"

Components Required

🤖
Arduino UNO
Main controller
📡
HC-SR04
Trig: pin 3 · Echo: pin 2
💧
Moisture Sensor
Power: pin 6 · DO: pin 0
🔩
Inductive Sensor
Signal: pin 7
⚙️
SG90 Servo
Signal: pin 13
🔄
28BYJ-48 Stepper
IN1-4: pins 8,10,9,11
🖥
16×2 I2C LCD
SDA: A4 · SCL: A5
🔌
ULN2003 Driver
Stepper motor driver
🔋
9V Battery
Power supply

Libraries Required

LibraryPurposeInstall
Stepper.h28BYJ-48 stepper motor via ULN2003Built-in Arduino
Wire.hI2C communication for LCDBuilt-in Arduino
LiquidCrystal_I2C.hI2C LCD display controlLibrary Manager
Servo.hSG90 servo motor controlBuilt-in Arduino

Complete Wiring Guide

HC-SR04 Ultrasonic Sensor

HC-SR04 PinArduino PinWire
VCC5VRed
GNDGNDBlack
TRIGDigital 3Yellow
ECHODigital 2Green

Moisture / Rain Sensor

Sensor PinArduino PinWireNotes
VCCDigital 6 (POWER_PIN)RedSoftware-controlled power — saves energy
GNDGNDBlack
DODigital 0 (DO_PIN)BlueLOW = wet, HIGH = dry
⚠️

Avoid pin 0 in production: Digital pin 0 is the hardware Serial RX pin. While it works in this sketch, it can conflict with serial uploading. In a real build, consider moving DO to pin 4 or 5 and adjusting the DO_PIN define.

Inductive Proximity Sensor

Sensor PinArduino PinWireNotes
VCC5VRedSome modules need 12V — check datasheet
GNDGNDBlack
OUTDigital 7OrangeHIGH = metal detected

SG90 Servo Motor

Servo WireArduino PinColor
Power (+)5VRed
Ground (–)GNDBlack / Brown
SignalDigital 13Orange / Yellow

28BYJ-48 Stepper Motor (via ULN2003 Driver)

ULN2003 PinArduino PinWire
IN1Digital 8Blue
IN2Digital 10Blue
IN3Digital 9Blue
IN4Digital 11Blue
VCC (+)5VRed
GND (–)GNDBlack
📌

Stepper pin order matters: The Stepper(2048, 8, 10, 9, 11) constructor uses interleaved pin order (IN1, IN3, IN2, IN4) which produces the correct half-step sequence for the 28BYJ-48. Do not change this order.

16×2 I2C LCD Display

LCD PinArduino PinWire
VCC5VRed
GNDGNDBlack
SDAA4Green
SCLA5Yellow

Stepper Motor Bin Positions

The 28BYJ-48 makes 2048 steps per revolution. The three waste bins are positioned 120° apart around the rotating platform:

🟡 Dry Bin
0 steps · Default position
120°
💧 Wet Bin
682 steps (2048 ÷ 3)
240°
🔩 Metal Bin
1365 steps (2048 × 2 ÷ 3)

After each sorting cycle, the stepper always returns to the dry position (0°) to reset for the next item. The position tracker (currentPosition) ensures efficient movement by calculating only the delta steps needed.


Step-by-Step Setup

  1. 1

    Set Up the Arduino UNO in Wokwi

    Go to wokwi.com, click "New Project", and select "Arduino Uno". The Uno appears on the canvas — this is your main controller for all sensors and motors.

  2. 2

    Add the HC-SR04 Ultrasonic Sensor

    Click "+", search for "HC-SR04", and place it above the Uno. Connect TRIG to digital pin 3 and ECHO to digital pin 2. This sensor detects when waste is within 5cm of the input chute.

  3. 3

    Add the Moisture / Rain Sensor

    Search for "Rain Sensor" or "Moisture Sensor". Connect its VCC to digital pin 6 (software-controlled power) and DO to digital pin 0. LOW output = moisture detected (wet waste).

  4. 4

    Add the Inductive Proximity Sensor

    Search for "Inductive Sensor" and connect its output to digital pin 7. This sensor outputs HIGH when a metal object is detected — it takes priority in the sorting logic.

  5. 5

    Add the SG90 Servo Motor

    Search for "Servo" and connect the signal wire to digital pin 13. The servo controls the waste chute flap — sweeping from 0° to 180° releases waste into the selected bin.

  6. 6

    Add the Stepper Motor with ULN2003 Driver

    Search for "Stepper Motor (28BYJ-48)" which includes the ULN2003 board. Connect IN1→pin 8, IN2→pin 10, IN3→pin 9, IN4→pin 11. This motor rotates the 3-compartment bin platform.

    In Wokwi, the 28BYJ-48 + ULN2003 is often a single combined component. If not, search for "ULN2003 Stepper Driver" and attach the motor to it.

  7. 7

    Add the 16×2 I2C LCD

    Search for "LCD 1602 I2C" and connect SDA to A4 and SCL to A5. The LCD address is 0x27 — confirm this matches your physical module.

  8. 8

    Paste the diagram.json and Code, then Simulate

    Copy the diagram.json below into Wokwi's diagram tab, paste the Arduino code into the editor, and press ▶ Play. The serial monitor will show distance and sensor readings in real time.


Arduino Code — Complete Sketch

Copy and paste this into the Wokwi code editor or Arduino IDE. All logic is contained in a single sketch.

Arduino C++ — sketch.ino
#include <Stepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>

// ── Pin Definitions ───────────────────────────
#define POWER_PIN  6   // Software power for moisture sensor
#define DO_PIN     0   // Moisture sensor digital output
#define SERVO_PIN  13  // SG90 servo signal pin

// ── Ultrasonic Sensor ─────────────────────────
const int trigPin = 3;
const int echoPin = 2;
long duration;
int distance;

// ── Inductive Sensor ──────────────────────────
const int InductiveSensor = 7;

// ── Stepper Motor (28BYJ-48 via ULN2003) ─────
int stepsPerRevolution = 2048;
int rpm = 10;
// Pin order: IN1, IN3, IN2, IN4 for correct sequence
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);

// ── Servo Motor ───────────────────────────────
Servo myServo;

// ── I2C LCD (address 0x27, 16×2) ─────────────
LiquidCrystal_I2C lcd(0x27, 16, 2);

// ── Dry Detection Threshold ───────────────────
int dryCounter = 0;
const int dryThreshold = 3; // 3 consecutive reads = confirmed dry

// ── Stepper Position Tracker (steps from 0°) ──
int currentPosition = 0;
const int dryPosition   = 0;                          // 0°
const int wetPosition   = stepsPerRevolution / 3;       // 120°
const int metalPosition = stepsPerRevolution * 2 / 3;   // 240°

// ─────────────────────────────────────────────
void setup() {
  myStepper.setSpeed(rpm);
  myServo.attach(SERVO_PIN);
  pinMode(InductiveSensor, INPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(POWER_PIN, OUTPUT);
  pinMode(DO_PIN, INPUT);
  lcd.init();
  lcd.backlight();
  Serial.begin(9600);
}

// ─────────────────────────────────────────────
void loop() {
  getDistance();

  int inductiveValue = digitalRead(InductiveSensor);

  // Metal detection takes PRIORITY
  if (inductiveValue == HIGH) {
    processMetal();
    return;
  }

  // No object detected → idle state
  if (distance > 5) {
    lcd.setCursor(0, 0);
    lcd.print("Put Waste       ");
    dryCounter = 0;
    returnStepperToDry();
  }
  // Object detected within 5cm
  else {
    int rain_state = getRainState();
    if (inductiveValue == LOW && rain_state == LOW) {
      processWet();    // Wet: no metal, moisture present
    } else if (inductiveValue == LOW && rain_state == HIGH) {
      dryCounter++;
      if (dryCounter >= dryThreshold) {
        processDry();   // Dry: confirmed after 3 readings
      }
    }
  }
}

// ── Ultrasonic distance measurement ──────────
void getDistance() {
  digitalWrite(trigPin, LOW);  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH); delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034 / 2;
  Serial.print("Distance: "); Serial.println(distance);
}

// ── Moisture sensor read (power-cycled) ───────
int getRainState() {
  digitalWrite(POWER_PIN, HIGH);
  delay(10);
  int rain_state = digitalRead(DO_PIN);
  digitalWrite(POWER_PIN, LOW);
  Serial.println(rain_state == HIGH ? "Dry" : "Wet");
  return rain_state;
}

// ── Metal waste processing ────────────────────
void processMetal() {
  lcd.setCursor(0, 0); lcd.print("Metal Detected  ");
  moveStepperTo(metalPosition);
  delay(1000);
  myServo.write(180); delay(500);
  myServo.write(0);   delay(500);
  returnStepperToDry();
}

// ── Wet waste processing ──────────────────────
void processWet() {
  lcd.setCursor(0, 0); lcd.print("Wet Object      ");
  moveStepperTo(wetPosition);
  delay(1000);
  myServo.write(180); delay(500);
  myServo.write(0);   delay(500);
  returnStepperToDry();
}

// ── Dry waste processing ──────────────────────
void processDry() {
  lcd.setCursor(0, 0); lcd.print("Dry Object      ");
  moveStepperTo(dryPosition);
  delay(1000);
  myServo.write(180); delay(500);
  myServo.write(0);   delay(500);
}

// ── Stepper position control ──────────────────
void moveStepperTo(int targetPosition) {
  int stepsToMove = targetPosition - currentPosition;
  myStepper.step(stepsToMove);
  currentPosition = targetPosition;
}

void returnStepperToDry() {
  if (currentPosition != dryPosition) {
    moveStepperTo(dryPosition);
  }
}
📌

Dry threshold: Change dryThreshold = 3 to 1 for faster response, or increase it to reduce false positives from borderline moisture readings.


IoT Upgrade Possibilities

This system is designed to be expandable. Add any of the following to transform it into a full Smart City Waste Monitoring System:

ESP8266 for WiFi cloud data logging
ESP32 for advanced IoT applications
GSM module for SMS fill-level alerts
Mobile app monitoring dashboard
Solar panel for off-grid operation
Load cell to track bin fill weight

More Arduino & IoT Projects on MakeMindz

Comments

try for free