🌱 Makmal Arduino Maya
Bengkel 2 Hari · Sekolah Menengah

Kebun Pintar Sekolah

Elektronik, ESP32 dan IoT, dibina bersama Gemini: dari pin pertama hingga papan pemuka di awan.
Nurul dan Aiman di sebelah kebun mini dengan ESP32, sensor dan pam air

15 tahun ke atas2 hari × 4.5 jamESP32GeminiIoT · MQTT

🧕🏻
Nurul dan Aiman ahli Kelab STEM. Kebun sayur sekolah selalu layu semasa cuti hujung minggu kerana tiada siapa menyiram. Cikgu mencabar mereka: bina kebun yang boleh menjaga dirinya sendiri, dan laporkan keadaannya ke telefon.

Dalam dua hari, kamu akan belajar menjadi jurutera yang mengarah AI: kamu tentukan perkakasan, keperluan dan ujian. Gemini menulis kod. Kamu menyemak, menguji dan bertanggungjawab ke atas hasilnya.

Tekan Seterusnya › atau kekunci anak panah untuk bertukar halaman. Perkataan bergaris titik seperti sistem terbenam boleh ditekan untuk melihat maksudnya.

Peta bengkel

Dua hari, satu kebun

HariBahagianSoalan yang dijawabMasa
11 Sistem terbenamApakah ESP32 dan bagaimana ia berfikir?25 min
12 Elektrik asasBerapa ohm perintang untuk LED, dan kenapa?40 min
13 Digital, analog, PWMBagaimana membaca sensor dan memalapkan lampu?45 min
14 Sensor & aktuatorApa yang kebun perlukan, dan di pin mana?40 min
15 Kejuruteraan promptBagaimana menulis spesifikasi yang Gemini tidak boleh salah faham?60 min
16 Aliran kerja MakmalBagaimana membina, menjalankan dan membaca ralat?40 min
27 Menyemak kod AIKod berjalan, tetapi betulkah ia?45 min
28 NyahpepijatBagaimana mencari punca masalah dengan sistematik?30 min
29 IoT: Wi-Fi, HTTP, MQTTBagaimana kebun melapor ke telefon?60 min
210 AI secara bertanggungjawabApa tanggungjawab kita apabila AI menulis kod?15 min
211 Projek akhirBolehkah pasukan kamu membina Kebun Pintar?2 jam

Masa ialah anggaran tanpa rehat. Cikgu boleh mengubah suai mengikut kelas.

Bahagian 1 · Sistem terbenam

Komputer yang tersembunyi di mana-mana

Telefon kamu ada pemproses berbilang teras. Tetapi pengawal penyaman udara, mesin basuh dan lampu isyarat hanya perlukan komputer kecil yang murah dan jimat tenaga: mikropengawal.

Input

Sensor mengukur dunia: suhu, kelembapan tanah, cahaya, butang.

Proses

Kod membuat keputusan: “jika tanah kering, siram”.

Output

Aktuator bertindak: pam air, LED, paparan LCD, mesej Wi-Fi.

Arduino UnoESP32 DevKit
Pemproses8-bit, 16 MHz32-bit dwi-teras, 240 MHz
Voltan logik5 V3.3 V
Analog (ADC)10-bit (0 hingga 1023)12-bit (0 hingga 4095)
Wi-Fi / BluetoothTiadaAda

Untuk kebun yang melapor ke telefon, kita pilih ESP32.

Bahagian 1 · Sistem terbenam

Bagaimana program Arduino berjalan

Setiap program Arduino (dipanggil sketch) ada dua bahagian wajib:

void setup() {
  // berjalan SEKALI semasa papan dihidupkan
  // contoh: tetapkan pin, mulakan Serial, sambung Wi-Fi
}

void loop() {
  // berjalan BERULANG-ULANG selama-lamanya, beribu kali sesaat
  // contoh: baca sensor, buat keputusan, kawal pam
}

Kamu tidak perlu menulis kod ini sendiri hari ini, tetapi kamu mesti boleh membacanya untuk menyemak kerja Gemini.

Aktiviti 1 · Semak kefahaman
ESP32 bekerja pada 3.3 V. Bagaimana kita memastikan arus yang mengalir ke LED dan sensor selamat?
Bahagian 2 · Elektrik asas

