AI Garbage Segregation Robot!

🤖 AI Garbage Robot — Kids' Build Tutorial!

AI Garbage Segregation Robot! 🤖♻️

Build a real robot that uses a camera and a smart AI brain to sort your rubbish — all by itself! 🌍

🥧 Raspberry Pi 🤖 Arduino 🧠 TensorFlow Lite 📷 Camera ⚙️ Servo Motor ♻️ Saves the Planet
🗺️ Project Overview

What Does This Robot Do? 🤔

You drop a piece of rubbish onto the robot's tray. Its camera takes a photo. Then the AI brain (a smart program on the Raspberry Pi) looks at the photo and says "hey, that's a plastic bottle — it goes in the recycling bin!" Then a little servo motor swings a flap to guide the rubbish into the right bin. Magic? Nope — it's science! 🔬

🗑️
Drop rubbish
PIR detects it
📷
Camera snaps
Pi Camera v2
🧠
AI decides
TFLite model
📡
Pi tells Arduino
1 byte via USB
⚙️
Servo swings
Flap gate moves
♻️
Right bin!
Planet saved 🌍
📝This is a learning prototype — perfect for a school project or science fair! The same ideas are used in real sorting factories that recycle millions of items every day.
🧠 Learning Corner

What Is Artificial Intelligence? 🤖

Artificial Intelligence (AI) means teaching a computer to think and learn — a bit like how you learned to recognise a cat by seeing lots of cats! Let's learn the big ideas behind this robot:

👁️

Computer Vision

Teaching a computer to understand pictures — just like how your eyes and brain work together!

🕸️

Neural Networks

A type of AI that works like a brain — thousands of tiny connected "neurons" learn patterns together.

📦

Transfer Learning

We start with an AI that already knows about 1 million images — then teach it about rubbish! Saves a LOT of time.

Tiny AI (TFLite)

We squish a big AI model into a tiny file so it fits on the Raspberry Pi — like zipping a huge bag into a small backpack!

🏷️

Image Classification

Looking at an image and saying "this is a bottle" or "this is cardboard." Our robot does this for 6 types of rubbish!

📊

Confidence Score

The AI says "I'm 91% sure that's plastic." If it's less than 65% sure, we take a second photo and try again!

🔄

Automation

The robot keeps working by itself — sense → think → act → repeat. No humans needed once it's set up!

🌱

Training Data

We teach the AI using thousands of rubbish photos. More good photos = smarter robot. Rubbish in, intelligence out! 😄

The 6 Types of Rubbish Our Robot Knows 🗂️

♻️ RECYCLABLE BIN (5 types)

  • 📦 Cardboard — boxes, tubes
  • 🍾 Glass — bottles and jars
  • 🥫 Metal — cans and tin foil
  • 📰 Paper — newspapers, notebooks
  • 🧴 Plastic — bottles, containers

🗑️ NON-RECYCLABLE BIN (1 type)

  • 🍕 Food waste
  • 🥡 Mixed materials
  • ☕ Styrofoam cups
  • 🧁 Waxed packaging
  • 🍽️ Ceramics / porcelain

How Good Is Our AI? 📈

📦 Cardboard
94%
🍾 Glass
88%
🥫 Metal
91%
📰 Paper
89%
🧴 Plastic
87%
🗑️ Trash
82%
🌟Did you know? Real rubbish sorting factories in Japan and Sweden use the same AI technology — and sort over 1,000 items per minute! Your robot is the same idea, just smaller! 🏭
⚙️ System Design

Two Brains Are Better Than One! 🧠🧠

Our robot uses two computers working as a team — just like a pilot and a co-pilot on an aeroplane!

🥧 Raspberry Pi 4 (Big Brain)🤖 Arduino Uno (Fast Brain)
Runs Linux and PythonRuns C++ code
Takes photos with the cameraControls the servo motor
Runs the AI to classify rubbishShows results on the LCD screen
Makes the sorting decisionReads the PIR motion sensor
Sends a 1-letter command over USBMakes the robot physically move!
Saves a log of everything sortedSends a "done!" message back to Pi

📨 The Secret Message System

The Raspberry Pi sends just one letter to the Arduino to tell it what to do! Simple and fast:

