DEV Community

Emily Johnson
Emily Johnson

Posted on

How to Use MQTT and Microcontrollers to Automate Trash Bin Cleaning

Keeping commercial trash bins clean on a reliable schedule can be a logistical headache—especially when you manage multiple locations or a large facility. In this tutorial, we'll show you how to leverage MQTT, microcontrollers (e.g., ESP32 or Arduino), and minimal code to:

  • Monitor fill levels or time-based triggers
  • Publish and subscribe to cleaning events
  • Automatically activate cleaning mechanisms (pump, motor, valve, etc.)
  • Track and log every cleaning cycle for auditing

Whether you run a large facility in Chicago’s west side like Cleaning Services Avondale or maintain an office park north of the city, this system will save you time and money.


Table of Contents

  1. Why Automate Trash Bin Cleaning?
  2. System Architecture Overview
  3. Hardware Components
  4. Setting Up the MQTT Broker
  5. Microcontroller Firmware (ESP32 / Arduino)
  6. Backend Script to Schedule & Monitor
  7. Putting It All Together
  8. Deployment & Maintenance
  9. Conclusion

Why Automate Trash Bin Cleaning?

Manual cleaning schedules can suffer from:

  • Inconsistent timing (forgotten or delayed cleanings)
  • High labor costs for routine checks
  • Lack of audit logs for compliance or SLA reporting

An IoT-based solution ensures each bin is serviced exactly when needed. You can even integrate with local providers—imagine scheduling overflow alerts to trigger external contractors like Cleaning Services Beverly or Cleaning Services Bridgeport only when a bin’s ultrasonic sensor reports it’s 90% full.


System Architecture Overview

flowchart LR
    Sensor[Ultrasonic Sensor] --> MCU[ESP32 / Arduino]
    MCU --> MQTTBroker[MQTT Broker (Mosquitto)]
    MQTTBroker --> Scheduler[Python Scheduler Service]
    Scheduler --> MCU
    Scheduler --> Database[(PostgreSQL / InfluxDB)]
    UI[Web Dashboard] --> Scheduler
Enter fullscreen mode Exit fullscreen mode
  1. Sensor & MCU: Detect fill level or use a simple timer
  2. MQTT Broker: Central hub for publish/subscribe messages
  3. Scheduler Service: Python script that issues “clean now” commands
  4. Database & Dashboard: Log events, display status

Hardware Components

  • ESP32 or Arduino Uno + Ethernet/WiFi Shield
  • Ultrasonic sensor (HC-SR04) or load cell for weight detection
  • Relay module to drive pump/motor/solenoid valve
  • Power supply (5V/12V depending on actuator)

Setting Up the MQTT Broker

We’ll use Mosquitto on a Raspberry Pi or any Linux server.

# Install Mosquitto
sudo apt update
sudo apt install -y mosquitto mosquitto-clients

# Configure a basic user/password
sudo mosquitto_passwd -c /etc/mosquitto/passwd iot_user
# (enter password when prompted)

# Edit /etc/mosquitto/mosquitto.conf and add:
allow_anonymous false
password_file /etc/mosquitto/passwd
listener 1883

# Restart service
sudo systemctl restart mosquitto
Enter fullscreen mode Exit fullscreen mode

Test connectivity:

mosquitto_pub -h localhost -t "trashbin/test" -u iot_user -P <yourpw> -m "hello"
mosquitto_sub -h localhost -t "trashbin/test" -u iot_user -P <yourpw>
Enter fullscreen mode Exit fullscreen mode

Microcontroller Firmware (ESP32 / Arduino)

Below is an ESP32 Arduino sketch. It reads an ultrasonic sensor, publishes bin level every minute, and listens for a “clean” command.

#include <WiFi.h>
#include <PubSubClient.h>

#define TRIG_PIN 5
#define ECHO_PIN 18
#define RELAY_PIN 23

const char* ssid     = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASS";
const char* mqttServer = "192.168.1.10";
const int mqttPort = 1883;
const char* mqttUser = "iot_user";
const char* mqttPass = "YOURMQTTPASSWORD";

WiFiClient espClient;
PubSubClient client(espClient);

