Tong Sampah Automatik RBT dengan Arduino, HC-SR04 dan Servo

Kartun tong sampah kelabu dengan penutup terbuka diangkat oleh servo biru lut sinar di engsel, dan sensor ultrasonik biru berpita hitam di hadapan tong mengesan tangan

Tong sampah automatik untuk projek RBT tingkatan 3 ialah tiga blok yang mudah: HC-SR04 mengukur jarak tangan, Arduino Uno membandingkan jarak itu dengan satu ambang, dan servo SG90 mengangkat penutup. Bahagian yang paling kerap gagal bukan kodnya β€” ia kuasa. Servo yang mengambil 5V terus dari Uno menyebabkan penutup bergegar dan board reset di tengah demo.

Apa yang perlu untuk membina tong sampah automatik ini?

Projek ini tidak perlu memateri langsung β€” semua sambungan dibuat dengan wayar jumper dan satu breadboard.

Parts list

ItemPriceQty
Electrical Insulation Tape 18mm x 10m PVC Color Coded Marking Red White Blue Yellow Green Black - ELECTRICAL TAPE (BLACK)Electrical Insulation Tape 18mm x 10m PVC Color Coded Marking Red White Blue Yellow Green Black - ELECTRICAL TAPE (BLACK)T1609BKRM1.90

Untuk melekatkan sensor dan servo pada badan tong, dan menebat sambungan wayar bateri. Mana-mana pita elektrik pun boleh.

Padanan hujung male dan female itulah yang menentukan sama ada binaan ini bebas pematerian. HC-SR04 keluar dengan empat pin male, jadi ia perlukan hujung female pada jumper M-F β€” hujung female itu juga menjadi wayar juntai supaya sensor boleh dipasang di hadapan tong. Wayar servo SG90 pula berakhir dengan satu penyambung hitam 3-lubang female, jadi pin male jumper M-M masuk ke dalamnya. Wayar bekas bateri pula jenis serabut dengan hujung terdedah: pintal ketat dan lipat dua hujungnya sebelum ditolak ke dalam rel breadboard, kalau tidak urat halusnya akan mengembang dan tercabut. Uno ini diprogram melalui port USB-B bersaiz penuh, jadi ambil kabel A-ke-B bersamanya; dalam Arduino IDE pilih board Arduino Uno dan port yang muncul apabila kabel dicucuk.

Macam mana HC-SR04, Arduino dan servo membentuk input–proses–output?

HC-SR04 ialah blok input. Denyut 10 mikrosaat pada pin Trig menyuruhnya melepaskan satu letusan bunyi 40kHz, kemudian ia menaikkan pin Echo dan menahannya tinggi selama tempoh perjalanan bunyi itu pergi dan balik. Kod tinggal mengukur lebar denyut itu. Bunyi bergerak kira-kira 343 meter sesaat, iaitu 0.0343cm setiap mikrosaat, dan kerana tempohnya meliputi perjalanan dua hala, jarak = tempoh Γ— 0.0343 Γ· 2. Suhu bilik yang lebih panas menaikkan laju bunyi kira-kira 2%, iaitu 0.3cm pada ambang 15cm β€” tidak penting di sini. Mekanik denyut selebihnya ada dalam panduan sensor ultrasonik HC-SR04 kami.

Papan HC-SR04 keluaran terkini kami mencetak label bergabung pada silkscreennya: Vcc, Trig_RX_SCL, Echo_TX_SDA, Gnd. Perkataan tambahan itu untuk mod komunikasi lain yang projek ini langsung tidak guna β€” layan pin kedua sebagai Trig dan pin ketiga sebagai Echo, seperti mana-mana HC-SR04 lain.

Servo SG90 pula blok output. Ia menerima denyut setiap 20 milisaat; lebar denyut itulah yang menetapkan sudut aci, bukan voltan dan bukan arus. Kerana kedudukan diminta sebagai sudut mutlak, servo 180Β° inilah yang betul untuk penutup tong β€” versi 360Β° ialah servo putaran berterusan yang hanya faham arah dan laju, dan tidak boleh menahan penutup pada satu sudut. Perbezaannya ada dalam panduan beza servo 180Β°, 270Β° dan 360Β°.

Di antara keduanya duduk blok proses β€” ambang, pengesahan bacaan dan pemasa tahan-buka β€” iaitu isi bahagian “proses” dalam folio RBT anda.