Voltan, arus dan rintangan

Aiman mengukur perintang dengan multimeter

Bayangkan paip air di kebun:

Ketiga-tiganya dihubungkan oleh Hukum Ohm:

V = I × RI = VRR = VIV dalam volt, I dalam ampere, R dalam ohm
Had keselamatan pin ESP32: pastikan arus setiap pin sekitar 10 hingga 20 mA. Pin tidak boleh membekalkan arus besar seperti untuk motor atau pam. Untuk itu kita guna geganti (relay) atau pemacu motor.
Bahagian 2 · Elektrik asas

Mengira perintang untuk LED

LED “memakan” sebahagian voltan, dipanggil voltan hadapan (Vf). Baki voltan jatuh pada perintang:

R = Vbekalan − VfILED merah Vf ≈ 2.0 V · biru/putih ≈ 3.0 V

Contoh: ESP32 (3.3 V), LED merah (2.0 V), arus 10 mA = 0.010 A:

R = 3.3 − 2.00.010 = 1.30.010 = 130 Ω

Perintang dijual dalam nilai piawai. Kita pilih nilai piawai yang sama atau lebih besar: 150 Ω atau 220 Ω (arus lebih kecil, lebih selamat, LED masih cukup terang).

Aktiviti 2 · Kalkulator perintang

Kira perintang untuk setiap kes. Tunjukkan jalan kira sebagai pecahan.

BekalanLEDArusR dikiraNilai piawai dipilih
5 VMerah (2.0 V)15 mA
3.3 VHijau (2.2 V)5 mA
5 VBiru (3.0 V)10 mA
LED boleh dihidupkan dan dimatikan. Tetapi bagaimana dengan membaca kelembapan tanah, atau memalapkan lampu?
Bahagian 3 · Digital, analog, PWM

Isyarat digital dan perintang tarik-naik

Isyarat digital hanya ada dua keadaan: HIGH (3.3 V) atau LOW (0 V). Butang ialah input digital.

Pin input yang tidak disambung ke mana-mana akan “terapung” dan membaca nilai rawak. Penyelesaiannya ialah perintang tarik-naik. ESP32 ada satu di dalamnya:

pinMode(BUTANG, INPUT_PULLUP);   // butang antara pin dan GND
if (digitalRead(BUTANG) == LOW) { /* ditekan */ }
Lantunan (bounce): apabila butang ditekan, logam di dalamnya melantun beberapa milisaat, jadi satu tekanan boleh dibaca sebagai 5 tekanan! Minta Gemini menambah nyahlantun (debounce) sekitar 50 ms.
Bahagian 3 · Digital, analog, PWM

Isyarat analog: membaca nilai di antara

Sensor kelembapan tanah dan sensor cahaya memberi voltan di antara 0 dan 3.3 V. ADC menukar voltan itu kepada nombor:

bacaan = Vmasuk3.3 V × 4095V = bacaan4095 × 3.3 VESP32, ADC 12-bit
Aktiviti 3 · Penukar ADC

Gerakkan peluncur untuk menukar voltan sensor.

Vmasuk = 1.65 V → analogRead() = 2048

Penting untuk IoT: apabila Wi-Fi digunakan, pin ADC2 (contohnya GPIO 25, 26, 27) tidak boleh membaca analog. Guna pin ADC1: GPIO 32, 33, 34, 35, 36, 39 untuk sensor analog.
Bahagian 3 · Digital, analog, PWM

PWM: “analog palsu” untuk memalapkan

Nurul memusing potensiometer, tiga LED makin terang

Pin digital hanya boleh HIGH atau LOW. Untuk memalapkan LED atau mengawal kelajuan kipas, kita tukar HIGH dan LOW dengan sangat laju. Peratus masa HIGH dipanggil kitar tugas (duty cycle).

kitar tugas = masa HIGHtempoh × 100%nilai 8-bit = kitar tugas100% × 255
Aktiviti 4 · Lihat PWM

Kitar tugas 25% → nilai ledcWrite(..., 64)  

Dalam ESP32 core 2.0.17: ledcSetup(saluran, frekuensi, resolusi) dan ledcAttachPin(pin, saluran), kemudian ledcWrite(saluran, nilai). Nyatakan versi core dalam prompt supaya Gemini guna fungsi yang betul.