void setupWifi() {
  delay(10);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}

long readUltrasonicDistance() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  long duration = pulseIn(ECHO_PIN, HIGH);
  long distance = (duration / 2) / 29.1; // cm
  return distance;
}

void callback(char* topic, byte* payload, unsigned int length) {
  String msg;
  for (unsigned int i = 0; i < length; i++) msg += (char)payload[i];

  if (String(topic) == "trashbin/clean") {
    if (msg == "NOW") {
      digitalWrite(RELAY_PIN, HIGH);
      delay(5000);
      digitalWrite(RELAY_PIN, LOW);
    }
  }
}

void reconnect() {
  while (!client.connected()) {
    if (client.connect("ESP32Client", mqttUser, mqttPass)) {
      client.subscribe("trashbin/clean");
    } else {
      delay(5000);
    }
  }
}

void setup() {
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);

  setupWifi();
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) reconnect();
  client.loop();

  long distance = readUltrasonicDistance();
  int fillPercent = map(distance, 2, 100, 100, 0);
  if (fillPercent < 0) fillPercent = 0;
  if (fillPercent > 100) fillPercent = 100;

  // Publish fill level as JSON
  String payload = "{"level":" + String(fillPercent) + "}";
  client.publish("trashbin/level", payload.c_str());

  delay(60000); // every minute
}
Enter fullscreen mode Exit fullscreen mode

Backend Script to Schedule & Monitor

A Python service can subscribe to trashbin/level, store data, and publish trashbin/clean when needed:

import json
import time
import paho.mqtt.client as mqtt
from datetime import datetime
import psycopg2

MQTT_BROKER = "192.168.1.10"
MQTT_PORT = 1883
USER = "iot_user"
PASSWORD = "YOURMQTTPASSWORD"

# PostgreSQL connection
conn = psycopg2.connect(
    dbname="iot_db", user="iot", password="dbpass", host="localhost"
)
cur = conn.cursor()

def on_connect(client, userdata, flags, rc):
    client.subscribe("trashbin/level")

def on_message(client, userdata, msg):
    data = json.loads(msg.payload.decode())
    level = data["level"]
    timestamp = datetime.utcnow()
    cur.execute(
        "INSERT INTO bin_levels (timestamp, level) VALUES (%s, %s)",
        (timestamp, level),
    )
    conn.commit()

    # Trigger clean at > 80% or every 24h
    if level > 80 or (timestamp.hour == 3 and timestamp.minute == 0):
        client.publish("trashbin/clean", "NOW")
        # Log cleaning event
        cur.execute(
            "INSERT INTO clean_events (timestamp, reason) VALUES (%s, %s)",
            (timestamp, "AUTO_TRIGGER"),
        )
        conn.commit()

client = mqtt.Client()
client.username_pw_set(USER, PASSWORD)
client.on_connect = on_connect
client.on_message = on_message

client.connect(MQTT_BROKER, MQTT_PORT, 60)
client.loop_forever()
Enter fullscreen mode Exit fullscreen mode

Putting It All Together

  1. Deploy the ESP32 code to each trash bin node.
  2. Run Mosquitto on a stable server.
  3. Start the Python scheduler as a systemd service for resilience.
  4. Visualize data with Grafana or a simple React dashboard—ideal for facility managers at companies like Maid Service Chatham.

Deployment & Maintenance

  • Security: Enable TLS on Mosquitto and rotate credentials periodically.
  • Scaling: For dozens of bins, partition topics (trashbin/1/level, trashbin/2/level, …).
  • Alerts: Integrate with Slack or SMS (Twilio) for manual intervention.
  • Firmware OTA: Consider Arduino OTA or ESP32 HTTP update server for remote code pushes.

Conclusion

By combining MQTT, microcontrollers, and a lightweight backend, you can fully automate commercial trash bin cleaning:

  • Reduce labor costs and oversight
  • Guarantee compliance with service-level agreements
  • Generate audit logs for each cleaning cycle

Start prototyping today using this guide, and transform routine maintenance into a smart, data-driven process.


Ready to dive deeper? Share your project on GitHub, tag #IoTCleaning, and connect with our community on dev.to!

Top comments (0)