Letter SentMeaningServo Goes To
'R'♻️ Recyclable item!45° — left bin
'N'🗑️ Non-recyclable135° — right bin
'?'🤔 Not sure — take another photo!90° — stay in middle
'T'✅ Test — are you alive?Don't move
💡The Raspberry Pi is too big and powerful to control a servo directly — it's like using a supercomputer to switch on a light! The Arduino is perfectly sized for that job. This is called a heterogeneous computing architecture — a very fancy name for "two computers sharing the work"! 😄
🧰 Parts List

Everything You'll Need to Build It! 🛒

🥧
Raspberry Pi 4 (2GB+)
The main AI brain
🤖
Arduino Uno R3
Controls the moving parts
📷
Raspberry Pi Camera v2
The robot's eye!
⚙️
SG90 Servo Motor
Swings the sorting flap
🖥️
I2C LCD Screen 16×2
Shows what was detected
👤
PIR Motion Sensor
Detects when rubbish arrives
🔴
LED Lights × 3
Green, Red, and Blue
🔔
Buzzer
Beeps when done sorting!
🔋
5V 3A Power Supply
Official Pi charger only!
💾
MicroSD Card 32GB+
Stores the Pi's brain
🔗
USB-A to USB-B Cable
Pi talks to Arduino
📦
Cardboard Box Chassis
Build your own two-bin robot body!
⚠️The Raspberry Pi 4 needs a proper 5V 3A power supply. Using a phone charger might make it go slow or crash — like trying to run a race wearing flip-flops! 🩴
🔌 Wiring Guide

How to Connect Everything 🔧

AI Garbage Segregation Robot circuit diagram showing Raspberry Pi 4 connected to Pi Camera, PIR sensor, LEDs and Arduino Uno connected to SG90 servo, I2C LCD display and buzzer
📐 Full Circuit — Raspberry Pi + Camera + PIR + Arduino + Servo + LCD Display

📷 Pi Camera → Raspberry Pi

ConnectionHow to do it
CSI ribbon cableLift the latch on the Camera (CSI) port on your Pi. Slide in the ribbon cable with the blue side facing the Ethernet port. Push the latch down firmly. Test it with libcamera-still -o test.jpg

👤 PIR Sensor → Raspberry Pi GPIO

PIR PinPi PinWire Colour
VCCPin 2 (5V)Red
GNDPin 6 (GND)Black
OUTGPIO 17 (Pin 11)Yellow

🔴 Status LEDs → Raspberry Pi GPIO

LED ColourPi GPIOResistor NeededMeans...
Blue LEDGPIO 27 (Pin 13)220Ω🔵 Scanning right now!
Green LEDGPIO 22 (Pin 15)220Ω♻️ Recyclable!
Red LEDGPIO 23 (Pin 16)220Ω🗑️ Non-recyclable!
All GND legsPin 20 (GND)Common ground

🔗 Raspberry Pi → Arduino

ConnectionNotes
USB-A (Pi) → USB-B (Arduino)This one cable does EVERYTHING — it powers the Arduino AND lets the Pi send messages to it! On the Pi it shows up as /dev/ttyACM0

⚙️ SG90 Servo → Arduino

Servo WireArduino PinNotes
Red5VPower!
BrownGNDGround
Orange (signal)Pin 9 (PWM)This wire controls the angle

🖥️ I2C LCD Screen → Arduino

LCD PinArduino PinWire
VCC5VRed
GNDGNDBlack
SDAA4Blue
SCLA5Yellow

🔔 Buzzer → Arduino

Buzzer PinArduino PinNotes
Positive (+)Pin 8Put a 100Ω resistor in the wire — it protects the buzzer!
Negative (−)GNDCommon ground
💡Before you start, run ls /dev/ttyACM* on the Pi to check Arduino is detected. Also run sudo adduser pi dialout once — otherwise Python can't talk to the Arduino! 🐍
🧠 AI Model Setup

Teaching the AI Brain About Rubbish! 📚

Before our robot can sort rubbish, we need to train the AI — show it thousands of photos of rubbish so it learns what's what. We do this in Google Colab, which gives us a free super-fast computer in the cloud! ☁️

