Skip to content

Commit 9d108f9

Browse files
feat: complete smart dustbin embedded system with dual ultrasonic, servo lid control, 16x2 I2C LCD, alerts, and Wokwi simulation
1 parent e7d3540 commit 9d108f9

54 files changed

Lines changed: 2026 additions & 6 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/platformio.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: PlatformIO Build
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v4
16+
17+
- name: Set up PlatformIO
18+
uses: n-vr/setup-platformio-action@v1
19+
20+
- name: Build Arduino UNO firmware
21+
run: pio run

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.pio/
2+
.vscode/
3+
!.vscode/extensions.json
4+
5+
*.log
6+
.DS_Store
7+
Thumbs.db

LICENSE

Whitespace-only changes.

README.md

Lines changed: 405 additions & 6 deletions
Large diffs are not rendered by default.

arduino_code/smart_dustbin.ino

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
/**
2+
* ============================================================================
3+
* PROJECT: Smart Dustbin – Industry-Oriented Embedded System
4+
* PLATFORM: Arduino UNO / ATmega328P (Fully compatible with Wokwi / Tinkercad)
5+
* AUTHOR: Adarsh Srivastav
6+
* REPOSITORY: Smart-Dustbin-Embedded-System
7+
* ============================================================================
8+
*
9+
* DESCRIPTION:
10+
* An automated, hygienic, dual-sensor smart waste management system designed
11+
* for institutional and public deployment. It features:
12+
* 1. Proximity-based touchless lid actuation (Ultrasonic Sensor 1 + Servo Motor).
13+
* 2. Real-time internal waste level monitoring (Ultrasonic Sensor 2).
14+
* 3. 16x2 I2C LCD Display telemetry output.
15+
* 4. Fill-level percentage calculation and threshold detection.
16+
* 5. Multi-tier alert management (Green LED, Red LED, Active Buzzer).
17+
* 6. Full-bin safety interlock (prevents lid opening when bin is 100% full).
18+
* 7. Non-blocking state management using millis() timers.
19+
* ============================================================================
20+
*/
21+
22+
#include <Arduino.h>
23+
#include <Servo.h>
24+
#include <Wire.h>
25+
#include <LiquidCrystal_I2C.h>
26+
27+
// ============================================================================
28+
// 1. PIN DEFINITIONS & HARDWARE MAPPINGS
29+
// ============================================================================
30+
// Proximity Sensor (Hand Detection)
31+
const uint8_t HAND_TRIG_PIN = 9;
32+
const uint8_t HAND_ECHO_PIN = 10;
33+
34+
// Level Sensor (Internal Bin Fill Depth)
35+
const uint8_t LEVEL_TRIG_PIN = 6;
36+
const uint8_t LEVEL_ECHO_PIN = 7;
37+
38+
// Actuator & Acoustic Alert
39+
const uint8_t SERVO_PIN = 5;
40+
const uint8_t BUZZER_PIN = 4;
41+
42+
// Visual Indicators
43+
const uint8_t GREEN_LED_PIN = 12; // Normal operation / Ready
44+
const uint8_t RED_LED_PIN = 13; // Full-bin warning alert
45+
46+
// ============================================================================
47+
// 2. CALIBRATION CONSTANTS & SYSTEM THRESHOLDS
48+
// ============================================================================
49+
const float HAND_DETECTION_DISTANCE_CM = 20.0f;
50+
51+
const float EMPTY_BIN_DISTANCE_CM = 30.0f;
52+
const float FULL_BIN_DISTANCE_CM = 6.0f;
53+
54+
const uint8_t FULL_LEVEL_PERCENT = 90;
55+
56+
const int LID_CLOSED_ANGLE = 10;
57+
const int LID_OPEN_ANGLE = 100;
58+
59+
const unsigned long HAND_SENSOR_INTERVAL_MS = 100;
60+
const unsigned long LEVEL_SENSOR_INTERVAL_MS = 400;
61+
const unsigned long LID_HOLD_TIME_MS = 3000;
62+
const unsigned long BUZZER_BEEP_INTERVAL_MS = 2000;
63+
const unsigned long LCD_UPDATE_INTERVAL_MS = 500;
64+
const unsigned long SERIAL_PRINT_INTERVAL_MS = 1000;
65+
66+
// ============================================================================
67+
// 3. GLOBAL OBJECTS & STATE VARIABLES
68+
// ============================================================================
69+
Servo lidServo;
70+
LiquidCrystal_I2C lcd(0x27, 16, 2);
71+
72+
float currentHandDistance = -1.0f;
73+
float currentWasteDistance = -1.0f;
74+
int currentFillPercent = 0;
75+
bool isBinFull = false;
76+
bool isLidOpen = false;
77+
78+
unsigned long lastHandReadTime = 0;
79+
unsigned long lastLevelReadTime = 0;
80+
unsigned long lidAutoCloseTarget = 0;
81+
unsigned long lastBuzzerBeepTime = 0;
82+
unsigned long lastLcdUpdateTime = 0;
83+
unsigned long lastSerialLogTime = 0;
84+
85+
// ============================================================================
86+
// 4. HELPER FUNCTION: Read HC-SR04 Ultrasonic Sensor
87+
// ============================================================================
88+
float readUltrasonicDistance(uint8_t trigPin, uint8_t echoPin) {
89+
digitalWrite(trigPin, LOW);
90+
delayMicroseconds(2);
91+
92+
digitalWrite(trigPin, HIGH);
93+
delayMicroseconds(10);
94+
digitalWrite(trigPin, LOW);
95+
96+
unsigned long duration = pulseIn(echoPin, HIGH, 30000UL);
97+
if (duration == 0) return -1.0f;
98+
99+
float distanceCm = (duration * 0.0343f) / 2.0f;
100+
if (distanceCm < 2.0f || distanceCm > 400.0f) return -1.0f;
101+
102+
return distanceCm;
103+
}
104+
105+
// ============================================================================
106+
// 5. HELPER FUNCTION: Calculate Bin Fill Percentage
107+
// ============================================================================
108+
int calculateFillPercentage(float distanceCm) {
109+
if (distanceCm < 0.0f) return currentFillPercent;
110+
111+
float percentage = ((EMPTY_BIN_DISTANCE_CM - distanceCm) /
112+
(EMPTY_BIN_DISTANCE_CM - FULL_BIN_DISTANCE_CM)) * 100.0f;
113+
114+
if (percentage < 0.0f) percentage = 0.0f;
115+
if (percentage > 100.0f) percentage = 100.0f;
116+
117+
return (int)(percentage + 0.5f);
118+
}
119+
120+
// ============================================================================
121+
// 6. ACTUATION FUNCTIONS
122+
// ============================================================================
123+
void openLid() {
124+
lidServo.write(LID_OPEN_ANGLE);
125+
isLidOpen = true;
126+
lidAutoCloseTarget = millis() + LID_HOLD_TIME_MS;
127+
}
128+
129+
void closeLid() {
130+
lidServo.write(LID_CLOSED_ANGLE);
131+
isLidOpen = false;
132+
}
133+
134+
// ============================================================================
135+
// 7. ALERT MANAGEMENT FUNCTION
136+
// ============================================================================
137+
void updateAlertSystem(bool binFull) {
138+
unsigned long now = millis();
139+
140+
if (binFull) {
141+
digitalWrite(GREEN_LED_PIN, LOW);
142+
digitalWrite(RED_LED_PIN, HIGH);
143+
144+
if (now - lastBuzzerBeepTime >= BUZZER_BEEP_INTERVAL_MS) {
145+
lastBuzzerBeepTime = now;
146+
digitalWrite(BUZZER_PIN, HIGH);
147+
delay(100);
148+
digitalWrite(BUZZER_PIN, LOW);
149+
}
150+
} else {
151+
digitalWrite(GREEN_LED_PIN, HIGH);
152+
digitalWrite(RED_LED_PIN, LOW);
153+
digitalWrite(BUZZER_PIN, LOW);
154+
}
155+
}
156+
157+
// ============================================================================
158+
// 8. 16x2 LCD DISPLAY MANAGER
159+
// ============================================================================
160+
void updateLCD(unsigned long now) {
161+
if (now - lastLcdUpdateTime < LCD_UPDATE_INTERVAL_MS) return;
162+
lastLcdUpdateTime = now;
163+
164+
lcd.clear();
165+
166+
if (isBinFull) {
167+
lcd.setCursor(0, 0);
168+
lcd.print("BIN FULL! LOCK");
169+
lcd.setCursor(0, 1);
170+
lcd.print("FILL: ");
171+
lcd.print(currentFillPercent);
172+
lcd.print("% CRIT");
173+
} else if (isLidOpen) {
174+
lcd.setCursor(0, 0);
175+
lcd.print("LID: OPENING...");
176+
lcd.setCursor(0, 1);
177+
lcd.print("FILL: ");
178+
lcd.print(currentFillPercent);
179+
lcd.print("% READY");
180+
} else {
181+
lcd.setCursor(0, 0);
182+
lcd.print("SMART DUSTBIN");
183+
lcd.setCursor(0, 1);
184+
lcd.print("FILL: ");
185+
lcd.print(currentFillPercent);
186+
lcd.print("% NORMAL");
187+
}
188+
}
189+
190+
// ============================================================================
191+
// 9. TELEMETRY & SERIAL DIAGNOSTICS
192+
// ============================================================================
193+
void printTelemetry(unsigned long now) {
194+
if (now - lastSerialLogTime >= SERIAL_PRINT_INTERVAL_MS) {
195+
lastSerialLogTime = now;
196+
197+
Serial.print(F("[TELEMETRY] Hand: "));
198+
if (currentHandDistance < 0) Serial.print(F("NONE"));
199+
else { Serial.print(currentHandDistance, 1); Serial.print(F(" cm")); }
200+
201+
Serial.print(F(" | Waste Depth: "));
202+
if (currentWasteDistance < 0) Serial.print(F("ERR"));
203+
else { Serial.print(currentWasteDistance, 1); Serial.print(F(" cm")); }
204+
205+
Serial.print(F(" | Fill: "));
206+
Serial.print(currentFillPercent);
207+
Serial.print(F("% | Lid: "));
208+
Serial.print(isLidOpen ? F("OPEN ") : F("CLOSED "));
209+
210+
Serial.print(F(" | Status: "));
211+
Serial.println(isBinFull ? F("CRITICAL (FULL)") : F("NORMAL (READY)"));
212+
}
213+
}
214+
215+
// ============================================================================
216+
// 10. SETUP FUNCTION
217+
// ============================================================================
218+
void setup() {
219+
Serial.begin(9600);
220+
221+
pinMode(HAND_TRIG_PIN, OUTPUT);
222+
pinMode(HAND_ECHO_PIN, INPUT);
223+
pinMode(LEVEL_TRIG_PIN, OUTPUT);
224+
pinMode(LEVEL_ECHO_PIN, INPUT);
225+
226+
pinMode(BUZZER_PIN, OUTPUT);
227+
pinMode(GREEN_LED_PIN, OUTPUT);
228+
pinMode(RED_LED_PIN, OUTPUT);
229+
230+
digitalWrite(BUZZER_PIN, LOW);
231+
digitalWrite(GREEN_LED_PIN, HIGH);
232+
digitalWrite(RED_LED_PIN, LOW);
233+
234+
lidServo.attach(SERVO_PIN);
235+
closeLid();
236+
237+
// Initialize 16x2 I2C LCD
238+
lcd.init();
239+
lcd.backlight();
240+
lcd.clear();
241+
lcd.setCursor(0, 0);
242+
lcd.print("SMART DUSTBIN");
243+
lcd.setCursor(0, 1);
244+
lcd.print("INITIALIZING...");
245+
delay(1000);
246+
lcd.clear();
247+
248+
Serial.println();
249+
Serial.println(F("=========================================================="));
250+
Serial.println(F(" SMART DUSTBIN - EMBEDDED SYSTEM CONTROL PLATFORM"));
251+
Serial.println(F(" Architecture: Arduino UNO / ATmega328P + 16x2 I2C LCD"));
252+
Serial.println(F("=========================================================="));
253+
Serial.println(F("[SYS] System Initialized Successfully. Running main loop..."));
254+
}
255+
256+
// ============================================================================
257+
// 11. MAIN SUPER-LOOP (Non-Blocking Cooperative Scheduling)
258+
// ============================================================================
259+
void loop() {
260+
unsigned long now = millis();
261+
262+
if (now - lastHandReadTime >= HAND_SENSOR_INTERVAL_MS) {
263+
lastHandReadTime = now;
264+
currentHandDistance = readUltrasonicDistance(HAND_TRIG_PIN, HAND_ECHO_PIN);
265+
}
266+
267+
if (now - lastLevelReadTime >= LEVEL_SENSOR_INTERVAL_MS) {
268+
lastLevelReadTime = now;
269+
currentWasteDistance = readUltrasonicDistance(LEVEL_TRIG_PIN, LEVEL_ECHO_PIN);
270+
currentFillPercent = calculateFillPercentage(currentWasteDistance);
271+
isBinFull = (currentFillPercent >= FULL_LEVEL_PERCENT);
272+
}
273+
274+
if (!isBinFull) {
275+
if (currentHandDistance > 0.0f && currentHandDistance <= HAND_DETECTION_DISTANCE_CM) {
276+
openLid();
277+
}
278+
} else {
279+
if (isLidOpen) {
280+
closeLid();
281+
}
282+
}
283+
284+
if (isLidOpen && ((long)(now - lidAutoCloseTarget) >= 0)) {
285+
closeLid();
286+
}
287+
288+
updateAlertSystem(isBinFull);
289+
updateLCD(now);
290+
printTelemetry(now);
291+
}

circuit_diagram/architecture.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# System Architecture
2+
3+
```text
4+
USER
5+
|
6+
v
7+
+---------------+
8+
| Hand Sensor |
9+
| HC-SR04 |
10+
+-------+-------+
11+
|
12+
v
13+
+-------------+
14+
| Arduino UNO |
15+
| Control |
16+
| Logic |
17+
+------+------+
18+
|
19+
+----------+----------+
20+
| | |
21+
v v v
22+
Servo Level Alert
23+
Control Sensor System
24+
| | |
25+
v v +---+---+
26+
Lid Fill % LED Buzzer

circuit_diagram/pinout.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Pin Configuration
2+
3+
| Component | Signal | Arduino Pin |
4+
|---|---|---|
5+
| Hand HC-SR04 | TRIG | D9 |
6+
| Hand HC-SR04 | ECHO | D10 |
7+
| Level HC-SR04 | TRIG | D6 |
8+
| Level HC-SR04 | ECHO | D7 |
9+
| Servo | PWM | D5 |
10+
| Buzzer | Signal | D4 |
11+
| Green LED | Anode | D12 |
12+
| Red LED | Anode | D13 |

0 commit comments

Comments
 (0)