Banjir merupakan salah satu bencana
alam yang sering terjadi di berbagai wilayah Indonesia, terutama pada daerah
yang memiliki sistem drainase kurang optimal dan curah hujan tinggi.
Peningkatan volume air secara tiba-tiba dapat menyebabkan meluapnya saluran
drainase sehingga menimbulkan kerugian material maupun gangguan terhadap
aktivitas masyarakat. Oleh karena itu, diperlukan suatu sistem yang mampu
memberikan peringatan dini sekaligus melakukan pengendalian secara otomatis
untuk mengurangi risiko terjadinya banjir.
Perkembangan teknologi
mikrokontroler memungkinkan terciptanya sistem monitoring dan kontrol yang
dapat bekerja secara otomatis berdasarkan kondisi lingkungan yang terdeteksi
oleh sensor. Pada proyek ini dirancang sebuah sistem Smart Drainage Gate (Pintu
Air Drainase Pintar) yang memanfaatkan kombinasi Rain Sensor, Vibration Sensor,
dan Laser Distance Sensor sebagai perangkat masukan (input). Data dari ketiga
sensor tersebut diproses oleh mikrokontroler STM32F103C8 untuk menentukan
tingkat kondisi drainase dan mengendalikan perangkat keluaran berupa motor
servo, buzzer, dan LCD Display.
Sistem ini dirancang untuk
mendeteksi kondisi aman, waspada, dan bahaya berdasarkan intensitas hujan,
getaran aliran air, serta ketinggian permukaan air. Dengan adanya sistem ini
diharapkan proses pemantauan kondisi drainase dapat dilakukan secara real-time
dan tindakan pengendalian pintu air dapat dilakukan secara otomatis sehingga
potensi banjir dapat diminimalkan.
- Merancang sistem monitoring kondisi drainase berbasis mikrokontroler STM32F103C8.
- Mendeteksi keberadaan hujan menggunakan Rain Sensor sebagai indikator awal potensi peningkatan debit air.
- Mengukur ketinggian permukaan air menggunakan Laser Distance Sensor secara real time.
- Mendeteksi getaran atau arus aliran air menggunakan Vibration Sensor sebagai indikator kondisi aliran yang semakin deras.
- Memberikan peringatan dini kepada pengguna melalui buzzer berdasarkan tingkat kondisi yang terdeteksi.
- Mengendalikan bukaan pintu air secara otomatis menggunakan motor servo sesuai dengan kondisi drainase.
- Menampilkan informasi status sistem dan ketinggian air pada LCD Display sehingga memudahkan proses pemantauan.
3. Alat dan Komponen [Kembali]
- STM32F103C8T6 : Mikrokontroler atau pusat pengendalian sistem.
- Laser Distance Sensor (VL53L0X) : Mengukur ketinggian permukaan air dari dasarnya.
- Rain Sensor (FC-37) : Mendeteksi adanya hujan.
- Vibration Sensor (SW-420) : Mendeteksi adanya getaran.
- LCD Display 16×2 I2C : Menampilkan status sistem dan ketingggian permukaan air dari dasarnya.
- Motor Servo (SG-90) : Menggerakkan pintu air sesuai kondisi yang terdeteksi.
- Buzzer : Memberikan peringatan suara
- Potensiometer : Mengatur tingkat kontras kecerahan LCD Display 16×2 I2C.
- Adaptor 5V : Sumber catu daya utama untuk menyuplai tegangan listrik ke rangkaian.
- Jumper : Kabel penghubung untuk menyambungkan sensor, mikrokontroller, dan output agar menjadi rangkaian yang saling terhubung.
- Breadboard : Papan sirkuit untuk merakit komponen rangkaian.
4.1
General Input Output
Input merupakan seluruh data maupun instruksi yang dimasukkan ke dalam
memori untuk selanjutnya diolah oleh mikroprosesor. Perangkat input adalah
komponen perangkat keras yang berfungsi sebagai media bagi pengguna untuk
memasukkan data atau perintah ke dalam sistem mikrokontroler. Sementara itu,
output merupakan hasil dari proses pengolahan data yang dilakukan oleh
mikroprosesor. Perangkat output adalah perangkat keras yang bertugas
menyampaikan informasi atau hasil pemrosesan kepada pengguna.
Pada mikrokontroler STM32F103C8T6 maupun STM32 NUCLEO G474RE, tersedia
pin Input/Output (I/O) yang dapat berfungsi sebagai input atau output digital
maupun analog. Jumlah pin yang tersedia berbeda-beda tergantung pada tipe
mikrokontroler yang digunakan. Input digital berfungsi untuk mendeteksi
perubahan kondisi logika biner pada suatu pin. Dengan adanya fitur ini,
mikrokontroler mampu menginterpretasikan tegangan 0 V sebagai logika LOW dan
tegangan 3,3 V atau 5 V sebagai logika HIGH. Pembacaan status logika digital
pada pin dapat dilakukan menggunakan fungsi digitalRead(pin).
Output digital memiliki dua kondisi logika, yaitu HIGH dan LOW. Untuk
menghasilkan sinyal keluaran digital, pin harus terlebih dahulu
dikonfigurasikan sebagai OUTPUT, kemudian nilai logika dapat diberikan
menggunakan fungsi digitalWrite(pin, nilai). Jika pin diberikan nilai HIGH,
maka tegangan keluaran pada pin akan berada pada level sekitar 3,3 V atau 5 V
sesuai spesifikasi mikrokontroler. Sebaliknya, jika pin diberikan nilai LOW,
maka tegangan keluaran akan menjadi 0 V. Dengan mekanisme ini, mikrokontroler
dapat mengendalikan berbagai perangkat eksternal seperti LED, relay, buzzer,
maupun aktuator lainnya.
4.2
STM32F103C8
STM32F103C8
adalah mikrokontroler berbasis ARM Cortex-M3 yang dikembangkan oleh
STMicroelectronics. Mikrokontroler ini sering digunakan dalam pengembangan
sistem tertanam karena kinerjanya yang baik, konsumsi daya yang rendah, dan
kompatibilitas dengan berbagai protokol komunikasi. Pada praktikum ini, kita
menggunakan STM32F103C8 yang dapat diprogram menggunakan berbagai metode,
termasuk komunikasi serial (USART), SWD (Serial Wire Debug), atau JTAG untuk
berhubungan dengan komputer maupun perangkat lain. Adapun spesifikasi dari
STM32F4 yang digunakan dalam praktikum ini adalah sebagai berikut:
Gambar 1 STM32F103C8
Gambar 2 Pinout Stm32 F103C8T6
|
Microcontroller |
ARM
Cortex-M3 |
|
Operating
Voltage |
3.3
V |
|
Input
Voltage (recommended) |
5
V |
|
Input
Voltage (limit) |
2
– 3.6 V |
|
Digital
I/O Pins |
32 |
|
PWM
Digital I/O Pins |
15 |
|
Analog
Input Pins |
10
(dengan resolusi 12-bit ADC) |
|
DC
Current per I/O Pin |
25
mA |
|
DC
Current for 3.3V Pin |
150
mA |
|
Flash
Memory |
64
KB |
|
SRAM |
20
KB |
|
EEPROM |
Emulasi
dalam Flash |
|
Clock
Speed |
72
MHz |
BAGIAN-BAGIAN
PENDUKUNG:
1.
RAM (Random Access Memory)
STM32F103C8 dilengkapi dengan 20KB
SRAM on-chip. Kapasitas RAM ini memungkinkan mikrokontroler menjalankan
berbagai aplikasi serta menyimpan data sementara selama eksekusi program.
2.
Memori Flash Internal
STM32F103C8 memiliki memori flash
internal sebesar 64KB atau 128KB, yang digunakan untuk menyimpan firmware dan
program pengguna. Memori ini memungkinkan penyimpanan kode program secara
permanen tanpa memerlukan media penyimpanan eksternal.
3.
Crystal Oscillator
STM32F103C8 menggunakan crystal
oscillator eksternal (biasanya 8MHz) yang bekerja dengan PLL untuk meningkatkan
frekuensi clock hingga 72MHz. Sinyal clock yang stabil ini penting untuk
mengatur kecepatan operasi mikrokontroler dan komponen lainnya.
4.
Regulator Tegangan
STM32F103C8 memiliki sistem
pengaturan tegangan internal yang memastikan pasokan daya stabil ke
mikrokontroler. Tegangan operasi yang didukung berkisar antara 2.0V hingga
3.6V.
5.
Pin GPIO (General Purpose Input/Output)
STM32F103C8 memiliki hingga 37 pin
GPIO yang dapat digunakan untuk menghubungkan berbagai perangkat eksternal
seperti sensor, motor, LED, serta komunikasi dengan antarmuka seperti UART,
SPI, dan I²C.
4.3 ADC
ADC
atau Analog to Digital Converter merupakan salah satu perangkat elektronika
yang digunakan sebagai penghubung dalam pemrosesan sinyal analog oleh sistem
digital. Fungsi utama dari fitur ini adalah mengubah sinyal masukan yang masih
dalam bentuk sinyal analog menjadi sinyal digital dengan bentuk kode-kode
digital.
Pada
mikrokontroler STM32, terdapat dua ADC (Analog-to-Digital Converter) 12-bit
yang masing-masing memiliki hingga 16 kanal eksternal. ADC ini dapat beroperasi
dalam mode single-shot atau scan mode. Pada scan mode, konversi dilakukan
secara otomatis pada sekelompok input analog yang dipilih. Selain itu, ADC ini
memiliki fitur tambahan seperti simultaneous sample and hold, interleaved
sample and hold, serta single shunt. ADC juga dapat dihubungkan dengan DMA
untuk meningkatkan efisiensi transfer data. Mikrokontroler ini dilengkapi
dengan fitur analog watchdog yang memungkinkan pemantauan tegangan hasil
konversi dengan akurasi tinggi, serta dapat menghasilkan interupsi jika
tegangan berada di luar ambang batas yang telah diprogram. Selain itu, ADC
dapat disinkronkan dengan timer internal (TIMx dan TIM1) untuk memulai
konversi, pemicu injeksi, serta pemicu DMA, sehingga memungkinkan aplikasi
untuk melakukan konversi ADC secara terkoordinasi dengan timer.
Pada
STM32 Nucleo G474RE, terdapat blok ADC (Analog-to-Digital Converter) yang
digunakan untuk mengubah sinyal analog menjadi data digital. STM32 G474RE
memiliki beberapa unit ADC (seperti ADC1, ADC2, ADC3, dan ADC4) yang
memungkinkan proses konversi dilakukan secara paralel untuk meningkatkan
kecepatan akuisisi data. Setiap ADC mendukung resolusi hingga 12-bit, dengan
fitur tambahan seperti oversampling untuk meningkatkan akurasi dan mengurangi
noise pada sinyal.
Setiap
unit ADC dapat mengakses banyak channel input yang terhubung ke berbagai pin
GPIO, sehingga memungkinkan pembacaan berbagai sensor secara fleksibel. ADC
pada STM32 G474RE juga dilengkapi dengan fitur scan mode untuk membaca beberapa
channel secara berurutan, serta mode continuous conversion yang memungkinkan
pembacaan data secara terus-menerus tanpa intervensi CPU. Selain itu, terdapat
injected channel yang berfungsi sebagai channel prioritas untuk kebutuhan
real-time.
ADC ini
juga mendukung berbagai sumber trigger, seperti timer (TIM) atau sinyal
eksternal, sehingga dapat disinkronkan dengan modul lain seperti PWM untuk
aplikasi kontrol tertutup (closed-loop). Proses konversi dilakukan melalui
tahap sampling dan quantization, dengan hasil akhir disimpan pada register data
ADC. Dengan fitur-fitur tersebut, ADC pada STM32 G474RE sangat cocok digunakan
dalam aplikasi seperti pembacaan sensor, monitoring tegangan, serta sistem
kendali berbasis sinyal analog yang membutuhkan kecepatan dan presisi tinggi.
4.4 I2C
(Inter-Intergrated Circuit)
Inter
Integrated Circuit atau sering disebut I2C adalah standar komunikasi serial dua
arah menggunakan dua saluran yang didisain khusus untuk mengirim maupun
menerima data. Sistem I2C terdiri dari saluran SCL (Serial Clock) dan SDA
(Serial Data) yang membawa informasi data antara I2C dengan pengontrolnya.
Cara Kerja
Komunikasi I2C
Gambar 3 Cara Kerja Komunikasi I2C
Pada
I2C, data ditransfer dalam bentuk message yang terdiri dari kondisi start,
Address Frame, R/W bit, ACK/NACK bit, Data Frame 1, Data Frame 2, dan kondisi
Stop. Kondisi start dimana saat pada SDA beralih dari logika high ke low
sebelum SCL. Kondisi stop dimana saat pada SDA beralih dari logika low ke high
sebelum SCL.
R/W
bit berfungsi untuk menentukan apakah master mengirim data ke slave atau
meminta data dari slave. (logika 0 = mengirim data ke slave, logika 1 = meminta
data dari slave) ACK/NACK bit berfungsi sebagai pemberi kabar jika data frame
ataupun address frame telah diterima receiver.
4.5
Laser Distance Sensor (VL53L0X)
4.5.1
Deskripsi Laser Distance Sensor
VL53L0X merupakan sensor pengukur jarak berbasis teknologi Time of
Flight (ToF) yang menggunakan laser inframerah untuk mengukur jarak objek
secara non-kontak. Sensor ini dipilih karena memiliki akurasi yang lebih tinggi
dibanding sensor ultrasonik dan mampu menghasilkan data jarak dalam satuan
milimeter. Pada sistem Smart Drainage Gate, sensor digunakan untuk memantau
ketinggian permukaan air secara real-time..
Gambar
4 Laser Distance Sensor
4.5.2
Spesifikasi Laser Distance Sensor
Sensor ini
memancarkan sinar laser inframerah tak terlihat dengan panjang gelombang 940
nanometer yang aman bagi mata manusia (Class 1 laser safety). Untuk
mendukung performa yang cepat, sensor ini memiliki waktu respons atau ranging
time yang sangat singkat, yaitu kurang dari 30 milidetik, sehingga sangat
ideal untuk aplikasi pembacaan cepat seperti pada robotika atau sistem otomasi
Tabel Spesifikasi
Laser Distance Sensor
|
Parameter |
Nilai |
|
Tegangan Kerja |
2.6 – 5 V |
|
Interface |
I2C |
|
Resolusi |
1 mm |
|
Jarak Ukur |
Hingga 2000 mm |
|
Panjang Gelombang Laser |
940 nm |
|
Konsumsi Arus |
±20 mA |
|
Tipe Sensor |
Time of Flight (ToF) |
4.5.3 Prinsip Kerja
Keluaran sensor berupa
data digital jarak dalam satuan milimeter (mm) yang dikirim melalui komunikasi
I2C ke STM32. Berbeda dengan sensor ultrasonik yang menggunakan pulsa echo,
VL53L0X langsung memberikan nilai jarak sehingga pemrosesan menjadi lebih
sederhana. Sensor memancarkan pulsa laser inframerah menuju permukaan air.
Setelah mengenai permukaan air, sinar akan dipantulkan kembali ke sensor. Waktu
yang dibutuhkan sinar untuk bergerak dari sensor menuju objek dan kembali lagi
diukur dalam satuan nanodetik. Berdasarkan waktu tempuh tersebut, sensor
menghitung jarak menggunakan kecepatan cahaya sebagai referensi.
Pada sistem Smart Drainage Gate,
sensor VL53L0X ditempatkan di bagian atas saluran air dan diarahkan ke
permukaan air. Ketika permukaan air naik, jarak antara sensor dan permukaan air
akan semakin kecil. Sebaliknya, ketika air surut, nilai jarak yang terbaca akan
semakin besar. Mikrokontroler STM32 secara berkala membaca data jarak dari
sensor melalui komunikasi I2C. Nilai tersebut kemudian dibandingkan dengan
batas ketinggian air yang telah ditentukan untuk menentukan status Aman,
Waspada, atau Bahaya. Berdasarkan status tersebut, motor servo akan mengatur
posisi pintu air secara otomatis.
4.5.4 Grafik Respon Sensor
Grafik respon
sensor menunjukkan hubungan antara ketinggian air dan jarak yang dibaca sensor.
Semakin tinggi permukaan air, jarak antara sensor dan permukaan air akan
semakin kecil. Dengan demikian, grafik memiliki kecenderungan menurun dan
relatif linier dalam rentang pengukuran tertentu.
Gambar 6 Grafik
Respon Sistem Flame Senso.
4.6 Sensor Hujan (Rain Sensor)
4.6.1 Deskripsi Sensor Hujan
Sensor hujan
digunakan untuk mendeteksi adanya tetesan air pada permukaan sensor. Sensor ini
terdiri dari papan konduktor yang akan berubah resistansinya ketika terkena
air. Sensor ini bekerja berdasarkan perubahan nilai resistansi akibat adanya
tetesan air yang menghubungkan jalur-jalur konduktor pada papan sensor.. Pada
proyek Smart Drainage Gate, sensor hujan berfungsi sebagai indikator awal
terjadinya hujan sehingga sistem dapat meningkatkan kewaspadaan sebelum
ketinggian air naik secara signifikan..
Gambar 7 Rain
Sensor
4.6.2 Spesifikasi Sensor Hujan
Tabel Spesifikasi Sensor Hujan
|
Parameter |
Nilai |
|
Tegangan Kerja |
3.3
– 5 V |
|
Output |
Digital
dan Analog |
|
Sensitivitas |
Adjustable |
|
Arus Kerja |
<
20 mA |
4.6.3 Prinsip Kerja
Sensor hujan
digunakan untuk mendeteksi kondisi cuaca di sekitar pintu air. Ketika hujan
mulai turun, sistem akan meningkatkan kewaspadaan terhadap kemungkinan kenaikan
debit air. Informasi hujan akan dikombinasikan dengan data ketinggian air dari
sensor laser untuk menentukan keputusan pembukaan pintu air secara otomatis. Ketika
permukaan sensor terkena air hujan, hambatan listrik antar jalur konduktor akan
berubah. Perubahan tersebut diproses oleh modul sehingga menghasilkan sinyal
digital atau analog yang menunjukkan kondisi hujan atau tidak hujan.
Ketika tidak ada hujan, jalur konduktor pada
sensor tidak terhubung sehingga tegangan keluaran berada pada kondisi normal.
Saat hujan turun, tetesan air menghubungkan jalur konduktor sehingga terjadi
perubahan resistansi dan tegangan keluaran. STM32 membaca perubahan tersebut
sebagai indikator adanya hujan. Informasi hujan digunakan sebagai parameter
tambahan dalam pengambilan keputusan pembukaan pintu air.
4.6.4 Grafik Respon Sensor
Grafik menunjukkan
hubungan antara intensitas air yang mengenai sensor terhadap tegangan keluaran
sensor.
Gambar 9 Grafik Respon
Sistem Mq-6 Sensor
4.7 Sensor Getaran (SW-420)
4.7.1 Deskripsi Sensor Getaran SW-420
Sensor SW-420
merupakan sensor yang digunakan untuk mendeteksi adanya getaran atau benturan
pada suatu objek. Sensor ini banyak digunakan pada sistem keamanan dan
monitoring kondisi lingkungan..
Gambar 10 Sensor Getaran SW-420
4.7.2 Spesifikasi Sensor Getaran SW-420
Tabel Spesifikasi Sensor Getaran
SW-420
|
Parameter |
Nilai |
|
Tegangan Operasi |
3.3
– 5V |
|
Output |
Digital |
|
Sensitivitas |
Adjustable |
|
Arus Operasi |
<15mA |
4.7.3 Prinsip Kerja
Sensor SW-420
merupakan sensor yang digunakan untuk mendeteksi adanya getaran atau benturan
pada suatu objek. Sensor ini banyak digunakan pada sistem keamanan dan
monitoring kondisi lingkungan.
Pada sistem Smart Drainage Gate, sensor getar
dipasang pada struktur pintu air. Ketika terjadi getaran berlebih akibat
benturan benda asing, kerusakan mekanik, atau kondisi tidak normal lainnya,
sensor menghasilkan sinyal digital yang dibaca oleh Mikrokontroller. Sensor
getaran digunakan sebagai pendeteksi kondisi abnormal seperti benturan pada
pintu air, getaran struktur, atau gangguan lingkungan yang berpotensi
memengaruhi sistem. Ketika getaran melebihi ambang batas, Mikrokontroller akan
mengaktifkan buzzer dan menampilkan peringatan pada LCD agar operator dapat
segera melakukan pemeriksaan.
4.7.4 Grafik Respon Sensor
Grafik menunjukkan
perubahan kondisi output sensor terhadap tingkat getaran yang diterima sensor.
Grafik Respon Sensor
Getaran
4.8 Motor Servo SG90
4.8.1 Deskripsi Servo SG90
Motor servo SG90 merupakan aktuator
yang mampu bergerak ke sudut tertentu berdasarkan sinyal PWM yang diberikan
oleh mikrokontroler. Pada proyek ini servo digunakan untuk mengangkat dan
menurunkan pintu air secara otomatis..
Gambar Servo SG90
4.8.2 Spesifikasi Servo SG90
Tabel Spesifikasi Servo SG90
|
Parameter |
Nilai |
|
Tegangan Kerja |
4.8 – 6V |
|
Sudut Rotasi |
0° – 180° |
|
Frekuensi PWM |
50 Hz |
|
Lebar Pulsa |
1 – 2 ms |
4.8.3 Prinsip Kerja
Servo menerima
sinyal PWM dari mikrokontroler. Lebar pulsa PWM menentukan sudut putaran poros
servo. Semakin besar lebar pulsa, semakin besar sudut yang dicapai servo.
Servo digunakan sebagai aktuator utama
untuk membuka dan menutup pintu air. Saat kondisi Aman, servo mempertahankan
pintu dalam posisi tertutup. Saat kondisi Waspada, servo membuka pintu sebagian
untuk mengalirkan air secara bertahap. Pada kondisi Bahaya, servo membuka pintu
sepenuhnya agar debit air dapat segera dialirkan ke saluran drainase sehingga
risiko banjir dapat diminimalkan.
4.8.4 Grafik Hubungan PWM dengan sudut servo
Gambar 12 Grafik Hubungan PWM
dengan sudut servo
4.9 LCD 16x2 I2C
4.9.1 Deskripsi
LCD 16×2 I2C
merupakan perangkat tampilan yang digunakan untuk menampilkan informasi teks. Penggunaan
modul I2C memungkinkan pengurangan jumlah pin mikrokontroler yang digunakan
dibandingkan LCD paralel.
4.9.2 Spesifikasi
Tabel Spesifikasi LCD
I2C
|
Parameter |
Nilai |
|
Tegangan Operasi |
5V |
|
Jumlah Karakter |
16×2 |
|
Interface |
I²C |
|
Alamat Umum |
0x27 atau 0x3F |
4.9.3 Cara Kerja
LCD digunakan
sebagai media informasi bagi pengguna. LCD menampilkan status sistem seperti
kondisi Aman, Waspada, atau Bahaya, nilai ketinggian air yang terbaca sensor
laser, status hujan, dan informasi alarm apabila terjadi getaran atau kondisi
darurat pada pintu air. LCD menerima data dari mikrokontroler melalui
komunikasi I2C. Data yang diterima akan ditampilkan dalam bentuk karakter pada
layar LCD.
4.10 Buzzer
4.10.1 Deskripsi
Buzzer merupakan komponen elektronika
yang berfungsi mengubah energi listrik menjadi energi suara sebagai indikator
atau alarm.
4.11.2 Spesifikasi
Tabel Spesifikasi
Buzzer
|
Parameter |
Nilai |
|
Tegangan Kerja |
3.3–5V |
|
Arus Operasi |
±30mA |
4.11.3 Cara Kerja
Buzzer berfungsi sebagai alarm peringatan pada kondisi kritis. Saat sensor mendeteksi ketinggian air berbahaya atau terdapat getaran abnormal pada struktur pintu air, buzzer akan aktif untuk memberikan peringatan kepada pengguna agar segera melakukan tindakan penanganan. Ketika diberikan tegangan, buzzer menghasilkan getaran mekanis yang menghasilkan gelombang suara sehingga dapat didengar oleh pengguna.
5. Flowchart dan Listing Program [Kembali]
Flowchart :
Listing Program :
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Smart Drainage Monitoring System — Prototipe 30 cm (Rev. 4 - servo fix)
*
* LCD 16x2 — Satu layar, selalu tampil:
* Baris 1 : "STATUS : AMAN/WASPADA/BAHAYA"
* Baris 2 : "AIR : XXcm" (nilai jarak AKTUAL hasil pembacaan sensor, rata tengah)
*
* Tabel Logika:
* ----------------------------------------------------------------------------
* Kondisi | Rain | Vibration | Jarak | Buzzer | Servo | PWM | CCR
* AMAN | Low | Low | 20-30 cm | Mati | 0° | 1.0 ms | 1000
* WASPADA | High | Low | 10-20 cm | Menyala putus | 45° | 1.25 ms | 1250
* BAHAYA | High | High | 0-10 cm | Menyala terus | 90° | 1.5 ms | 1500
* ----------------------------------------------------------------------------
*
* Konfigurasi PWM Servo:
* Frekuensi = 50 Hz (periode 20 ms)
* Prescaler = 7 ? f_cnt = 8 MHz / 8 = 1 MHz (1 tick = 1 µs)
* Period = 19999 (ARR)
* CCR AMAN = 1000 (1,0 ms)
* CCR WASPADA = 1250 (1,25 ms)
* CCR BAHAYA = 1500 (1,5 ms)
*
* CATATAN PERBAIKAN (Rev. 4):
* 1) BUG: posisi servo sebelumnya ditentukan dari variabel statusDrainase,
* yang dihitung dari KOMBINASI (OR) rain + vibration + jarak. Akibatnya
* servo bisa "terkunci" ke WASPADA/BAHAYA walau jarak air sebenarnya
* AMAN, setiap kali sensor hujan/getaran aktif (atau noise akibat pin
* floating). Servo jadi tidak terlihat mengikuti pembacaan Laser
* Distance Sensor (VL53L0X) secara langsung.
* 2) FIX: ditambahkan fungsi Servo_CCR_FromJarak(jarakCm) yang menghitung
* CCR servo LANGSUNG dan HANYA dari jarakCm (hasil VL53L0X), sesuai
* tabel Jarak->Servo. Pemanggilan ini dipisah total dari logika buzzer.
* 3) Logika buzzer/LCD (statusDrainase, gabungan rain+vibration+jarak)
* TIDAK diubah — tetap dipakai untuk indikator suara/peringatan dini.
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>
#include "i2c_lcd.h"
#include "VL53L0X.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
I2C_HandleTypeDef hi2c2;
TIM_HandleTypeDef htim1;
/* USER CODE BEGIN PV */
I2C_LCD_HandleTypeDef hlcd;
#define RAIN_SENSOR_PORT GPIOA
#define RAIN_SENSOR_PIN GPIO_PIN_1
#define VIBRATION_SENSOR_PORT GPIOA
#define VIBRATION_SENSOR_PIN GPIO_PIN_2
#define BUTTON_PORT GPIOB
#define BUTTON_PIN GPIO_PIN_12
#define BUZZER_PORT GPIOB
#define BUZZER_PIN GPIO_PIN_15
/* Ganti ke GPIO_PIN_RESET jika modul sensor Anda aktif LOW */
#define RAIN_ACTIVE_LEVEL GPIO_PIN_RESET /* sensor hujan terkonfirmasi aktif LOW */
#define VIBRATION_ACTIVE_LEVEL GPIO_PIN_RESET
/*
* Servo PWM — TIM1, Prescaler=7, Period=19999
* f_cnt = 8 MHz / (7+1) = 1 MHz ? 1 tick = 1 µs
*
* CCR (Nilai Timer / Compare Register) per kondisi:
* AMAN : 1000 ? 1,0 ms ? 0°
* WASPADA : 1250 ? 1,25 ms ? 45°
* BAHAYA : 1500 ? 1,5 ms ? 90°
*/
#define SERVO_CCR_AMAN 1000u
#define SERVO_CCR_WASPADA 1250u
#define SERVO_CCR_BAHAYA 1500u
/* Batas jarak (cm) sesuai tabel kondisi */
#define JARAK_BAHAYA_MAX_CM 10
#define JARAK_WASPADA_MAX_CM 20
uint16_t jarakMm = 0;
uint8_t jarakCm = 30;
char statusDrainase[12] = "AMAN";
char statusDrainasePrev[12] = "AMAN";
volatile uint8_t buzzerMuted = 0;
volatile uint32_t lastBtnTick = 0;
uint32_t statusMillis = 0;
uint32_t lcdMillis = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_I2C2_Init(void);
static void MX_TIM1_Init(void);
/* USER CODE BEGIN PFP */
static void CheckDrainageStatus(uint8_t rainHigh, uint8_t vibrationHigh);
static void UpdateOutputs(void);
static void Servo_SetCCR(uint16_t ccr);
static uint16_t Servo_CCR_FromJarak(uint8_t cm);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == BUTTON_PIN)
{
uint32_t now = HAL_GetTick();
if (now - lastBtnTick >= 150)
{
lastBtnTick = now;
buzzerMuted = 1;
}
}
}
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
MX_GPIO_Init();
MX_I2C1_Init();
MX_I2C2_Init();
MX_TIM1_Init();
/* USER CODE BEGIN 2 */
hlcd.hi2c = &hi2c2;
hlcd.address = 0x4E;
lcd_init(&hlcd);
lcd_clear(&hlcd);
lcd_gotoxy(&hlcd, 0, 0);
lcd_puts(&hlcd, "Sistem Drainase");
lcd_gotoxy(&hlcd, 0, 1);
lcd_puts(&hlcd, "Inisialisasi...");
HAL_Delay(1000);
if (!initVL53L0X(true, &hi2c1))
{
lcd_clear(&hlcd);
lcd_gotoxy(&hlcd, 0, 0);
lcd_puts(&hlcd, "ERROR: Sensor!");
lcd_gotoxy(&hlcd, 0, 1);
lcd_puts(&hlcd, "Cek kabel I2C1");
HAL_Delay(3000);
Error_Handler();
}
setSignalRateLimit(0.25f);
setVcselPulsePeriod(VcselPeriodPreRange, 14);
setVcselPulsePeriod(VcselPeriodFinalRange, 10);
setMeasurementTimingBudget(20000);
startContinuous(0);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
Servo_SetCCR(SERVO_CCR_AMAN); /* posisi awal: 0° / 1 ms */
lcd_clear(&hlcd);
lcd_gotoxy(&hlcd, 0, 0);
lcd_puts(&hlcd, "Sensor OK!");
lcd_gotoxy(&hlcd, 0, 1);
lcd_puts(&hlcd, "Siap memantau..");
HAL_Delay(1000);
lcd_clear(&hlcd);
statusMillis = HAL_GetTick();
lcdMillis = HAL_GetTick();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
uint32_t currentMillis = HAL_GetTick();
/* --- Baca sensor jarak (VL53L0X) --- */
jarakMm = readRangeContinuousMillimeters(0);
if (jarakMm != 65535)
{
uint8_t rawCm = (uint8_t)(jarakMm / 10);
if (rawCm > 30) rawCm = 30;
jarakCm = rawCm;
}
/* --- Baca sensor digital --- */
uint8_t rainHigh = (HAL_GPIO_ReadPin(RAIN_SENSOR_PORT, RAIN_SENSOR_PIN) == RAIN_ACTIVE_LEVEL);
uint8_t vibrationHigh = (HAL_GPIO_ReadPin(VIBRATION_SENSOR_PORT, VIBRATION_SENSOR_PIN) == VIBRATION_ACTIVE_LEVEL);
if (currentMillis - statusMillis >= 300)
{
statusMillis = currentMillis;
CheckDrainageStatus(rainHigh, vibrationHigh);
if (strcmp(statusDrainase, statusDrainasePrev) != 0)
{
buzzerMuted = 0;
strcpy(statusDrainasePrev, statusDrainase);
}
}
UpdateOutputs();
if (currentMillis - lcdMillis >= 200)
{
lcdMillis = currentMillis;
char line1[17];
char line2[17];
char text1[17];
char band[17];
memset(line1, ' ', 16); line1[16] = '\0';
memset(line2, ' ', 16); line2[16] = '\0';
if (strcmp(statusDrainase, "BAHAYA") == 0)
{
snprintf(text1, sizeof(text1), "STATUS : BAHAYA");
}
else if (strcmp(statusDrainase, "WASPADA") == 0)
{
snprintf(text1, sizeof(text1), "STATUS : WASPADA");
}
else
{
snprintf(text1, sizeof(text1), "STATUS : AMAN");
}
uint8_t l1Len = (uint8_t)strlen(text1);
if (l1Len > 16) l1Len = 16;
memcpy(line1, text1, l1Len);
snprintf(band, sizeof(band), "AIR : %ucm", (unsigned int)jarakCm);
uint8_t bLen = (uint8_t)strlen(band);
if (bLen > 16) bLen = 16;
uint8_t padLeft = (uint8_t)((16 - bLen) / 2);
memcpy(&line2[padLeft], band, bLen);
lcd_gotoxy(&hlcd, 0, 0);
lcd_puts(&hlcd, line1);
lcd_gotoxy(&hlcd, 0, 1);
lcd_puts(&hlcd, line2);
}
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); }
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); }
}
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); }
}
static void MX_I2C2_Init(void)
{
hi2c2.Instance = I2C2;
hi2c2.Init.ClockSpeed = 100000;
hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c2) != HAL_OK) { Error_Handler(); }
}
static void MX_TIM1_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
/*
* f_TIM1 = PCLK2 = 8 MHz (HSI, semua divider = 1)
* Prescaler = 7 ? f_cnt = 8 MHz / (7+1) = 1 MHz (1 tick = 1 µs)
* Period = 19999 ? T_PWM = (19999+1) / 1 MHz = 20 ms ? 50 Hz
*/
htim1.Instance = TIM1;
htim1.Init.Prescaler = 7;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 19999;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) { Error_Handler(); }
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { Error_Handler(); }
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = SERVO_CCR_AMAN; /* CCR awal = 1000 (posisi 0°) */
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); }
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) { Error_Handler(); }
HAL_TIM_MspPostInit(&htim1);
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = RAIN_Pin | VIBRATION_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = BUTTON_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(BUTTON_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = BUZZER_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(BUZZER_GPIO_Port, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}
/* USER CODE BEGIN 4 */
static void CheckDrainageStatus(uint8_t rainHigh, uint8_t vibrationHigh)
{
uint8_t jarakBahaya = (jarakCm <= JARAK_BAHAYA_MAX_CM);
uint8_t jarakWaspada = (jarakCm > JARAK_BAHAYA_MAX_CM && jarakCm <= JARAK_WASPADA_MAX_CM);
if (vibrationHigh || jarakBahaya)
{
strcpy(statusDrainase, "BAHAYA");
}
else if (rainHigh || jarakWaspada)
{
strcpy(statusDrainase, "WASPADA");
}
else
{
strcpy(statusDrainase, "AMAN");
}
}
/**
* @brief Hitung nilai CCR servo LANGSUNG dari jarak air (cm) hasil
* pembacaan Laser Distance Sensor (VL53L0X). Fungsi ini SENGAJA
* tidak melibatkan status rain/vibration — posisi servo murni
* representasi ketinggian air, sesuai tabel:
* 20-30 cm -> 1000 (0°)
* 10-20 cm -> 1250 (45°)
* 0-10 cm -> 1500 (90°)
* @param cm Jarak air dalam cm (0-30)
* @retval Nilai CCR (1000 / 1250 / 1500)
*/
static uint16_t Servo_CCR_FromJarak(uint8_t cm)
{
if (cm <= JARAK_BAHAYA_MAX_CM)
{
return SERVO_CCR_BAHAYA; /* 0-10 cm -> 1500 -> 90° */
}
else if (cm <= JARAK_WASPADA_MAX_CM)
{
return SERVO_CCR_WASPADA; /* 11-20 cm -> 1250 -> 45° */
}
else
{
return SERVO_CCR_AMAN; /* 21-30 cm -> 1000 -> 0° */
}
}
static void UpdateOutputs(void)
{
static uint32_t buzzerMillis = 0;
static uint8_t buzzerState = 0;
static uint16_t lastCCR = 0xFFFF; /* nilai tidak valid ? paksa set pertama kali */
static uint8_t beepStep = 0;
static uint8_t waspadaActive = 0;
/* Pola beep WASPADA: ON-120ms, OFF-150ms, ON-120ms, DIAM-700ms */
static const uint16_t beepDurasi[4] = { 120, 150, 120, 700 };
uint32_t now = HAL_GetTick();
#define BUZ_ON() do { HAL_GPIO_WritePin(BUZZER_PORT, BUZZER_PIN, GPIO_PIN_SET); buzzerState = 1; } while (0)
#define BUZ_OFF() do { HAL_GPIO_WritePin(BUZZER_PORT, BUZZER_PIN, GPIO_PIN_RESET); buzzerState = 0; } while (0)
/* --- SERVO: selalu mengikuti jarak air dari Laser Distance Sensor,
* terlepas dari status gabungan rain/vibration --- */
uint16_t targetCCR = Servo_CCR_FromJarak(jarakCm);
/* --- BUZZER: tetap mengikuti status gabungan (rain/vibration/jarak) --- */
if (strcmp(statusDrainase, "BAHAYA") == 0)
{
waspadaActive = 0;
if (buzzerMuted) { BUZ_OFF(); }
else if (!buzzerState) { BUZ_ON(); }
buzzerMillis = now;
}
else if (strcmp(statusDrainase, "WASPADA") == 0)
{
if (buzzerMuted)
{
BUZ_OFF();
waspadaActive = 0;
}
else if (!waspadaActive)
{
waspadaActive = 1;
beepStep = 0;
buzzerMillis = now;
BUZ_ON();
}
else if (now - buzzerMillis >= beepDurasi[beepStep])
{
buzzerMillis = now;
beepStep = (beepStep + 1) % 4;
if (beepStep == 0 || beepStep == 2) { BUZ_ON(); }
else { BUZ_OFF(); }
}
}
else /* AMAN */
{
waspadaActive = 0;
BUZ_OFF();
buzzerMillis = now;
}
if (targetCCR != lastCCR)
{
Servo_SetCCR(targetCCR);
lastCCR = targetCCR;
}
}
/**
* @brief Set nilai CCR (Compare Register) TIM1 CH1 untuk servo.
* @param ccr Nilai timer langsung (µs), contoh: 1000 / 1250 / 1500.
* Rentang valid: SERVO_CCR_AMAN (1000) .. SERVO_CCR_BAHAYA (1500).
*/
static void Servo_SetCCR(uint16_t ccr)
{
/* Batasi agar tidak keluar rentang aman servo */
if (ccr < SERVO_CCR_AMAN) ccr = SERVO_CCR_AMAN;
if (ccr > SERVO_CCR_BAHAYA) ccr = SERVO_CCR_BAHAYA;
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, ccr);
}
/* USER CODE END 4 */
void Error_Handler(void)
{
__disable_irq();
while (1) {}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line) {}
#endif
6. Rangkaian Simulasi dan Prinsip Kerja [Kembali]
Sistem Smart Drainage Gate bekerja dengan memanfaatkan tiga jenis sensor yang berfungsi untuk memantau kondisi lingkungan drainase. Data dari sensor hujan, sensor getaran, dan sensor jarak laser akan diproses oleh mikrokontroler STM32F103C8 untuk menentukan tingkat status drainase. Berdasarkan hasil pengolahan data tersebut, sistem akan mengaktifkan buzzer, menggerakkan motor servo sebagai pintu air otomatis, dan menampilkan informasi pada LCD.
A. Kondisi Aman
Kondisi ini terjadi apabila:
- Sensor hujan tidak mendeteksi hujan.
- Sensor getaran tidak aktif.
- Ketinggian permukaan air > 20 cm dari Laser Distance Sensor.
Maka sistem akan:
- Menampilkan STATUS : AMAN.
- Buzzer mati.
- Servo berada pada posisi 0° (pintu air tertutup atau bukaan minimum).
- LCD menampilkan tinggi air aktual.
B. Kondisi Waspada
Kondisi ini terjadi apabila:
- Sensor hujan aktif, atau
- Ketinggian air berada pada rentang 10–20 cm dari Laser Distance Sensor.
Maka sistem akan:
- Menampilkan STATUS : WASPADA.
- Buzzer berbunyi putus-putus.
- Servo bergerak ke posisi 45°.
- Pintu air mulai dibuka sebagian.
C. Kondisi Bahaya
Kondisi ini terjadi apabila:
- Sensor getaran aktif, atau
- Ketinggian permukaan air ≤ 10 cm dari Laser Distance Sensor.
Maka sistem akan:
- Menampilkan STATUS : BAHAYA.
- Buzzer menyala terus-menerus.
- Servo bergerak ke posisi 90°.
- Pintu air terbuka maksimal untuk mempercepat aliran air.
Dengan mekanisme tersebut, sistem mampu memberikan respons otomatis terhadap perubahan kondisi lingkungan sehingga dapat membantu mengurangi risiko terjadinya banjir.
-Video Simulasi di Proteus
8. Kesimpulan dan Saran [Kembali]
- Menambahkan sensor debit air untuk memperoleh informasi aliran air yang lebih akurat.
- Menambahkan sumber daya cadangan (backup battery) agar sistem tetap beroperasi saat terjadi pemadaman listrik.
- Mengintegrasikan sistem dengan aplikasi monitoring berbasis web atau smartphone sehingga informasi kondisi drainase dapat diterima secara real-time oleh petugas maupun masyarakat.
File Zip
Rangkaian Project [Klik Disini]
File Zip
Library Komponen [Klik Disini]
Datasheet STM32F103C8
[Klik Disini]
Datasheet Ultrasonic
Sensor [Klik Disini]
Datasheet Laser Distance Sensor [Klik Disini]
Datasheet
Vibration Sensor [Klik Disini]
Datasheet
Rain Sensor [Klik Disini]
Datasheet LCD 16x2 I2C [Klik Disini]
Datasheet Motor Servo [Klik Disini]
Datasheet Buzzer [Klik Disini]
No comments:
Post a Comment