Kita tahu jenis-jenis isyarat. Sekarang, komponen apa yang kebun perlukan, dan di pin mana?
Bahagian 4 · Sensor & aktuator

Komponen Kebun Pintar

Barisan modul sensor dan aktuator
KomponenJenisSambunganDalam Wokwi
🌡️ DHT22 suhu & kelembapan udaraINPUT digitalVCC 3V3, GND, SDA → GPIO 15wokwi-dht22
💧 Sensor kelembapan tanahINPUT analogAO → GPIO 34Ganti dengan potensiometer (Wokwi tiada sensor tanah)
☀️ Modul LDR (cahaya)INPUT analogAO → GPIO 35wokwi-photoresistor-sensor
🔘 Butang siram manualINPUT digitalGPIO 4 ↔ GND, INPUT_PULLUPwokwi-pushbutton
⚡ Modul geganti (pam)OUTPUTIN → GPIO 26wokwi-relay-module
📟 LCD 16×2 I2COUTPUT I2CSDA → GPIO 21, SCL → GPIO 22, alamat 0x27wokwi-lcd1602 (pins: i2c)
🔔 Buzzer amaranOUTPUT+ → GPIO 25wokwi-buzzer
Bahagian 4 · Sensor & aktuator

Geganti dan I2C

⚡ Geganti (relay)

Suis yang dikawal elektrik. Pin ESP32 yang lemah menghidupkan suis, dan suis itu menyambungkan bekalan pam yang lebih kuat.

Keselamatan: dalam bengkel, kita hanya guna pam kecil 5 V hingga 12 V. Jangan sekali-kali menyambung bekalan elektrik rumah (240 V) tanpa pengawasan juruteknik bertauliah.

📟 I2C: dua wayar, banyak peranti

I2C menggunakan dua wayar sahaja: SDA (data) dan SCL (jam). Banyak peranti boleh berkongsi dua wayar ini kerana setiap satu ada alamat (contohnya LCD = 0x27).

Pada ESP32: SDA = GPIO 21, SCL = GPIO 22. Jangan guna pin ini untuk benda lain.

Nurul dan Aiman melihat paparan LCD di kebun
Bahagian 4 · Sensor & aktuator

Aktiviti: Pelan Pin kebun

Jurutera tidak menyambung wayar secara rawak. Mereka menulis Pelan Pin dahulu, iaitu satu jadual yang menjadi kontrak antara litar, prompt dan kod.

Aktiviti 5 · Pelan Pin ESP32

Pilih komponen dan pin. Halaman ini menyemak pin bertindih, pin yang dilarang, dan pin ADC2 yang tidak boleh digunakan bersama Wi-Fi. Pelan disimpan untuk Pembina Spesifikasi.

Guna?KomponenPin
KomponenPinJenisNota (voltan, alamat, ADC1?)
DHT22
Sensor tanah (potensiometer)
LDR
Butang siram
Geganti pam
LCD I2C (SDA/SCL)
Buzzer

Litar siap untuk Wokwi: kebun-diagram.json (salin ke diagram.json projek).

Pelan Pin sudah ada. Bagaimana kita menukarnya kepada arahan yang Gemini tidak boleh salah faham?
Bahagian 5 · Kejuruteraan prompt

Prompt ialah spesifikasi

Nurul menyusun lima kad spesifikasi di sebelah komputer riba

Gemini menulis kod berdasarkan apa yang kamu tulis sahaja. Ia tidak nampak litar kamu, tidak tahu versi pustaka kamu, dan akan meneka apa yang tidak dinyatakan. Setiap tekaan ialah peluang untuk pepijat.

Jurutera menulis spesifikasi. Prompt yang baik ialah spesifikasi yang ringkas, dengan lima bahagian:

1 · KONTEKSPeranan dan projek. Siapa pengguna?
2 · PERKAKASANPapan, versi core, Pelan Pin penuh.
3 · KEPERLUANBernombor, boleh diuji, dengan nilai dan masa.
4 · KEKANGANPustaka, gaya kod, tiada delay() panjang.
5 · UJIANOutput Serial yang dijangka untuk setiap keadaan.
Bahagian 5 · Kejuruteraan prompt

Menulis keperluan yang boleh diuji