Rajah kartun tiga panel menunjukkan sensor ultrasonik biru mengesan tangan, lengkung teal melintasi garis ambang putus-putus dengan satu pemasa, dan servo biru lut sinar mengangkat penutup kelabu
Input, proses, output: jarak menjadi nombor, nombor melintasi satu ambang dan memulakan satu pemasa, dan pemasa itu menentukan berapa lama penutup kekal terangkat.

Kenapa penutup bergegar dan Uno reset bila servo dikuasakan dari pin 5V?

Servo SG90 mengandungi motor DC berus biasa dengan kotak gear. Pada saat ia mula bergerak β€” dan lebih teruk lagi apabila penutup tersangkut β€” rotornya belum berputar, jadi tiada daya gerak elektrik balikan yang menentang bekalan, dan arus yang mengalir ditentukan oleh rintangan gegelung sahaja. Itulah lonjakan: beratus miliampere dalam sekelip mata, jauh lebih tinggi daripada arus mantapnya.

Lihat dari mana lonjakan itu perlu datang. Port USB komputer dikadarkan 500mA, dan kuasa USB masuk ke papan Uno R3 melalui satu polyfuse 500mA β€” bukan suis, tetapi perintang yang memanas dan naik rintangannya apabila arus naik, jadi kesan pertamanya bukan pemutusan tetapi kejatuhan voltan. Board kosong sudah makan lebih kurang 50mA dan HC-SR04 kira-kira 15mA lagi, jadi bakinya tidak sampai setengah ampere β€” dan bersama rintangan kabel USB, setiap lonjakan servo menjatuhkan voltan rel sebelum ia sempat sampai ke papan.

Kejatuhan voltan itulah yang menghasilkan gegaran. Tetapi bukan kerana servo tersalah baca kedudukannya. Cip pengawal di dalam servo analog seperti SG90 mempunyai pengatur voltan terbina yang membekalkan rujukan untuk potentiometer maklum balasnya sendiri, dan rujukan itu direka supaya kekal stabil walaupun voltan bekalan turun naik; kedudukan aci pula dibaca sebagai rintangan yang ditukar menjadi tempoh denyut, bukan sebagai voltan mentah. Jadi servo bukan keliru β€” ia kebuluran. Rel yang merudum bermakna tork yang lemah, jadi aci tidak sampai ke sudut yang diminta, ralat kekal terbuka, litar kawalan terus memacu motor, dan motor terus menarik arus. Setiap denyut 20 milisaat dibandingkan semula di atas rel yang bergoyang dan penuh bunyi berus motor, jadi arah pacuan bertukar-tukar β€” itulah dengungan serta gegaran yang anda dengar. Bacaan HC-SR04 pada rel yang sama turut bergoyang, dan jika polyfuse akhirnya terputus, Uno hilang kuasa sepenuhnya lalu bermula semula.

Penyelesaiannya ialah memisahkan kuasa, bukan menurunkan sudut atau melambatkan kod. Beri servo bekalannya sendiri: empat bateri AA dalam bekas bateri (empat sel bersiri, lebih kurang 6V, dengan suis ON/OFF terbina) masuk ke rel kuasa breadboard, dan wayar merah serta coklat servo mengambil dari rel itu. Arus servo tidak lagi melalui Uno langsung.

Satu wayar lagi tidak boleh ditinggalkan: GND bateri mesti disambung ke GND Uno. Isyarat pada wayar oren servo ialah voltan, dan voltan hanya bermakna berbanding satu titik rujukan. Jika 0V servo dan 0V Uno tidak bertemu di mana-mana, “denyut 5V” yang dihantar Arduino tiada rujukan bersama di hujung servo, dan servo akan mengabaikannya atau berkedut rambang. Menyambungkan dua GND itu memberi kedua-dua belah takrifan sifar yang sama.

Jangan masukkan pek 6V yang sama ke pin VIN Uno. Spesifikasi papan ini ialah input disyorkan 7–12V, kerana pengatur voltan di atasnya perlukan lebihan voltan untuk bekerja; pada 6V ia berada di dasar julat dan rel 5V akan merudum apabila bateri semakin lemah. Jangan pula masukkannya ke pin 5V sebagai jalan pintas: pin itu memintas pengatur voltan dan pergi terus ke kaki VCC ATmega328P, yang had mutlaknya 6.0V β€” di bawah voltan pek alkali yang baharu. Kuasakan Uno melalui USB β€” laptop semasa memuat naik kod, atau power bank melalui kabel A-ke-B untuk demo berdiri sendiri. Empat bateri alkali baharu pula membaca lebih kurang 6.2–6.4V tanpa beban, sedikit di atas julat 4.8–6V servo; voltan itu jatuh masuk ke dalam julat sebaik motor mula menarik arus β€” sebabnya amalan 4Γ—AA berjalan di setiap meja RBT. Untuk kekal dalam julat terarah sepanjang masa, empat bateri NiMH boleh cas semula (4 Γ— 1.2V = 4.8V) ialah pilihan mengikut buku.

