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 */ /* SISTEM PERINGATAN DINI BANJIR DAN PENGENDALIAN PINTU AIR OTOMATIS Mikrokontroler : STM32F103C8T6 Simulasi : Proteus Sensor : Rain Sensor, Vibration Sensor, Ultrasonic Sensor Output : LCD LM016L, Buzzer, Servo Motor Keterangan: - Potensio pada Ultrasonic Sensor di Proteus dianggap sebagai tinggi air. - 1% nilai potensio = 1 cm ketinggian air dari dasar. - 0-25 cm = AMAN - 26-40 cm = WASPADA - >40 cm = BAHAYA */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> #include <string.h> /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ typedef enum { STATUS_AMAN = 0, STATUS_WASPADA, STATUS_BAHAYA } StatusBanjir; /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #define SERVO_MIN_US 1000 #define SERVO_MAX_US 2000 #define SERVO_PERIOD_US 20000 #define BATAS_AMAN_CM 25 #define BATAS_WASPADA_CM 40 #define BUZZER_INTERVAL_MS 300 /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ TIM_HandleTypeDef htim2; /* USER CODE BEGIN PV */ uint32_t lastBuzzerTick = 0; uint32_t lastLcdUpdate = 0; GPIO_PinState buzzerState = GPIO_PIN_RESET; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM2_Init(void); /* USER CODE BEGIN PFP */ void delay_us(uint16_t us); void LCD_Init(void); void LCD_Enable(void); void LCD_Send4Bit(uint8_t data); void LCD_SendCommand(uint8_t cmd); void LCD_SendData(uint8_t data); void LCD_Clear(void); void LCD_SetCursor(uint8_t row, uint8_t col); void LCD_Print(char *str); void LCD_PrintLine(uint8_t row, char *str); uint32_t Ultrasonic_Read_CM(void); void Servo_SetAngle(uint8_t angle); void Output_Control(StatusBanjir status); StatusBanjir Get_Status(uint32_t tinggiAirCm, uint8_t rainHigh, uint8_t vibrationHigh); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ void delay_us(uint16_t us) { uint16_t start = __HAL_TIM_GET_COUNTER(&htim2); while ((uint16_t)(__HAL_TIM_GET_COUNTER(&htim2) - start) < us) { } } /* ========================= LCD LM016L 4 BIT ========================= */ void LCD_Enable(void) { HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, GPIO_PIN_SET); delay_us(2); HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, GPIO_PIN_RESET); delay_us(50); } void LCD_Send4Bit(uint8_t data) { HAL_GPIO_WritePin(D4_GPIO_Port, D4_Pin, (data & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(D5_GPIO_Port, D5_Pin, (data & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(D6_GPIO_Port, D6_Pin, (data & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(D7_GPIO_Port, D7_Pin, (data & 0x08) ? GPIO_PIN_SET : GPIO_PIN_RESET); LCD_Enable(); } void LCD_SendCommand(uint8_t cmd) { HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, GPIO_PIN_RESET); LCD_Send4Bit(cmd >> 4); LCD_Send4Bit(cmd & 0x0F); HAL_Delay(2); } void LCD_SendData(uint8_t data) { HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, GPIO_PIN_SET); LCD_Send4Bit(data >> 4); LCD_Send4Bit(data & 0x0F); HAL_Delay(1); } void LCD_Init(void) { HAL_Delay(50); HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, GPIO_PIN_RESET); LCD_Send4Bit(0x03); HAL_Delay(5); LCD_Send4Bit(0x03); HAL_Delay(5); LCD_Send4Bit(0x03); HAL_Delay(5); LCD_Send4Bit(0x02); LCD_SendCommand(0x28); // LCD 4-bit, 2 baris LCD_SendCommand(0x0C); // Display ON, cursor OFF LCD_SendCommand(0x06); // Cursor geser kanan LCD_SendCommand(0x01); // Clear display HAL_Delay(5); } void LCD_Clear(void) { LCD_SendCommand(0x01); HAL_Delay(2); } void LCD_SetCursor(uint8_t row, uint8_t col) { uint8_t address; if (row == 0) address = 0x80 + col; else address = 0xC0 + col; LCD_SendCommand(address); } void LCD_Print(char *str) { while (*str) { LCD_SendData(*str++); } } void LCD_PrintLine(uint8_t row, char *str) { char buffer[17]; uint8_t i; memset(buffer, ' ', 16); buffer[16] = '\0'; for (i = 0; i < 16 && str[i] != '\0'; i++) { buffer[i] = str[i]; } LCD_SetCursor(row, 0); LCD_Print(buffer); } /* ========================= ULTRASONIC SENSOR ========================= */ uint32_t Ultrasonic_Read_CM(void) { uint32_t timeout; uint16_t startTime, endTime; uint32_t pulseWidth; uint32_t tinggiAirCm; HAL_GPIO_WritePin(TRIGGER_GPIO_Port, TRIGGER_Pin, GPIO_PIN_RESET); delay_us(2); HAL_GPIO_WritePin(TRIGGER_GPIO_Port, TRIGGER_Pin, GPIO_PIN_SET); delay_us(10); HAL_GPIO_WritePin(TRIGGER_GPIO_Port, TRIGGER_Pin, GPIO_PIN_RESET); timeout = HAL_GetTick(); while (HAL_GPIO_ReadPin(ECHO_GPIO_Port, ECHO_Pin) == GPIO_PIN_RESET) { if ((HAL_GetTick() - timeout) > 50) return 0; } startTime = __HAL_TIM_GET_COUNTER(&htim2); timeout = HAL_GetTick(); while (HAL_GPIO_ReadPin(ECHO_GPIO_Port, ECHO_Pin) == GPIO_PIN_SET) { if ((HAL_GetTick() - timeout) > 50) return 50; } endTime = __HAL_TIM_GET_COUNTER(&htim2); if (endTime >= startTime) pulseWidth = endTime - startTime; else pulseWidth = (19999 - startTime) + endTime; /* Proteus ultrasonic menghasilkan durasi echo. Durasi itu kita ubah dulu menjadi jarak. */ uint32_t jarakCm = pulseWidth / 58; /* Bagian penting: Kita anggap tinggi tangki maksimal 50 cm. Jika jarak ultrasonic besar, air rendah. Jika jarak ultrasonic kecil, air tinggi. Maka: tinggi air = 50 - jarak sensor */ if (jarakCm >= 50) tinggiAirCm = 0; else tinggiAirCm = 50 - jarakCm; return tinggiAirCm; } /* ========================= SERVO MOTOR ========================= */ void Servo_SetAngle(uint8_t angle) { uint32_t pulse; if (angle > 180) angle = 180; pulse = SERVO_MIN_US + ((SERVO_MAX_US - SERVO_MIN_US) * angle / 180); __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pulse); } /* ========================= STATUS SISTEM ========================= */ StatusBanjir Get_Status(uint32_t tinggiAirCm, uint8_t rainHigh, uint8_t vibrationHigh) { if ((rainHigh == 0) && (vibrationHigh == 0) && (tinggiAirCm >= 0) && (tinggiAirCm <= 25)) { return STATUS_AMAN; } else if ((rainHigh == 1) && (vibrationHigh == 0) && (tinggiAirCm > 25) && (tinggiAirCm <= 40)) { return STATUS_WASPADA; } else if ((rainHigh == 1) && (vibrationHigh == 1) && (tinggiAirCm > 40) && (tinggiAirCm <= 50)) { return STATUS_BAHAYA; } return STATUS_AMAN; } void Output_Control(StatusBanjir status) { if (status == STATUS_AMAN) { HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_RESET); Servo_SetAngle(0); } else if (status == STATUS_WASPADA) { Servo_SetAngle(45); if ((HAL_GetTick() - lastBuzzerTick) >= BUZZER_INTERVAL_MS) { lastBuzzerTick = HAL_GetTick(); if (buzzerState == GPIO_PIN_RESET) buzzerState = GPIO_PIN_SET; else buzzerState = GPIO_PIN_RESET; HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, buzzerState); } } else if (status == STATUS_BAHAYA) { HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_SET); Servo_SetAngle(90); } } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ uint32_t tinggiAirCm = 0; uint8_t rainHigh = 0; uint8_t vibrationHigh = 0; StatusBanjir status; char line1[17]; char line2[17]; /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM2_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_4); Servo_SetAngle(0); LCD_Init(); LCD_Clear(); LCD_PrintLine(0, "Sistem Banjir"); LCD_PrintLine(1, "Mulai..."); HAL_Delay(1000); LCD_Clear(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { tinggiAirCm = Ultrasonic_Read_CM(); rainHigh = (HAL_GPIO_ReadPin(RAIN_GPIO_Port, RAIN_Pin) == GPIO_PIN_SET) ? 1 : 0; vibrationHigh = (HAL_GPIO_ReadPin(VIBRATION_GPIO_Port, VIBRATION_Pin) == GPIO_PIN_SET) ? 1 : 0; status = Get_Status(tinggiAirCm, rainHigh, vibrationHigh); Output_Control(status); if ((HAL_GetTick() - lastLcdUpdate) >= 300) { lastLcdUpdate = HAL_GetTick(); if (status == STATUS_AMAN) { snprintf(line1, sizeof(line1), "Status : AMAN"); } else if (status == STATUS_WASPADA) { snprintf(line1, sizeof(line1), "Status : WASPADA"); } else { snprintf(line1, sizeof(line1), "Status : BAHAYA"); } snprintf(line2, sizeof(line2), "Ktg air :%3lu cm", tinggiAirCm); LCD_PrintLine(0, line1); LCD_PrintLine(1, line2); } HAL_Delay(50); } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ 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(); } /** Initializes the CPU, AHB and APB buses clocks */ 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(); } } /** * @brief TIM2 Initialization Function * @param None * @retval None */ static void MX_TIM2_Init(void) { /* USER CODE BEGIN TIM2_Init 0 */ /* USER CODE END TIM2_Init 0 */ TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; TIM_IC_InitTypeDef sConfigIC = {0}; /* USER CODE BEGIN TIM2_Init 1 */ /* USER CODE END TIM2_Init 1 */ htim2.Instance = TIM2; htim2.Init.Prescaler = 7; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 65535; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) { Error_Handler(); } if (HAL_TIM_IC_Init(&htim2) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_4) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM2_Init 2 */ /* USER CODE END TIM2_Init 2 */ HAL_TIM_MspPostInit(&htim2); } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* USER CODE BEGIN MX_GPIO_Init_1 */ /* USER CODE END MX_GPIO_Init_1 */ /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(TRIGGER_GPIO_Port, TRIGGER_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOB, D4_Pin|D5_Pin|D6_Pin|BUZZER_Pin |D7_Pin|EN_Pin|RS_Pin, GPIO_PIN_RESET); /*Configure GPIO pins : RAIN_Pin VIBRATION_Pin */ GPIO_InitStruct.Pin = RAIN_Pin|VIBRATION_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pin : TRIGGER_Pin */ GPIO_InitStruct.Pin = TRIGGER_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(TRIGGER_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pins : D4_Pin D5_Pin D6_Pin BUZZER_Pin D7_Pin EN_Pin RS_Pin */ GPIO_InitStruct.Pin = D4_Pin|D5_Pin|D6_Pin|BUZZER_Pin |D7_Pin|EN_Pin|RS_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pin : BUTTON_Pin */ 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); /* EXTI interrupt init*/ HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); /* USER CODE BEGIN MX_GPIO_Init_2 */ /* USER CODE END MX_GPIO_Init_2 */ } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */
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 ultrasonik sebagai pengganti sensor jarak laser (karena tidak ada library) 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 aman terjadi ketika:
- Rain Sensor = Low (tidak terdeteksi hujan)
- Vibration Sensor = Low (tidak terdapat getaran signifikan)
- Ketinggian air = 0 – 25 cm
Pada kondisi ini debit air masih berada pada batas normal sehingga tidak diperlukan tindakan khusus. Mikrokontroler akan mempertahankan posisi motor servo pada sudut 0° yang menandakan pintu air dalam kondisi tertutup atau bukaan minimum. Buzzer berada dalam keadaan mati dan LCD menampilkan informasi:
Status : AMANKtg Air : xx cm
B. Kondisi Waspada
Kondisi waspada terjadi ketika:
- Rain Sensor = High (terdeteksi hujan)
- Vibration Sensor = Low
- Ketinggian air = 25 – 40 cm
Kondisi ini menunjukkan adanya peningkatan debit air akibat hujan sehingga diperlukan tindakan antisipasi. Mikrokontroler akan mengaktifkan buzzer secara putus-putus sebagai tanda peringatan awal. Motor servo akan bergerak ke posisi 45° sehingga pintu air terbuka sebagian untuk membantu memperlancar aliran air. LCD akan menampilkan informasi:
Status : WASPADAKtg Air : xx cm
C. Kondisi Bahaya
Kondisi bahaya terjadi ketika:
- Rain Sensor = High
- Vibration Sensor = High
- Ketinggian air = 40 – 50 cm
Kondisi ini menunjukkan bahwa debit air sudah mencapai batas kritis dan terdapat indikasi aliran yang deras. Mikrokontroler akan mengaktifkan buzzer secara kontinu sebagai alarm bahaya. Motor servo akan bergerak ke posisi 90° sehingga pintu air terbuka penuh untuk mempercepat pembuangan air. LCD akan menampilkan informasi:
Status : BAHAYAKtg Air : xx cm
Dengan mekanisme tersebut, sistem mampu memberikan respons otomatis terhadap perubahan kondisi lingkungan sehingga dapat membantu mengurangi risiko terjadinya banjir.
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