Keperluan yang baik boleh dijawab dengan lulus atau gagal. Elakkan perkataan kabur seperti “cepat”, “kering”, “kadang-kadang”.

Kabur ❌Boleh diuji ✅
Siram bila tanah kering.K1. Jika bacaan tanah (GPIO 34) > 3000, hidupkan geganti (GPIO 26) selama 5 saat, kemudian tunggu sekurang-kurangnya 60 saat sebelum menyiram semula.
Tunjuk suhu.K2. Setiap 2 saat, papar “S:28.5C L:65%” pada baris 1 LCD (1 titik perpuluhan).
Beri amaran bila panas.K3. Jika suhu ≥ 35.0 °C, buzzer berbunyi 2000 Hz 200 ms setiap 5 saat sehingga suhu < 34.0 °C.

Perhatikan K3 menggunakan dua nilai (35.0 dan 34.0). Ini dipanggil histeresis, iaitu ia mengelakkan buzzer berbunyi-berhenti tanpa henti apabila suhu berada di sekitar 35 °C.

Aktiviti 6 · Kabur atau boleh diuji?
Bahagian 5 · Kejuruteraan prompt

Kekangan: menghalang tabiat buruk AI

Tanpa kekangan, kod AI selalunya “berjalan” tetapi rapuh. Kekangan yang berguna untuk projek kita:

Kenapa millis()? delay(5000) membekukan papan selama 5 saat: butang tidak dibaca, LCD tidak dikemas kini, MQTT terputus. Dengan millis(), program menyemak jam dan terus bekerja.
Bahagian 5 · Kejuruteraan prompt

Teknik prompt yang digunakan jurutera

TeknikContoh ayatBila digunakan
Rancang dahulu“Sebelum menulis kod, senaraikan langkah dan fungsi yang akan kamu buat. Tunggu saya setuju.”Projek besar
Minta soalan“Jika ada apa-apa yang tidak jelas dalam spesifikasi, tanya saya dahulu.”Sebelum kod pertama
Satu perubahan“Kod sedia ada berfungsi. Tambah K4 sahaja. Jangan ubah bahagian lain.”Menambah ciri
Ralat + kod“Ini ralat compile dan kod penuh. Terangkan punca, kemudian beri kod yang dibetulkan.”Ralat compile
Dijangka vs berlaku“Dijangka: pam hidup 5 s. Berlaku: pam hidup terus. Output Serial: …”Pepijat logik
Terangkan“Terangkan baris 40 hingga 55 seolah-olah kepada pelajar Tingkatan 4.”Memahami kod
Aktiviti 7 · Pilih teknik
Bahagian 5 · Kejuruteraan prompt

Aktiviti: Pembina Spesifikasi

Aktiviti 8 · Bina prompt spesifikasi

Pelan Pin dari Bahagian 4 dimasukkan automatik. Tulis keperluan (satu baris setiap satu), pilih kekangan, tulis ujian, kemudian salin ke Gemini.

3 · Keperluan (satu setiap baris)

4 · Kekangan

5 · Ujian penerimaan

Prompt kamu:

KONTEKS: Saya pelajar sekolah menengah membina   PERKAKASAN: ESP32 DevKit (ESP32 Arduino core 2.0.17). Sambungan: -   di GPIO   · -   di GPIO   -   di GPIO   · -   di GPIO   KEPERLUAN: K1.   K2.   K3.   KEKANGAN: core 2.0.17 · pustaka yang dibenarkan sahaja · tiada delay() panjang, guna millis() · pemalar bernama · semak NaN · kod penuh satu blok, komen BM, jangan ubah pin. UJIAN PENERIMAAN: U1.   U2.  
Spesifikasi siap dan Gemini memberi kod. Bagaimana kita membina, menjalankan dan menguji kod itu?
Bahagian 6 · Aliran kerja Makmal

Aliran kerja Makmal Arduino Maya

  1. Buka Makmal ESP32 dari Desktop. Untuk projek baharu, tekan 📁 Projek Baharu.
  2. Litar: lukis di wokwi.com (jangan tekan Play di sana), salin tab diagram.json ke diagram.json projek. Atau guna fail litar yang cikgu beri.
  3. Kod: tampal kod Gemini ke dalam sketch.ino (Ctrl+A, Ctrl+V).
  4. ▶ Bina & Jalankan (F5). Simulator terbuka. Output Serial muncul di Terminal.
  5. Ralat? Tekan 📋 Salin untuk Gemini, kemudian tampal dalam Gemini. Ralat dan kod disalin bersama.