Rajah kartun dua pulau kuasa berasingan, papan Arduino biru berkuasa USB dan bekas bateri AA hitam yang menyuap breadboard putih serta servo biru lut sinar, dihubungkan oleh satu wayar GND hitam tebal yang bercahaya
Dua pulau kuasa yang berasingan β€” Uno dari USB, servo dari 4 bateri AA β€” disatukan oleh satu wayar GND sepunya. Tanpa wayar tebal itu, isyarat oren tiada makna.

Macam mana nak sambung litarnya?

Cabut USB dan matikan suis pek AA sebelum menyambung apa-apa. Baris terakhir jadual ini β€” GND sepunya β€” yang paling kerap tertinggal.

Dari Ke Kenapa
HC-SR04 Vcc (pin hujung) Uno 5V Kira-kira 15mA sahaja β€” selamat pada rel USB
HC-SR04 Trig (pin kedua) Uno D7 Uno menghantar denyut cetus 10 Β΅s
HC-SR04 Echo (pin ketiga) Uno D6 Lebar denyut = tempoh perjalanan bunyi
HC-SR04 Gnd (pin hujung satu lagi) Uno GND Rujukan sifar untuk isyarat Echo
Servo wayar oren Uno D9 Denyut kedudukan 50 Hz; arus di sini hampir sifar
Servo wayar merah Rel + breadboard Arus motor datang dari bateri, bukan dari Uno
Servo wayar coklat Rel βˆ’ breadboard Laluan balik motor
Bekas bateri wayar merah Rel + breadboard Lebih kurang 6V daripada empat sel bersiri
Bekas bateri wayar hitam Rel βˆ’ breadboard Melengkapkan litar bateri
Uno GND (pin GND kedua) Rel βˆ’ breadboard GND sepunya β€” tanpa ini servo berkedut atau langsung diam

Macam mana coding tong sampah automatik ini berfungsi?

Tiga keputusan reka bentuk menjadikan penutup ini stabil. Ambang menukar nombor mentah kepada keputusan ya/tidak. Pengesahan dua bacaan berturut membuang satu bacaan sesat: gema yang terpantul dari tepi tong kadangkala pulang awal dan menghasilkan satu nombor kecil palsu. Pemasa tahan-buka pula memisahkan “masa penutup terbuka” daripada “tangan masih ada”, supaya penutup tidak terhempas pada tangan yang masih melayang, dan tidak pula terbuka-tutup berulang kali ketika tangan berada betul-betul di garis ambang.

Tiada delay() di dalam loop(), jadi sensor terus membaca sepanjang tempoh penutup terbuka β€” itulah yang membolehkan setiap pengesanan baharu menyegarkan pemasa. Sketch ini menggunakan 4,738 bait, iaitu 14% memori program Uno.

// Tong sampah automatik - HC-SR04 + servo SG90 pada Arduino Uno.
// Tiada delay() dalam loop(), jadi sensor terus membaca semasa tutup terbuka.

#include <Servo.h>

const uint8_t TRIG_PIN  = 7;   // HC-SR04 Trig
const uint8_t ECHO_PIN  = 6;   // HC-SR04 Echo
const uint8_t SERVO_PIN = 9;   // wayar oren servo (isyarat)

const int SUDUT_TUTUP = 10;    // laraskan ikut lengan tuas anda
const int SUDUT_BUKA  = 90;

const long          AMBANG_CM    = 15;      // tangan lebih dekat daripada ini = buka
const uint8_t       SAH_BERTURUT = 2;       // dua bacaan berturut sebelum percaya
const unsigned long SELANG_PING  = 60UL;    // jeda antara ping (echo lama perlu reda)
const unsigned long MASA_TAHAN   = 3000UL;  // tutup kekal buka selepas kesan terakhir
const unsigned long MASA_GERAK   = 600UL;   // masa servo habiskan pergerakan
const unsigned long HAD_ECHO_US  = 25000UL; // henti tunggu echo selepas ~4.2 m

Servo servoTutup;

bool tutupTerbuka  = false;
bool servoAktif    = false;
uint8_t kiraDekat  = 0;

unsigned long pingTerakhir  = 0;
unsigned long kesanTerakhir = 0;
unsigned long mulaGerak     = 0;