🌟Quick Option: You can download a pre-trained model from the TrashNet Kaggle page — search "MobileNetV2 TrashNet tflite" and download trash_classifier.tflite and labels.txt. Copy them to ~/segregation/model/ on your Pi and skip straight to Step 6!

🐍 Training Script — Run This in Google Colab!

📝In Google Colab: click Runtime → Change runtime type → T4 GPU. Training takes about 10–15 minutes and gives you a ready-to-use AI model file!
🌐 train_model.py — Run in Google Colab!
"""
Train our Garbage AI!
Uses MobileNetV2 + TrashNet dataset
Run in Google Colab with GPU for best results 🚀
"""

import tensorflow as tf
import tensorflow_datasets as tfds
import numpy as np, os

# ── Settings ──────────────────────────────────
IMG_SIZE    = 224   # MobileNetV2 needs 224×224 photos
BATCH_SIZE  = 32
EPOCHS_HEAD = 5    # train just the top layer first
EPOCHS_FINE = 10   # then fine-tune the whole model

CLASS_NAMES = ['cardboard', 'glass', 'metal',
               'paper', 'plastic', 'trash']

# ── Load TrashNet dataset ──────────────────────
print("📦 Loading TrashNet...")
(train_ds, val_ds), info = tfds.load(
    'trash_classification',
    split=['train[:80%]', 'train[80%:]'],
    as_supervised=True, with_info=True
)

# ── Make photos the right size + add variety ──
def preprocess(img, label):
    img = tf.image.resize(img, [IMG_SIZE, IMG_SIZE])
    img = tf.cast(img, tf.float32) / 255.0  # 0 to 1
    return img, label

def augment(img, label):  # make training harder = smarter AI!
    img = tf.image.random_flip_left_right(img)
    img = tf.image.random_brightness(img, 0.2)
    img = tf.image.random_contrast(img, 0.8, 1.2)
    return tf.clip_by_value(img, 0, 1), label

train_ds = (train_ds.map(preprocess).map(augment)
              .shuffle(1000).batch(BATCH_SIZE).prefetch(2))
val_ds   = (val_ds.map(preprocess).batch(BATCH_SIZE).prefetch(2))

# ── Build the AI model ────────────────────────
print("🧠 Building MobileNetV2...")
base = tf.keras.applications.MobileNetV2(
    input_shape=(IMG_SIZE, IMG_SIZE, 3),
    include_top=False, weights='imagenet'  # start with smart weights!
)
base.trainable = False  # freeze base for now

model = tf.keras.Sequential([
    base,
    tf.keras.layers.GlobalAveragePooling2D(),
    tf.keras.layers.Dropout(0.3),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(6, activation='softmax')  # 6 rubbish types
])