▶ Bina & Jalankan■ Henti📋 Salin untuk Gemini📁 Projek Baharu🔑 Lesen Wokwi
Lesen Wokwi: kali pertama, tekan 🔑 Lesen Wokwi → log masuk wokwi.com → GET YOUR LICENSE → benarkan pelayar membuka VS Code. Lesen perlu diperbaharui lebih kurang sebulan sekali. Simulasi perlukan Internet; pengkompilan tidak.

Dalam simulator, klik pada DHT22 atau potensiometer untuk menukar suhu dan kelembapan tanah semasa program berjalan. Ini cara terbaik untuk menguji K1 hingga K3.

Bahagian 6 · Aliran kerja Makmal

Membaca ralat compile

Mesej ralat bermula dengan sketch.ino:baris:lajur: error:. Baca baris pertama dahulu, kerana ralat lain selalunya akibat yang pertama.

MesejPunca biasaTindakan
'X' was not declared in this scopeNama belum ditakrif, atau salah ejaanSemak ejaan; minta Gemini menambah definisi
No such file or directoryPustaka tiada dalam MakmalMinta Gemini guna pustaka yang disenaraikan
'ledcAttach' was not declaredKod untuk core 3.x“Guna core 2.0.17 (ledcSetup/ledcAttachPin)”
expected ';' beforeTitik koma hilang pada baris sebelumnyaLihat baris di atas nombor yang diberi
redefinition of 'void setup()'Kod ditampal dua kaliCtrl+A, padam, tampal sekali sahaja
Aktiviti 9 · Diagnosis ralat
Kod berjaya dibina dan berjalan. Tetapi “berjalan” tidak bermaksud “betul”. Bagaimana kita menyemak kod AI?
Hari 2 · Bahagian 7 · Menyemak kod AI

Kod berjalan ≠ kod betul

Aiman menyemak cetakan kod dengan kanta pembesar

AI boleh menghasilkan kod yang kelihatan meyakinkan tetapi mengandungi kesilapan halus. Sebelum menjalankan kod pada perkakasan sebenar (contohnya pam), lakukan semakan kod:

  1. Pin: setiap pemalar pin sama dengan Pelan Pin?
  2. Keperluan: setiap K1, K2, K3 ada dalam kod? Cari nilai ambang dan masa.
  3. Pemasaan: ada delay() panjang yang membekukan program?
  4. Keadaan selamat: apa berlaku jika sensor gagal (NaN)? Adakah pam boleh hidup tanpa henti?
  5. Nombor ajaib: nilai seperti 3000 atau 5000 ditulis sebagai pemalar bernama?
  6. Faham: bolehkah kamu terangkan setiap fungsi kepada rakan?
Hari 2 · Bahagian 7 · Menyemak kod AI

Aktiviti: Cari pepijat

Gemini memberi kod ini untuk K1 (“jika tanah > 3000, pam 5 saat, kemudian rehat 60 saat”). Pelan Pin: tanah GPIO 34, geganti GPIO 26.

const int TANAH = 34;
const int PAM = 27;
const int AMBANG = 3000;

void loop() {
  int t = analogRead(TANAH);
  if (t > AMBANG) {
    digitalWrite(PAM, HIGH);
    delay(5000);
    digitalWrite(PAM, LOW);
  }
}
Aktiviti 10 · Semakan kod
Hari 2 · Bahagian 7 · Menyemak kod AI

Corak millis() yang patut kamu kenal

Kamu tidak perlu menulisnya, tetapi kenali bentuknya semasa menyemak kod Gemini:

unsigned long mulaPam = 0;
bool pamHidup = false;

void loop() {
  unsigned long kini = millis();
  if (!pamHidup && tanahKering() && kini - akhirSiram >= REHAT_MS) {
    pamHidup = true;  mulaPam = kini;  digitalWrite(PAM, HIGH);
  }
  if (pamHidup && kini - mulaPam >= SIRAM_MS) {
    pamHidup = false; akhirSiram = kini; digitalWrite(PAM, LOW);
  }
  // ...bahagian lain terus berjalan: LCD, butang, MQTT
}