// Hantar satu burst dan ukur berapa lama echo mengambil masa untuk balik.
// Pulangan -1 bermakna tiada echo langsung dalam had masa (jalan kosong).
long bacaJarakCm() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);          // denyut cetus 10 us yang diminta modul
  digitalWrite(TRIG_PIN, LOW);

  unsigned long tempoh = pulseIn(ECHO_PIN, HIGH, HAD_ECHO_US);
  if (tempoh == 0) return -1;

  // Bunyi bergerak ~343 m/s = 0.0343 cm setiap us, dan tempoh itu
  // meliputi perjalanan pergi DAN balik, jadi bahagi dua.
  return (long)(tempoh * 0.0343 / 2.0);
}

// Servo hanya di-attach semasa ia perlu bergerak, supaya ia tidak
// berdengung dan menyedut arus sepanjang masa tutup sedang rapat.
void gerakTutup(int sudut) {
  if (!servoAktif) {
    servoTutup.attach(SERVO_PIN);
    servoAktif = true;
  }
  servoTutup.write(sudut);
  mulaGerak = millis();
}

void setup() {
  Serial.begin(9600);

  pinMode(TRIG_PIN, OUTPUT);
  digitalWrite(TRIG_PIN, LOW);
  pinMode(ECHO_PIN, INPUT);

  gerakTutup(SUDUT_TUTUP);        // mula dalam keadaan tertutup
  delay(MASA_GERAK);
  servoTutup.detach();
  servoAktif = false;

  Serial.println(F("Tong sampah automatik sedia."));
}

void loop() {
  unsigned long kini = millis();

  // 1. INPUT - satu ping setiap SELANG_PING milisaat.
  if (kini - pingTerakhir >= SELANG_PING) {
    pingTerakhir = kini;
    long jarak = bacaJarakCm();

    if (jarak > 0 && jarak <= AMBANG_CM) {
      if (kiraDekat < SAH_BERTURUT) kiraDekat++;
    } else {
      kiraDekat = 0;              // satu bacaan jauh membatalkan kiraan
    }

    // 2. PROSES - keputusan dibuat hanya selepas bacaan disahkan.
    if (kiraDekat >= SAH_BERTURUT) {
      kesanTerakhir = kini;       // setiap pengesahan menyegarkan pemasa tahan

      if (!tutupTerbuka) {
        tutupTerbuka = true;
        gerakTutup(SUDUT_BUKA);   // 3. OUTPUT
        Serial.print(F("Buka pada "));
        Serial.print(jarak);
        Serial.println(F(" cm"));
      }
    }
  }

  // Tutup semula hanya apabila tiada pengesahan selama MASA_TAHAN penuh.
  // Menolak dua unsigned long kekal betul walaupun millis() pusing semula.
  if (tutupTerbuka && (kini - kesanTerakhir >= MASA_TAHAN)) {
    tutupTerbuka = false;
    kiraDekat = 0;
    gerakTutup(SUDUT_TUTUP);
    Serial.println(F("Tutup"));
  }

  // Lepaskan servo selepas tutup sampai ke tempatnya.
  if (servoAktif && !tutupTerbuka && (kini - mulaGerak >= MASA_GERAK)) {
    servoTutup.detach();
    servoAktif = false;
  }
}

Jeda 60 milisaat antara ping bukan angka cantik: gema letusan sebelumnya masih melantun di dalam bilik, dan jika anda mencetus terlalu awal, gema lama itu masuk sebagai bacaan baharu. Panggilan detach() selepas penutup rapat pula menghentikan denyut ke servo β€” graviti yang menahan penutup, jadi motor tidak perlu berdengung dan menyedut arus bateri sepanjang masa menunggu.

Macam mana nak pasang servo dan sensor pada tong sebenar?

Servo SG90 memberi tork terkadar 1.3kgΒ·cm pada 4.8V. Tork ialah daya darab jejari, jadi pada lengan sepanjang 2cm dari aci ia mampu menolak kira-kira 0.65kg β€” lebih daripada cukup untuk penutup plastik ringan, dan sebabnya lengan yang terlalu panjang menjadi lemah.