# Phase 1: teach just the top layer
print("📚 Phase 1: Learning rubbish categories...")
model.compile(optimizer=tf.keras.optimizers.Adam(1e-3),
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
model.fit(train_ds, validation_data=val_ds, epochs=EPOCHS_HEAD)

# Phase 2: fine-tune the whole model
base.trainable = True
for layer in base.layers[:100]:  # keep first 100 layers frozen
    layer.trainable = False

print("🔧 Phase 2: Fine-tuning (getting smarter)...")
model.compile(optimizer=tf.keras.optimizers.Adam(1e-5),
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
model.fit(train_ds, validation_data=val_ds, epochs=EPOCHS_FINE)

# ── Shrink it down for Raspberry Pi ──────────
print("📦 Shrinking model for Pi (quantization)...")
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()

with open('trash_classifier.tflite', 'wb') as f:
    f.write(tflite_model)
with open('labels.txt', 'w') as f:
    f.write('\n'.join(CLASS_NAMES))

print(f"✅ Done! Model size: {len(tflite_model)//1024} KB")
print("📋 Copy these to ~/segregation/model/ on your Pi!")
🛠️ Build Steps

Let's Build It — Step by Step! 🔨

  • 1
    Set Up Your Raspberry Pi 📦

    Flash Raspberry Pi OS Lite (64-bit) to your SD card using the Raspberry Pi Imager app. Turn on SSH and set your Wi-Fi password in the Imager settings. Boot up, SSH in, and run sudo apt update && sudo apt upgrade -y. Enable the camera: sudo raspi-config → Interface Options → Camera → Enable → Reboot!

  • 2
    Install the Python Packages 🐍

    Type this into your Pi's terminal: pip3 install tflite-runtime picamera2 pyserial RPi.GPIO opencv-python-headless numpy pillow. This downloads all the tools our AI code needs — like loading up your backpack before a school trip!

  • 3
    Attach the Camera 📷

    Carefully lift the latch on the Camera (CSI) port on your Pi. Slide the ribbon cable in with the blue side facing the Ethernet port. Press the latch down. Test it: libcamera-still -o test.jpg — if you can copy the photo to your computer and see it, the camera works! 🎉

  • 4
    Wire the Pi's GPIO Pins 🔴

    Connect your PIR sensor (OUT → GPIO 17). Connect the three LEDs through 220Ω resistors to GPIO 27 (blue), GPIO 22 (green), GPIO 23 (red). All negative legs go to a GND pin. Test a LED: python3 -c "import RPi.GPIO as G; G.setmode(G.BCM); G.setup(22,G.OUT); G.output(22,1)"

  • 5
    Wire the Arduino Parts ⚙️

    Servo: orange → Pin 9, red → 5V, brown → GND. LCD Screen: SDA → A4, SCL → A5, VCC → 5V, GND → GND. Buzzer: positive (through 100Ω resistor) → Pin 8, negative → GND. Open Arduino IDE, install the LiquidCrystal_I2C library, then upload the Arduino code below!

  • 6
    Copy Your AI Model to the Pi 🧠

    Create a folder: mkdir -p ~/segregation/model. Copy your trash_classifier.tflite and labels.txt files there using: scp trash_classifier.tflite pi@[YOUR_PI_IP]:~/segregation/model/. The Pi now has a brain!

  • 7
    Connect Pi to Arduino 🔗

    Plug the USB cable between Pi and Arduino. On the Pi, type ls /dev/ttyACM* — you should see /dev/ttyACM0. Then run sudo adduser $USER dialout and log out + back in. Now Pi and Arduino can talk to each other!

  • 8
    Build Your Sorting Robot Body 📦

    Grab a cardboard box and cut it into a two-compartment bin (left = recyclable, right = trash). Mount the servo at the top-centre to control a cardboard flap. Stick the camera above the drop zone pointing straight down. Mount the PIR sensor at the entrance pointing across. Get creative — decorate it! 🎨

  • 9
    Run the Robot! 🚀

    Copy segregation.py (see below) to ~/segregation/. Start the robot with python3 ~/segregation/segregation.py. Drop a plastic bottle in the tray and watch the magic happen! The blue LED flashes while scanning, then green or red lights up to show the result. 🎉

  • 10
    Make It Auto-Start 🔄 (Optional Bonus!)

    Want your robot to start automatically when you turn it on? Create a systemd service file at /etc/systemd/system/segregation.service pointing to your Python script. Run sudo systemctl enable segregation. Now just plug in the power and it starts by itself — just like a real product! ⚡

🐍 Python Code for Raspberry Pi

The Main AI Brain Script 🧠

This is the Python code that runs on the Raspberry Pi. It watches for rubbish, takes photos, runs the AI, and tells the Arduino what to do! Save this as ~/segregation/segregation.py

🐍 segregation.py — runs on Raspberry Pi 4
"""
╔══════════════════════════════════════════════════╗
║   AI GARBAGE SEGREGATION ROBOT — Raspberry Pi    ║
║   TFLite + Pi Camera + Serial → Arduino          ║
╚══════════════════════════════════════════════════╝
"""

import time, csv, os
import numpy as np
import RPi.GPIO as GPIO
import serial
from picamera2 import Picamera2
from PIL import Image
import tflite_runtime.interpreter as tflite

# ── GPIO Pin Numbers ──────────────────────────────
PIR_PIN       = 17   # motion sensor
LED_SCANNING  = 27   # blue  — scanning
LED_RECYCLE   = 22   # green — recyclable
LED_TRASH     = 23   # red   — non-recyclable

# ── File Paths ───────────────────────────────────
MODEL_PATH  = "/home/pi/segregation/model/trash_classifier.tflite"
LABELS_PATH = "/home/pi/segregation/model/labels.txt"
LOG_PATH    = "/home/pi/segregation/log.csv"
CAPTURE_DIR = "/home/pi/segregation/captures/"

# ── Settings ─────────────────────────────────────
IMG_SIZE       = 224
CONFIDENCE_MIN = 0.65   # below 65%? take another photo!
SERIAL_PORT    = "/dev/ttyACM0"
BAUD_RATE      = 9600
MAX_RESCANS    = 3

RECYCLABLE = {'cardboard', 'glass', 'metal', 'paper', 'plastic'}

# ── Set Up GPIO ───────────────────────────────────
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(PIR_PIN,      GPIO.IN)
GPIO.setup(LED_SCANNING, GPIO.OUT)
GPIO.setup(LED_RECYCLE,  GPIO.OUT)
GPIO.setup(LED_TRASH,    GPIO.OUT)

def leds_off():
    for pin in [LED_SCANNING, LED_RECYCLE, LED_TRASH]:
        GPIO.output(pin, GPIO.LOW)

leds_off()

# ── Load Class Labels ─────────────────────────────
with open(LABELS_PATH) as f:
    LABELS = [line.strip() for line in f]

# ── Load the TFLite AI Model ──────────────────────
interpreter = tflite.Interpreter(model_path=MODEL_PATH)
interpreter.allocate_tensors()
inp  = interpreter.get_input_details()
outp = interpreter.get_output_details()
print(f"🧠 AI model loaded! Input shape: {inp[0]['shape']}")

# ── Set Up Camera ─────────────────────────────────
cam = Picamera2()
cam.configure(cam.create_still_configuration(
    main={"size": (640, 480), "format": "RGB888"}
))
cam.start()
time.sleep(2)   # camera warm-up time
print("📷 Camera ready!")

# ── Connect to Arduino ────────────────────────────
try:
    ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=2)
    time.sleep(2)
    print(f"🤖 Arduino connected on {SERIAL_PORT}")
except:
    ser = None
    print("⚠️ Arduino not found — running without it")

# ── Set Up Log File ───────────────────────────────
os.makedirs(CAPTURE_DIR, exist_ok=True)
if not os.path.exists(LOG_PATH):
    with open(LOG_PATH, 'w', newline='') as f:
        csv.writer(f).writerow(
            ['time', 'class', 'confidence', 'category']
        )

# ── AI Classification Function ────────────────────
def classify(frame_rgb):
    "Take a photo array, return (label, confidence)"
    img = Image.fromarray(frame_rgb).resize((IMG_SIZE, IMG_SIZE))
    arr = np.array(img, dtype=np.float32) / 255.0
    arr = np.expand_dims(arr, axis=0)
    interpreter.set_tensor(inp[0]['index'], arr)
    interpreter.invoke()
    out = interpreter.get_tensor(outp[0]['index'])[0]
    idx = int(np.argmax(out))
    return LABELS[idx], float(out[idx])

# ── Sort the Item ─────────────────────────────────
def sort_item(label, confidence):
    leds_off()
    if confidence < CONFIDENCE_MIN:
        print(f"  🤔 Not sure ({confidence:.0%}) — rescanning...")
        if ser: ser.write(b'?')
        return "unknown"
    elif label in RECYCLABLE:
        GPIO.output(LED_RECYCLE, GPIO.HIGH)
        print(f"  ♻️  RECYCLABLE — {label} ({confidence:.0%}) ✅")
        if ser: ser.write(b'R')
        return "recyclable"
    else:
        GPIO.output(LED_TRASH, GPIO.HIGH)
        print(f"  🗑️  TRASH — {label} ({confidence:.0%})")
        if ser: ser.write(b'N')
        return "non-recyclable"

# ══════════════════════════════════════════════════
#   MAIN LOOP — keeps running forever!
# ══════════════════════════════════════════════════
print("\n🤖 AI GARBAGE ROBOT IS READY! Drop something in! 🗑️\n")
count = 0

try:
    while True:
        if GPIO.input(PIR_PIN) == GPIO.HIGH:
            count += 1
            print(f"\n[Item #{count}] 👀 Something arrived!")
            time.sleep(0.6)  # let item settle on the tray

            category, rescans = "unknown", 0
            while category == "unknown" and rescans <= MAX_RESCANS:
                GPIO.output(LED_SCANNING, GPIO.HIGH)
                frame = cam.capture_array()
                GPIO.output(LED_SCANNING, GPIO.LOW)

                label, conf = classify(frame)
                print(f"  Scan {rescans+1}: {label} — {conf:.0%}")
                category = sort_item(label, conf)
                rescans += 1
                if category == "unknown": time.sleep(2)

            if category == "unknown":   # gave up — default to trash
                category = "non-recyclable"
                if ser: ser.write(b'N')
                GPIO.output(LED_TRASH, GPIO.HIGH)

            if ser:  # print Arduino's reply
                ack = ser.readline().decode().strip()
                if ack: print(f"  🤖 Arduino says: {ack}")

            # Save to log
            with open(LOG_PATH, 'a', newline='') as f:
                csv.writer(f).writerow([
                    time.strftime("%Y-%m-%d %H:%M:%S"),
                    label, f"{conf:.4f}", category
                ])

            time.sleep(3)   # show LED result for 3 seconds
            leds_off()
            while GPIO.input(PIR_PIN): time.sleep(0.1)

        time.sleep(0.1)

except KeyboardInterrupt:
    print("\n👋 Robot shutting down...")
finally:
    cam.stop()
    if ser: ser.close()
    GPIO.cleanup()
    print(f"🏆 Session done! {count} items sorted. Log saved to {LOG_PATH}")
🤖 Arduino Code

The Servo & Screen Controller! ⚙️

This code runs on the Arduino Uno. It waits for a letter from the Raspberry Pi, then moves the servo and shows the result on the LCD screen! First, install the LiquidCrystal_I2C library via Arduino IDE → Sketch → Include Library → Manage Libraries.

🤖 garbage_sorter.ino — runs on Arduino Uno
/*
 * AI GARBAGE SORTER — Arduino Controller
 * Controls: SG90 Servo + I2C LCD + Buzzer
 *
 * Listens for 1 letter from Raspberry Pi:
 *   'R' → Recyclable  → servo swings LEFT  (45°)
 *   'N' → Non-recycle → servo swings RIGHT (135°)
 *   '?' → Not sure    → stay in middle     (90°)
 *   'T' → Test ping   → reply OK
 */

#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// ── Pins ──────────────────────────────────────
#define SERVO_PIN    9
#define BUZZER_PIN   8

// ── Servo angles ──────────────────────────────
#define RECYCLE_ANGLE   45    // left bin
#define TRASH_ANGLE    135    // right bin
#define NEUTRAL_ANGLE   90    // middle / waiting
#define RETURN_AFTER  3000    // return to middle after 3 seconds

// ── Objects ───────────────────────────────────
Servo flap;
LiquidCrystal_I2C lcd(0x27, 16, 2);  // try 0x3F if blank

// ── Counters ──────────────────────────────────
int recycleCount = 0;
int trashCount   = 0;
int currentAngle = NEUTRAL_ANGLE;
bool pendingReturn = false;
unsigned long returnAt = 0;

void setup() {
  Serial.begin(9600);
  pinMode(BUZZER_PIN, OUTPUT);

  flap.attach(SERVO_PIN);
  flap.write(NEUTRAL_ANGLE);
  delay(500);

  lcd.init();
  lcd.backlight();

  // Welcome message!
  lcd.setCursor(1, 0); lcd.print("AI RUBBISH BOT");
  lcd.setCursor(4, 1); lcd.print("READY! :)");

  // Happy startup beeps
  tone(BUZZER_PIN, 880, 100);  delay(150);
  tone(BUZZER_PIN, 1046, 100); delay(150);
  tone(BUZZER_PIN, 1318, 200); delay(400);

  Serial.println("READY");
}

// ── Smooth servo sweep ────────────────────────
void sweepTo(int target) {
  int step = (target > currentAngle) ? 1 : -1;
  while (currentAngle != target) {
    currentAngle += step;
    flap.write(currentAngle);
    delay(7);
  }
}

void loop() {

  // Auto-return to middle after a few seconds
  if (pendingReturn && millis() >= returnAt) {
    sweepTo(NEUTRAL_ANGLE);
    pendingReturn = false;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("R:"); lcd.print(recycleCount);
    lcd.print("  T:"); lcd.print(trashCount);
    lcd.setCursor(0, 1); lcd.print("Waiting... :)");
  }

  // Listen for message from Pi
  if (Serial.available() > 0) {
    char cmd = Serial.read();

    if (cmd == 'R') {       // ♻️ Recyclable!
      recycleCount++;
      sweepTo(RECYCLE_ANGLE);
      lcd.clear();
      lcd.setCursor(0, 0); lcd.print("  RECYCLABLE! :D");
      lcd.setCursor(0, 1); lcd.print("  GREEN BIN ->");
      tone(BUZZER_PIN, 1046, 100); delay(140);
      tone(BUZZER_PIN, 1318, 100); delay(140);
      tone(BUZZER_PIN, 1568, 220);
      Serial.println("ACK:RECYCLE");
      pendingReturn = true; returnAt = millis() + RETURN_AFTER;
    }
    else if (cmd == 'N') {  // 🗑️ Non-recyclable
      trashCount++;
      sweepTo(TRASH_ANGLE);
      lcd.clear();
      lcd.setCursor(0, 0); lcd.print(" NON-RECYCLE :/");
      lcd.setCursor(0, 1); lcd.print("   RED BIN ->");
      tone(BUZZER_PIN, 440, 350);
      Serial.println("ACK:TRASH");
      pendingReturn = true; returnAt = millis() + RETURN_AFTER;
    }
    else if (cmd == '?') {  // 🤔 Not sure — rescan
      sweepTo(NEUTRAL_ANGLE);
      lcd.clear();
      lcd.setCursor(0, 0); lcd.print(" RESCANNING...");
      lcd.setCursor(0, 1); lcd.print(" Hmm, not sure");
      for (int i = 0; i < 3; i++) {
        tone(BUZZER_PIN, 660, 60); delay(120);
      }
      Serial.println("ACK:RESCAN");
      pendingReturn = false;
    }
    else if (cmd == 'T') {  // ✅ Test ping
      lcd.clear();
      lcd.setCursor(3, 0); lcd.print("HELLO PI! :)");
      tone(BUZZER_PIN, 1320, 80);
      Serial.println("ACK:TEST-OK");
      delay(1500);
    }
  }
}
💡If the LCD screen stays blank after uploading, the I2C address might be 0x3F instead of 0x27. Just change that one number in the code and upload again! 🔧
📟 Live Output

What You'll See on the Screen! 👀

Open a terminal on the Pi and run your script — here's what it looks like when everything is working perfectly:

Pi Terminal — Live Robot Output
$ python3 ~/segregation/segregation.py
🧠 AI model loaded! Input shape: [1, 224, 224, 3]
📷 Camera ready!
🤖 Arduino connected on /dev/ttyACM0
─────────────────────────────────────────────
🤖 AI GARBAGE ROBOT IS READY! Drop something in! 🗑️

[Item #1] 👀 Something arrived!
Scan 1: plastic — 91%
♻️ RECYCLABLE — plastic (91%) ✅
🤖 Arduino says: ACK:RECYCLE

[Item #2] 👀 Something arrived!
Scan 1: trash — 78%
🗑️ TRASH — trash (78%)
🤖 Arduino says: ACK:TRASH

[Item #3] 👀 Something arrived!
Scan 1: cardboard — 58%
🤔 Not sure (58%) — rescanning...
Scan 2: cardboard — 85%
♻️ RECYCLABLE — cardboard (85%) ✅
🤖 Arduino says: ACK:RECYCLE

^C (pressed Ctrl+C to stop)
🏆 Session done! 3 items sorted. Log saved!
🔧 Fix Problems

Uh Oh! Something Not Working? 😅

Don't panic — every engineer runs into problems! Here's how to fix the most common ones:

😟 Problem🔍 Why It Happens✅ How to Fix It
Camera not found Camera not enabled or ribbon cable loose Run sudo raspi-config → Interface → Camera → Enable → Reboot. Re-seat the ribbon cable (blue side toward Ethernet port).
No module named tflite_runtime Package not installed or wrong version Run pip3 install tflite-runtime. On 64-bit Pi OS, add --index-url https://google-coral.github.io/py-repo/
Permission denied on /dev/ttyACM0 User not allowed to use serial ports Run sudo adduser $USER dialout then log out and back in. This lets Python talk to the Arduino!
Robot always says "trash" Image not normalized properly Make sure you divide pixel values by 255.0 in the classify() function. The AI expects numbers from 0 to 1, not 0 to 255!
Servo shakes but doesn't move Not enough power The Arduino's 5V pin might not give enough current for both the LCD and servo. Try powering the servo from the battery pack directly instead.
LCD screen is blank Wrong I2C address Try changing 0x27 to 0x3F in the Arduino code. Also turn the little potentiometer on the LCD backpack to adjust contrast.
PIR triggers with nothing there Too sensitive, or heat nearby Turn the sensitivity dial on the PIR module counter-clockwise. Keep it away from direct sunlight and heating vents.
AI takes 5 seconds per photo Model not compressed / Pi throttling Make sure you're using the .tflite file, not the full Keras model. Check Pi temperature: vcgencmd measure_temp — above 80°C it goes slow! Add a heatsink.
🌟Remember — bugs are normal! Every single programmer in the world, even professionals at Google and NASA, spends time fixing bugs. Finding and fixing a bug makes you a real engineer! 🚀
🚀 Level Up!

Make It Even More Amazing! ⭐

You've built the basic robot — now try these upgrades to make it even cooler!

Super-Speed AI

Plug in a Google Coral USB Accelerator — it makes the AI 30× faster! Near-instant sorting! 🏎️

📊

Web Dashboard

Build a website with Flask that shows how many items were sorted today — like a scoreboard! 🏆

🏗️

5-Bin Sorting!

Add one servo per rubbish type — cardboard, glass, metal, paper, plastic all get their own bin!

🔄

Real Conveyor Belt

Add a DC motor to move items automatically — like a real factory! Use a second sensor to pause the belt for scanning.

🔊

Voice Announcements

Add a speaker and use Python's pyttsx3 library to make the robot say "Recyclable!" out loud! 🗣️

📱

Full Bin Alert!

Add a weight sensor (HX711 + load cell). When the bin is full, send a WhatsApp message! 📲

🧠

Train Your Own AI

Take 200 photos of YOUR local rubbish and add them to the training data. A robot trained on YOUR bins will work better for YOU!

🎮

Rubbish Sorting Game

Build a website where people try to sort rubbish faster than your robot — and the robot always wins! 😄

🤖 ♻️ 🌍

You Just Built a Real AI Robot! 🎉

Camera → AI brain → servo motor → sorted rubbish. That's the same loop used in self-driving cars, medical robots, and smart factories. You now understand how it works — from scratch! Keep building and keep saving the planet! 💚

Comments

Product Cards
Buddy Bot eBook
⭐ New 2026 Release
Build Your
Own Robot!
3D design, wiring &
Arduino coding.
Young inventors love it!
🖨️
3D Print
All parts
Wire it
Circuit guide
💻
Code it
Arduino IDE
🤖
Watch it
Walk & react
📋 Your Details
Enter your name
Valid 10-digit no.
Enter a valid email
Special Website Offer
₹499 300
🌍 International: $5 USD
One-time · Instant digital delivery
🔒 Secured by Razorpay · Your data is safe
📄 Download Free Sample Copy
🔒 Secured by Razorpay · Your data is safe
🍓
Raspberry Pi Pico Mastery
21 Projects
⚡ Launch Price — 80% OFF
Learn Pico
Build 21 Projects!
MicroPython · Wokwi
IoT · Certificate
Perfect for beginners!
🖥️
Wokwi
No hardware
🐍
MicroPy
From zero
🔨
21 Projects
IoT + sensors
📄
Certificate
Verified cert
📋 Your Details
Enter your name
Valid 10-digit no.
Enter a valid email
Special Launch Offer
₹999 200 80% OFF
🌍 International: $5 USD
One-time · Lifetime access · No subscription
🔒 Secured by Razorpay · UPI · Cards · NetBanking
🎉

You're in!

Payment successful! Your Buddy Bot eBook is ready. Time to build!

📖 Access Your eBook Now
🎉

Enrolled!

Payment successful! Lifetime access to all 21 Pico Projects is yours!

🍓 Go to My Course