Tanda-tanda kod yang baik: kini - mula >= TEMPOH (selamat walaupun millis() melimpah selepas 49 hari), dan pemboleh ubah keadaan seperti pamHidup. Ini dipanggil mesin keadaan.

Aktiviti 11 · Pemeriksa pin

Tampal kod Gemini. Pemeriksa membandingkan pin dalam kod dengan Pelan Pin kamu (Bahagian 4).

SemakanLulus?Catatan
Pin sama dengan Pelan Pin☐
Semua keperluan K1 hingga K3 ada☐
Tiada delay() panjang☐
Keadaan selamat (NaN, pam tidak hidup terus)☐
Pemalar bernama☐
Saya boleh terangkan kod☐
Semakan membantu, tetapi pepijat tetap berlaku. Bagaimana mencari puncanya dengan sistematik?
Hari 2 · Bahagian 8 · Nyahpepijat

Nyahpepijat seperti saintis

Nyahpepijat ialah kaedah saintifik: buat hipotesis, uji, perhatikan.

1 · Lihat dengan Serial

Minta Gemini menambah Serial.printf() pada setiap keputusan penting: nilai sensor, keadaan pam, masa.

2 · Bahagi dan takluk

Uji satu komponen pada satu masa. LCD tidak papar? Cuba program LCD sahaja dahulu.

3 · Ubah satu benda

Hanya satu perubahan antara setiap ujian, supaya kamu tahu perubahan mana yang membetulkan.

4 · Litar dahulu

Semak diagram.json: wayar ke pin betul? GND disambung? LCD guna alamat 0x27?

Aktiviti 12 · Hipotesis
Kebun sudah berfungsi di meja. Bagaimana ia melapor ke telefon Cikgu semasa cuti hujung minggu?
Hari 2 · Bahagian 9 · IoT

Internet of Things

ESP32 di kebun menghantar data ke awan dan ke tablet

IoT bermaksud benda fizikal yang bercakap melalui Internet. Kebun kita akan menghantar data ke awan, dan sesiapa yang dibenarkan boleh melihatnya.

Dalam simulator, ESP32 bersambung ke rangkaian Wokwi-GUEST (tiada kata laluan):

WiFi.begin("Wokwi-GUEST", "", 6);   // saluran 6 = sambungan lebih cepat
while (WiFi.status() != WL_CONNECTED) { delay(200); }
Privasi: trafik Wi-Fi simulator melalui get laluan awam Wokwi dan boleh dipantau. Jangan hantar nama, nombor telefon atau kata laluan sebenar.
Hari 2 · Bahagian 9 · IoT

Dua cara bercakap: HTTP dan MQTT

HTTP

Seperti menghantar surat dan menunggu balasan. ESP32 membuat permintaan (GET atau POST) ke pelayan web, dan pelayan membalas dengan kod (200 = OK).

Sesuai untuk laporan sekali-sekala.

MQTT

Seperti kumpulan WhatsApp. Peranti menerbitkan (publish) mesej ke topik di broker, dan sesiapa yang melanggan (subscribe) topik itu menerimanya serta-merta.

Ringan, sesuai untuk IoT dan data berterusan.

Data dihantar dalam format JSON:

{"suhu": 28.5, "lembap": 65, "tanah": 3120, "pam": false}
Hari 2 · Bahagian 9 · IoT

Merancang topik MQTT

Kita guna broker awam percuma broker.hivemq.com (port 1883). Kerana ia awam, sesiapa sahaja boleh membaca topik yang diteka. Oleh itu, guna topik yang unik dan jangan hantar data peribadi.

Struktur topik bengkel: makmal/<kod sekolah>/<kumpulan>/<data>

Aktiviti 13 · Pereka topik

Untuk melihat data: buka klien web MQTT (contohnya HiveMQ WebSocket Client), sambung ke broker.hivemq.com, dan langgan makmal/smk01/k3/#.

Kebun kini melapor ke awan, dengan kod yang ditulis oleh AI. Siapa yang bertanggungjawab jika ia silap?
Hari 2 · Bahagian 10 · AI secara bertanggungjawab

Kamu jurutera, AI pembantu