Kami menjual servo ini sebagai unit servo sahaja β€” horn dan skru bukan sebahagian tawaran, jadi buat lengan sendiri daripada kayu aiskrim atau jalur plastik keras: tebuk lubang sedikit lebih kecil daripada aci berspline, tekan masuk supaya spline menggigit, dan balut pita elektrik pada boss supaya lengan tidak terkeluar. Muat naik kod dahulu, pasang lengan kemudian β€” sketch menggerakkan servo ke SUDUT_TUTUP sebaik ia hidup, jadi pasang lengan ketika penutup dalam kedudukan rapat; jika tidak, servo akan menolak penutup yang sudah tertutup, iaitu keadaan tersekat yang menghasilkan lonjakan arus tadi. Sambung lengan ke penutup dengan klip kertas lurus yang hujungnya dibengkok jadi gelung kecil β€” rod mesti boleh berpusing, kerana hujung mati akan mengunci dan menyekat servo. Pasang servo dekat engsel; jika ia berdengung di hujung ayunan, kurangkan SUDUT_BUKA.

Kedudukan sensor menentukan sama ada penutup akan menutup semula langsung. Pasangkan HC-SR04 pada muka hadapan tong menghadap keluar, kira-kira pada paras tangan, dan pastikan ia tidak melihat penutupnya sendiri semasa penutup terangkat. Lekatkan pita elektrik pada tepi papan sensor sahaja; jangan sesekali menutup muka jaring kedua-dua silinder perak itu, kerana di situlah bunyi keluar dan masuk.

Melihat lengan dan sensor benar-benar dipasang pada tong membantu di sini:

Kartun keratan sisi tong sampah kelabu menunjukkan servo biru lut sinar berpita hitam di engsel dengan rod klip kertas ke penutup, dan sensor ultrasonik biru di hadapan tong dengan kon teal yang tidak bertindih dengan lengkok penutup
Servo pada engsel dengan klip kertas lurus sebagai tuas, dan sensor di hadapan tong dengan kon pengesanannya jauh di bawah lengkok ayunan penutup.

Kesilapan biasa yang kami lihat

Servo disambung ke pin 5V Uno. Punca nombor satu bagi penutup bergegar, bacaan melompat dan board reset sendiri. Pisahkan kuasa, sambung GND sepunya.

Sensor terarah ke penutupnya sendiri. Sebaik penutup naik, ia masuk ke dalam kon pengesanan, sensor membaca jarak dekat tanpa henti, dan penutup kekal terbuka selama-lamanya. Buka Serial Monitor: jika bacaan kekal kecil sedangkan tiada tangan, inilah puncanya.

Menggunakan delay(3000) sebagai masa tahan. Sepanjang tiga saat itu Arduino buta β€” ia tidak nampak tangan yang datang semula, jadi penutup turun tepat ke atas tangan pengguna. Pemasa millis() menyelesaikannya.

Membeli servo 360Β°. Ia berputar, bukan menuju sudut, jadi penutup tidak akan pernah berhenti di kedudukan yang betul. Pastikan pilihan 180Β° semasa membeli.

Soalan lazim

Berapa jarak ambang yang sesuai untuk tong sampah automatik?

15cm ialah titik permulaan yang baik. HC-SR04 tidak boleh mengukur lebih dekat daripada 2cm, jadi ambang yang terlalu kecil hampir mustahil dicapai; ambang yang terlalu besar pula membuka penutup setiap kali seseorang melintas. Ubah AMBANG_CM sambil memerhati Serial Monitor.

Kenapa penutup saya terbuka dan tertutup berulang kali?

Tangan berada betul-betul di garis ambang, jadi bacaan berselang-seli antara di dalam dan di luar julat. Pemasa MASA_TAHAN dan kiraan SAH_BERTURUT dalam sketch ini memang wujud untuk itu; naikkan MASA_TAHAN jika ia masih berlaku.

Boleh guna empat bateri AA untuk kuasakan Arduino juga?

Tidak melalui pin VIN. Input disyorkan Uno ialah 7–12V dan 6V berada di bawah paras itu, jadi rel 5V akan merudum apabila bateri melemah. Kuasakan Uno melalui USB dan biarkan pek AA menguasakan servo sahaja.

Perlukah library tambahan untuk HC-SR04?

Tidak untuk HC-SR04 β€” pulseIn() sudah terbina dalam Arduino. Library Servo pula library rasmi Arduino sendiri; kalau IDE anda melaporkan Servo.h: No such file or directory, buka Library Manager, cari Servo, dan pasangnya sekali sahaja.

Sesuaikah projek ini untuk folio RBT tingkatan 3?

Ya β€” strukturnya memang input–proses–output, dan setiap blok boleh ditunjukkan berasingan. Untuk idea projek lain dengan bentuk yang sama, lihat senarai projek elektronik RBT kami.

Kemas kini terakhir Ogos 2026. Tersangkut? Chat dengan kami di WhatsApp.

Leave a Reply

Your email address will not be published. Required fields are marked *