Thùng rác thông minh tự mở nắp khi đưa tay lại gần
Đưa tay (hoặc túi rác) cách miệng thùng dưới 20cm thì nắp tự mở bằng động cơ servo, rút tay ra 3 giây thì tự đóng. Không phải chạm tay, hợp vệ sinh cho bếp, phòng khám, lớp học. Lắp được cho thùng rác nắp lật cỡ nhỏ và vừa (nắp nhẹ dưới 200g).
✅ Đã kiểm thử
Xem chi tiết 3 phép đo
Đang mở nắp (servo chạy, cảm biến đang đo)
- Tổng dòng đỉnh 695.1mA: dùng cục sạc điện thoại 5V ≥1A, cổng USB máy tính có thể không đủ.
- Mức tín hiệu điều khiển servo (cần ≥ 2V): 5.00V ✓
- Áp chân ECHO vào D8: 5.00V ✓
- Dòng chân D9 cấp cho dây tín hiệu servo: 0.0mA ✓
- Tổng dòng đỉnh 695.1mA: dùng cục sạc điện thoại 5V ≥1A, cổng USB máy tính có thể không đủ.
Nguyên lý hoạt động
Cảm biến siêu âm HC-SR04 gắn ở mặt trước nắp, đo khoảng cách tới tay mỗi 60ms (lọc trung vị 3 lần đo). Khi dưới 20cm, Arduino xuất xung điều khiển 50Hz vào dây cam của servo để quay cần tới góc mở (mặc định 100°). Khi tay đã rút ra 3 giây, servo quay từ từ về góc đóng rồi ngắt xung để servo không rung và đỡ tốn điện. Servo lúc khởi động ăn tới khoảng 650mA trong tích tắc, nên có tụ 470µF đặt sát chân nguồn servo để Arduino không bị sụt áp khởi động lại; tổng dòng đỉnh khoảng 0,7A nên dùng cục sạc 5V từ 1A trở lên.
Sơ đồ đấu dây
Mỗi màu là một dây. Chấm tròn là điểm hàn. Chạm vào tên dây trong bảng để làm nổi bật.
| # | Dây | Nối các điểm |
|---|---|---|
| 1 | đỏ 5V | U1 5V ⟷ U2 VCC ⟷ M1 VCC · dây đỏ ⟷ C1 + |
| 2 | đen GND | U1 GND ⟷ U2 GND ⟷ M1 GND · dây nâu ⟷ C1 - |
| 3 | vàng TRIG | U1 D7 ⟷ U2 TRIG |
| 4 | xanh lá ECHO | U2 ECHO ⟷ U1 D8 |
| 5 | xanh dương SERVO_SIG | U1 D9 ⟷ M1 SIG · dây cam |
Danh sách linh kiện
| Ký hiệu | Linh kiện | Giá tham khảo | |
|---|---|---|---|
| U1 | Arduino Nano V3 (ATmega328P, chip nạp CH340) | 85.000đ | Tìm mua |
| U2 | Cảm biến siêu âm HC-SR04 | 20.000đ | Tìm mua |
| M1 | Động cơ servo SG90 (nắp nặng 150–300g thì đổi MG90S bánh răng kim loại, cùng chân) | 30.000đ | Tìm mua |
| C1 | Tụ hóa 470µF 10V hoặc 16V (470u) | 2.000đ | Tìm mua |
| Tổng (chưa gồm board hàn, dây, thiếc) | 137.000đ |
Các bước làm
Code nạp cho mạch
Cài thư viện: Servo (Arduino IDE → Library Manager). Chọn board Arduino Nano.
/*
Mạch Gọn — Thùng rác tự mở nắp
Board : Arduino Nano (ATmega328P)
Chân : D7 -> TRIG, D8 <- ECHO (HC-SR04)
D9 -> dây cam servo SG90 (đỏ 5V, nâu GND), tụ 470µF sát nguồn servo
Thư viện: Servo (có sẵn trong Arduino IDE)
*/
#include <Arduino.h>
#include <Servo.h>
// ----- Cấu hình -----
const uint8_t PIN_TRIG = 7, PIN_ECHO = 8, PIN_SERVO = 9;
const int ANGLE_CLOSED = 0; // góc nắp đóng (độ)
const int ANGLE_OPEN = 100; // góc nắp mở (độ)
const int OPEN_CM = 20; // đưa tay gần hơn khoảng này thì mở
const uint32_t HOLD_MS = 3000; // rút tay bao lâu thì đóng
const uint8_t CLOSE_STEP_MS = 12; // đóng từ từ: mỗi độ 12ms
Servo lid;
bool isOpen = false;
uint32_t lastSeen = 0;
int angleNow = ANGLE_CLOSED;
int measureOnce() {
digitalWrite(PIN_TRIG, LOW); delayMicroseconds(3);
digitalWrite(PIN_TRIG, HIGH); delayMicroseconds(10);
digitalWrite(PIN_TRIG, LOW);
unsigned long us = pulseIn(PIN_ECHO, HIGH, 20000UL); // tối đa ~3,4m
if (us == 0) return -1;
int cm = (int)(us * 0.0343 / 2.0 + 0.5);
return cm >= 2 ? cm : -1;
}
int measureMedian3() {
int a = measureOnce(); delay(10);
int b = measureOnce(); delay(10);
int c = measureOnce();
// lần nào không đo được coi như rất xa
if (a < 0) a = 999; if (b < 0) b = 999; if (c < 0) c = 999;
return max(min(a, b), min(max(a, b), c));
}
void moveTo(int target, uint8_t stepMs) {
if (!lid.attached()) lid.attach(PIN_SERVO);
int dir = target > angleNow ? 1 : -1;
if (stepMs == 0) { angleNow = target; lid.write(target); delay(350); return; }
while (angleNow != target) { angleNow += dir; lid.write(angleNow); delay(stepMs); }
delay(150);
}
void setup() {
Serial.begin(9600);
pinMode(PIN_TRIG, OUTPUT);
pinMode(PIN_ECHO, INPUT);
lid.attach(PIN_SERVO);
lid.write(ANGLE_CLOSED); // về góc đóng lúc bật điện (dùng để lắp cần)
delay(600);
lid.detach(); // ngắt xung: servo không rung, đỡ tốn điện
Serial.println(F("Thung rac thong minh san sang"));
}
void loop() {
int cm = measureMedian3();
uint32_t now = millis();
bool near = cm <= OPEN_CM;
if (near) {
lastSeen = now;
if (!isOpen) {
Serial.print(F("Tay cach ")); Serial.print(cm); Serial.println(F(" cm -> MO NAP"));
moveTo(ANGLE_OPEN, 0); // mở nhanh
isOpen = true;
}
} else if (isOpen && now - lastSeen >= HOLD_MS) {
Serial.println(F("DONG NAP"));
moveTo(ANGLE_CLOSED, CLOSE_STEP_MS); // đóng từ từ, êm
lid.detach();
isOpen = false;
}
static uint32_t lastLog = 0;
if (now - lastLog > 1000) { lastLog = now; Serial.print(F("Khoang cach: ")); Serial.print(cm >= 999 ? -1 : cm); Serial.println(F(" cm")); }
delay(40);
}
Đo kiểm bằng đồng hồ vạn năng
| Giữa dây đỏ và dây nâu của servo | 4,7 – 5,1V (không sụt dưới 4,5V lúc servo quay) |
| Serial Monitor khi đưa tay cách 15cm | Báo khoảng 15cm và "MO NAP" |
| Rút tay ra | Sau 3 giây nắp tự đóng từ từ |
Sửa lỗi thường gặp
Servo giật giật, Arduino tự khởi động lại
Nguồn yếu: dùng cục sạc ≥1A, dây USB ngắn tốt; kiểm tra tụ 470µF đã hàn đúng chiều và sát servo.
Nắp không mở nổi
Nắp quá nặng hoặc cần đẩy quá gần bản lề: dời điểm đẩy xa bản lề hơn, hoặc đổi sang servo MG90S.
Tự mở khi không có ai
Cảm biến dội vào thành thùng/tường: nghiêng cảm biến lên một chút hoặc giảm OPEN_CM xuống 15.
Servo kêu rè ở vị trí đóng
Code đã ngắt xung sau khi đóng; nếu vẫn kêu, chỉnh ANGLE_CLOSED lệch 3–5° để servo không bị kẹt vào nắp.
⚠️ An toàn
- Mạch 5V an toàn; để xa nước, đặt board trong hộp kín.
- Không để ngón tay vào khe bản lề khi nắp đang đóng.