Nurul berfikir di hadapan komputer riba dengan ikon perisai dan mangga
Aktiviti 14 · Situasi
Hari 2 · Bahagian 11 · Projek akhir

Projek akhir: Kebun Pintar Sekolah

Pasukan pelajar membentangkan prototaip kebun pintar

Taklimat: bina sistem yang menjaga kebun sekolah semasa hujung minggu dan melapor keadaannya. Pasukan 3 hingga 4 orang, 2 jam.

TahapKeperluan
MinimumDHT22 dan sensor tanah dibaca; LCD memaparkan suhu, kelembapan dan tanah; pam (geganti) disiram mengikut K1 dengan rehat.
Sasaran+ Butang siram manual dengan nyahlantun; amaran suhu dengan histeresis; tiada delay() panjang.
Cabaran+ Terbit JSON ke MQTT setiap 10 s; terima arahan “siram” melalui topik MQTT; LDR untuk tidak menyiram pada tengah hari terik.

Peranan pasukan: Jurutera Perkakasan (litar, Pelan Pin) · Jurutera Spesifikasi (prompt, keperluan) · Penguji (ujian, semakan kod) · Pembentang (demo, log).

Hari 2 · Bahagian 11 · Projek akhir

Hasil kerja dan rubrik

  1. Pelan Pin dan diagram.json.
  2. Log prompt: setiap prompt yang digunakan, dan apa yang berubah selepasnya.
  3. Kod akhir dengan komen.
  4. Jadual ujian: setiap keperluan, langkah ujian, lulus/gagal.
  5. Demo 3 minit dalam simulator, termasuk satu keadaan gagal yang dikendalikan dengan selamat.
KriteriaCemerlang (4)Baik (3)Asas (2)
FungsiSemua keperluan sasaran + satu cabaranSemua keperluan sasaranKeperluan minimum
Spesifikasi & promptKeperluan bernombor, kekangan dan ujian jelas; log lengkapKebanyakan keperluan boleh diujiPrompt umum
Kualiti & keselamatan kodmillis(), pemalar bernama, NaN, had pamSebahagian ciriBerjalan tetapi rapuh
UjianSetiap keperluan diuji dan direkodKebanyakan diujiUjian tidak direkod
PembentanganJelas, menerangkan kod dan peranan AIJelasKurang jelas
Hari 2 · Bahagian 11 · Projek akhir

Jadual ujian pasukan

Aktiviti 15 · Rekod ujian
Kep.Langkah ujian dalam simulatorDijangkaLulus?
K1Pusing potensiometer tanah melebihi 3000“Pam ON”, geganti hidup 5 s, kemudian rehat 60 s☐
K2☐
K3☐
K4☐
K5☐
Penutup

Apa yang kamu bawa pulang

Seterusnya: cuba bina kebun ini dengan perkakasan sebenar. Kod yang sama boleh dimuat naik ke ESP32 sebenar.

Untuk cikgu

Jadual dan persediaan

Cadangan jadual
Hari 1Hari 2
08:30Bahagian 1–208:30Ulang kaji + Bahagian 7
09:35Bahagian 309:20Bahagian 8
10:20Rehat09:50Bahagian 9
10:40Bahagian 410:50Rehat
11:20Bahagian 511:10Bahagian 10 + taklimat projek
12:20Bahagian 6 + Makmal 1 (PWM + butang)11:30Projek akhir
13:00Makmal 2 (DHT22 → LCD), tamat13:30Demo dan penutup
Persediaan
  • Pasang Makmal Arduino Maya dan aktifkan lesen Wokwi pada setiap PC. Uji satu projek dengan Wi-Fi.
  • Salin litar/kebun-diagram.json ke setiap PC atau kongsi melalui Google Classroom. Uji ia dalam Makmal sebelum kelas.
  • Semak broker MQTT boleh dicapai dari makmal (port 1883 keluar). Jika disekat, guna HTTP sahaja.
  • Pastikan akaun Gemini pelajar (DELIMa) aktif.
Untuk cikgu

Kod rujukan: Kebun Pintar (tahap sasaran + MQTT)

Sudah diuji dengan pengkompil Makmal Arduino Maya (ESP32 core 2.0.17). Gunakan untuk menilai kod pasukan, bukan untuk diedarkan sebelum projek.

#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <DHT.h>
#include <LiquidCrystal_I2C.h>

const int PIN_DHT = 15, PIN_TANAH = 34, PIN_LDR = 35;
const int PIN_BUTANG = 4, PIN_PAM = 26, PIN_BUZZER = 25;
const int AMBANG_TANAH = 3000;             // lebih besar = lebih kering
const float SUHU_PANAS = 35.0, SUHU_OK = 34.0;
const unsigned long SIRAM_MS = 5000, REHAT_MS = 60000;
const unsigned long BACA_MS = 2000, TERBIT_MS = 10000;
const char* TOPIK = "makmal/smk01/k3/kebun";

DHT dht(PIN_DHT, DHT22);
LiquidCrystal_I2C lcd(0x27, 16, 2);
WiFiClient wifi;
PubSubClient mqtt(wifi);

float suhu = NAN, lembap = NAN;
int tanah = 0;
bool pamHidup = false, amaran = false;
unsigned long mulaPam = 0, akhirSiram = 0, akhirBaca = 0, akhirTerbit = 0, akhirBunyi = 0;
int butangLepas = HIGH; unsigned long masaButang = 0;

void mulaSiram(unsigned long kini) {
  pamHidup = true; mulaPam = kini; digitalWrite(PIN_PAM, HIGH);
  Serial.println("Pam ON");
}

void sambungMqtt() {
  if (mqtt.connected()) return;
  String id = "makmal-" + String((uint32_t)ESP.getEfuseMac(), HEX);
  if (mqtt.connect(id.c_str())) Serial.println("MQTT bersambung");
}

void setup() {
  Serial.begin(115200);
  pinMode(PIN_BUTANG, INPUT_PULLUP);
  pinMode(PIN_PAM, OUTPUT);
  dht.begin();
  lcd.init(); lcd.backlight();
  WiFi.begin("Wokwi-GUEST", "", 6);
  while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print("."); }
  mqtt.setServer("broker.hivemq.com", 1883);
  Serial.println("\nKebun sedia");
}

void loop() {
  unsigned long kini = millis();
  sambungMqtt();
  mqtt.loop();

  if (kini - akhirBaca >= BACA_MS) {                 // K2: baca dan papar
    akhirBaca = kini;
    float s = dht.readTemperature(), l = dht.readHumidity();
    if (!isnan(s) && !isnan(l)) { suhu = s; lembap = l; }
    tanah = analogRead(PIN_TANAH);
    lcd.setCursor(0, 0); lcd.printf("S:%4.1fC L:%3.0f%% ", suhu, lembap);
    lcd.setCursor(0, 1); lcd.printf("Tanah:%4d %s ", tanah, pamHidup ? "PAM" : "   ");
  }

  if (!pamHidup && tanah > AMBANG_TANAH && kini - akhirSiram >= REHAT_MS) mulaSiram(kini);   // K1
  int b = digitalRead(PIN_BUTANG);                   // siram manual, nyahlantun 50 ms
  if (b != butangLepas && kini - masaButang > 50) {
    masaButang = kini; butangLepas = b;
    if (b == LOW && !pamHidup) mulaSiram(kini);
  }
  if (pamHidup && kini - mulaPam >= SIRAM_MS) {
    pamHidup = false; akhirSiram = kini; digitalWrite(PIN_PAM, LOW);
    Serial.println("Pam OFF");
  }

  if (!isnan(suhu)) {                                // K3: amaran dengan histeresis
    if (suhu >= SUHU_PANAS) amaran = true;
    if (suhu < SUHU_OK) amaran = false;
  }
  if (amaran && kini - akhirBunyi >= 5000) { akhirBunyi = kini; tone(PIN_BUZZER, 2000, 200); }

  if (kini - akhirTerbit >= TERBIT_MS && mqtt.connected()) {   // cabaran: MQTT
    akhirTerbit = kini;
    JsonDocument doc;
    doc["suhu"] = suhu; doc["lembap"] = lembap; doc["tanah"] = tanah;
    doc["cahaya"] = analogRead(PIN_LDR); doc["pam"] = pamHidup;
    char buf[160]; serializeJson(doc, buf);
    mqtt.publish(TOPIK, buf);
    Serial.println(buf);
  }
}
Kandungan

Semua halaman

    Pergi ke halaman