Laporan Akhir Modul 4



 LAPORAN AKHIR

a. Prosedur[kembali]

  1. Menyiapkan seluruh komponen prototype, meliputi mikrokontroler STM32, sensor turbidity, sensor ultrasonik, flow sensor, pompa DC, relay, OLED, LED indikator, buzzer, serta catu daya.

  2. Mengisi wadah sumber dengan air yang akan diproses, kemudian mengalirkannya melalui saringan kasar menuju settling tank untuk proses pengendapan partikel.

  3. Menyalakan sistem sehingga STM32 melakukan inisialisasi seluruh sensor dan perangkat keluaran.

  4. Sensor turbidity membaca tingkat kekeruhan air sebelum proses filtrasi dan mengirimkan data ke mikrokontroler.

  5. Sensor ultrasonik mengukur ketinggian air pada tandon distribusi untuk mengetahui kondisi volume air.

  6. Flow sensor memantau debit aliran air setelah melewati proses filtrasi menuju tandon.

  7. STM32 memproses seluruh data sensor dengan prioritas:

    • Ketinggian air (sensor ultrasonik),

    • Kekeruhan air (sensor turbidity),

    • Debit aliran air (flow sensor).

  8. Apabila tandon penuh (jarak ≤ 6 cm), sistem mematikan pompa, menyalakan LED merah dan buzzer, serta menampilkan status "Penuh" pada OLED.

  9. Apabila nilai kekeruhan air melebihi 25 NTU, sistem mematikan pompa, menyalakan LED kuning dan buzzer, serta menampilkan status "Air Keruh" pada OLED.

  10. Apabila debit aliran air kurang dari 1,3 L/menit, sistem mematikan pompa, menyalakan LED merah dan buzzer, serta menampilkan status "Flow Kecil" pada OLED.

  11. Apabila seluruh parameter berada dalam kondisi normal (jarak > 6 cm, kekeruhan ≤ 25 NTU, dan debit ≥ 1,3 L/menit), sistem mengaktifkan pompa, menyalakan LED hijau, mematikan buzzer, dan menampilkan status "Normal" pada OLED.

  12. Proses monitoring dan pengendalian dilakukan secara berulang (real-time) selama sistem beroperasi untuk memastikan penyediaan air bersih berlangsung dengan aman dan optimal.

 b. Hardware [kembali]

1.  STM32F103C8T6 (Blue Pill)
2. Sensor Turbidity
3. Sensor Ultrasonik HC-SR04
4. Flow Sensor YF-S201
5. Modul Relay 1 Channel 5V
6. Pompa Air DC 5 V

7. OLED Display 0.96" (I2C)
8. Buzzer aktif 5V
9. LED indikator (Hijau, Kuning, Merah)

10. Resistor

 c. Rangkaian Simulasi dan Prinsip Kerja [kembali]

Gambar Prototype

Gambar Rangkaian Simulasi

Prinsip Kerja Rangkaian:

Rangkaian pada Proteus dirancang untuk mensimulasikan sistem Smart Clean Water Supply System with Settling Tank and Monitoring Sensors yang dikendalikan oleh mikrokontroler STM32F103C8T6 (Blue Pill). STM32 berfungsi sebagai pusat pengolah data yang menerima masukan dari sensor turbidity, sensor ultrasonik HC-SR04, dan flow sensor, kemudian mengendalikan keluaran berupa relay, LED indikator, buzzer, dan OLED berdasarkan kondisi yang terdeteksi.

Sensor turbidity dihubungkan ke pin PA0 sebagai masukan analog (ADC) untuk membaca tingkat kekeruhan air. Nilai analog tersebut dikonversi oleh ADC internal STM32 menjadi nilai digital yang kemudian diproses untuk menentukan apakah air berada dalam kondisi normal atau melebihi batas kekeruhan yang telah ditentukan.

Sensor ultrasonik HC-SR04 menggunakan pin PA1 sebagai sinyal Trigger dan PA2 sebagai sinyal Echo. STM32 mengirimkan pulsa pemicu (trigger) ke sensor, kemudian menghitung waktu pantulan gelombang ultrasonik yang diterima pada pin echo untuk memperoleh jarak permukaan air terhadap sensor. Informasi ini digunakan untuk mengetahui kondisi ketinggian air pada tandon.

Flow sensor dihubungkan ke pin PA3 sebagai masukan interrupt (external interrupt). Setiap pulsa yang dihasilkan oleh sensor akibat aliran air akan dihitung oleh STM32 untuk menentukan debit aliran dalam satuan liter per menit (L/menit). Metode interrupt dipilih agar pembacaan debit lebih akurat dibandingkan menggunakan teknik polling.

Hasil pembacaan ketiga sensor diproses berdasarkan prioritas yang telah ditentukan. Prioritas pertama adalah kondisi tandon yang dipantau menggunakan sensor ultrasonik. Apabila tandon telah penuh (jarak ≤ 6 cm), STM32 akan mematikan pompa melalui relay, mengaktifkan LED merah dan buzzer sebagai indikator peringatan. Jika kondisi tandon masih aman, sistem akan memeriksa nilai kekeruhan air. Apabila nilai kekeruhan melebihi 25 NTU, pompa dimatikan, LED kuning dan buzzer diaktifkan sebagai tanda bahwa kualitas air tidak memenuhi syarat. Selanjutnya, apabila debit aliran air yang dibaca flow sensor kurang dari 1,3 L/menit, sistem akan mematikan pompa, menyalakan LED merah dan buzzer sebagai indikasi adanya gangguan aliran.

Sebaliknya, apabila seluruh parameter berada pada kondisi normal, yaitu tandon belum penuh, tingkat kekeruhan air tidak melebihi 25 NTU, dan debit aliran minimal 1,3 L/menit, STM32 akan mengaktifkan relay sehingga pompa dapat bekerja, menyalakan LED hijau sebagai indikator normal, mematikan buzzer, serta menampilkan informasi hasil monitoring pada OLED. Dengan demikian, simulasi pada Proteus dapat menggambarkan cara kerja sistem penyediaan air bersih secara otomatis sebelum diimplementasikan pada perangkat keras sebenarnya.

 d. Flowchart dan Listing Program [kembali]

Flowchart


Listing Program
/* USER CODE BEGIN Header */
/*
  Project : Sistem Kontrol Air Bersih Berbasis STM32
  MCU     : STM32F103C8T6 / Blue Pill

  Pin:
  PA0  = Turbidity Sensor OUT / ADC1_IN0
  PA1  = HC-SR04 TRIG
  PA2  = HC-SR04 ECHO
  PA3  = Flow Sensor OUT / EXTI3

  PB0  = LED Hijau
  PB1  = LED Kuning
  PB2  = LED Merah
  PB10 = Buzzer
  PB12 = Relay Pompa / Motor

  Prioritas:
  1. Ultrasonic
  2. Turbidity
  3. Flow
*/
/* USER CODE END Header */

#include "main.h"
#include <stdio.h>
#include <string.h>

/* ===================== HANDLE PERIPHERAL ===================== */

ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim2;

/* ===================== SETTING BATAS SISTEM ===================== */

#define FLOW_LIMIT_LMIN          1.3f
#define TURBIDITY_LIMIT_NTU      25.0f
#define ULTRASONIC_LIMIT_CM      6.0f
#define ULTRASONIC_HYST_START_CM 8.0f

/*
  Relay aktif HIGH:
  1 = PB12 HIGH  -> Pompa ON
      PB12 LOW   -> Pompa OFF

  Kalau relay kamu aktif LOW, ubah menjadi 0.
*/
#define RELAY_ACTIVE_HIGH        1

/*
  Flow sensor YF-S201:
  Flow L/min = Frequency / 7.5
*/
#define FLOW_CALIBRATION_FACTOR  7.5f

/* ===================== VARIABEL GLOBAL ===================== */

volatile uint32_t flowPulseCount = 0;

uint32_t turbidityADC = 0;
float turbidityNTU = 0.0f;
float flowRate = 0.0f;
float distanceCM = 0.0f;
uint32_t lastFlowTick = 0;

uint8_t flowReady = 0;
uint8_t isTankFullFlag = 0;

char systemStatus[30];

/* ===================== PROTOTYPE FUNCTION ===================== */

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM2_Init(void);

void delay_us(uint16_t us);

uint32_t Read_ADC_Turbidity(void);
float Read_Turbidity_NTU(void);
float Read_Ultrasonic_CM(void);
float Read_Flow_LMin(void);

void Pump_ON(void);
void Pump_OFF(void);

void Green_LED_ON(void);
void Green_LED_OFF(void);
void Yellow_LED_ON(void);
void Yellow_LED_OFF(void);
void Red_LED_ON(void);
void Red_LED_OFF(void);
void All_LED_OFF(void);

void Buzzer_ON(void);
void Buzzer_OFF(void);

void System_Logic(float flow, float turbidity, float distance);

void Error_Handler(void);

/* ===================== MAIN PROGRAM ===================== */

int main(void)
{
  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_TIM2_Init();

  HAL_ADCEx_Calibration_Start(&hadc1);
  HAL_TIM_Base_Start(&htim2);

  Pump_OFF();
  All_LED_OFF();
  Buzzer_OFF();

  strcpy(systemStatus, "START");

    /* =================================================================
       PROSES STABILISASI AWAL SIMULASI PROTEUS (ANTI-KEDIP STARTUP)
       ================================================================= */
    HAL_Delay(100);            // Berikan waktu model Proteus siap

    lastFlowTick = HAL_GetTick(); // Inisialisasi sebelum loop
    flowReady = 0;

    while (1)
    {
      distanceCM   = Read_Ultrasonic_CM();
      turbidityNTU = Read_Turbidity_NTU();

      if (HAL_GetTick() - lastFlowTick >= 1000)
      {
        flowRate = Read_Flow_LMin();
        lastFlowTick = HAL_GetTick();
        flowReady = 1;
      }

      if (flowReady == 1)
      {
        System_Logic(flowRate, turbidityNTU, distanceCM);
      }
      else
      {
        Pump_OFF();
        All_LED_OFF();
        Buzzer_OFF();
      }

      HAL_Delay(100);
    }
}
/* ===================== DELAY MICROSECOND ===================== */

void delay_us(uint16_t us)
{
  __HAL_TIM_SET_COUNTER(&htim2, 0);

  while (__HAL_TIM_GET_COUNTER(&htim2) < us)
  {
  }
}

/* ===================== SENSOR TURBIDITY ===================== */

uint32_t Read_ADC_Turbidity(void)
{
  uint32_t adcValue = 0;

  HAL_ADC_Start(&hadc1);

  if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK)
  {
    adcValue = HAL_ADC_GetValue(&hadc1);
  }

  HAL_ADC_Stop(&hadc1);

  return adcValue;
}

float Read_Turbidity_NTU(void)
{
  uint32_t adcValue;
  float ntu;

  adcValue = Read_ADC_Turbidity();
  turbidityADC = adcValue;

  /*
    Mapping Proteus:
    ADC 0    = 0 NTU    -> air bersih
    ADC 4095 = 100 NTU  -> air sangat keruh

    Jika sensor turbidity kamu terbaca terbalik, pakai rumus alternatif
    yang ada di komentar bawah.
  */

  ntu = ((float)adcValue * 100.0f) / 4095.0f;

  /*
    Rumus alternatif jika sensor terbaca terbalik:

    ntu = ((4095.0f - (float)adcValue) * 100.0f) / 4095.0f;
  */

  if (ntu < 0.0f)
  {
    ntu = 0.0f;
  }

  if (ntu > 100.0f)
  {
    ntu = 100.0f;
  }

  return ntu;
}

/* ===================== SENSOR ULTRASONIC HC-SR04 (REVISI) ===================== */
float Read_Ultrasonic_CM(void)
{
  uint32_t echoTime = 0;
  float distance = 999.0f;

  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
  delay_us(5);

  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
  delay_us(20);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);

  /*
    Tunggu ECHO HIGH
  */
  __HAL_TIM_SET_COUNTER(&htim2, 0);

  while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) == GPIO_PIN_RESET)
  {
    if (__HAL_TIM_GET_COUNTER(&htim2) > 30000)
    {
      return 999.0f;
    }
  }

  /*
    Hitung durasi ECHO HIGH
  */
  __HAL_TIM_SET_COUNTER(&htim2, 0);

  while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) == GPIO_PIN_SET)
  {
    if (__HAL_TIM_GET_COUNTER(&htim2) > 30000)
    {
      return 999.0f;
    }
  }

  echoTime = __HAL_TIM_GET_COUNTER(&htim2);

  distance = echoTime / 58.0f;

  return distance;
}
/* ===================== SENSOR FLOW ===================== */

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if (GPIO_Pin == GPIO_PIN_3)
  {
    flowPulseCount++;
  }
}

float Read_Flow_LMin(void)
{
  uint32_t pulseCopy = 0;
  float flow = 0.0f;

  __disable_irq();
  pulseCopy = flowPulseCount;
  flowPulseCount = 0;
  __enable_irq();

  flow = (float)pulseCopy / FLOW_CALIBRATION_FACTOR;

  return flow;
}
/* ===================== OUTPUT CONTROL ===================== */

void Pump_ON(void)
{
#if RELAY_ACTIVE_HIGH
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
#else
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
#endif
}

void Pump_OFF(void)
{
#if RELAY_ACTIVE_HIGH
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
#else
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
#endif
}

void Green_LED_ON(void)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
}

void Green_LED_OFF(void)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
}

void Yellow_LED_ON(void)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
}

void Yellow_LED_OFF(void)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}

void Red_LED_ON(void)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
}

void Red_LED_OFF(void)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
}

void All_LED_OFF(void)
{
  Green_LED_OFF();
  Yellow_LED_OFF();
  Red_LED_OFF();
}

void Buzzer_ON(void)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
}

void Buzzer_OFF(void)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
}

/* ===================== LOGIKA SISTEM PRIORITAS ===================== */

void System_Logic(float flow, float turbidity, float distance)
{
  All_LED_OFF();

  /*
    PRIORITAS 1: ULTRASONIC
    Jika jarak <= 3 cm:
    Motor mati
    LED merah ON
    Buzzer ON
  */
  if (distance > 0.0f && distance <= ULTRASONIC_LIMIT_CM)
  {
    Pump_OFF();
    Red_LED_ON();
    Buzzer_ON();

    strcpy(systemStatus, "Penuh");
    return;
  }

  /*
    PRIORITAS 2: TURBIDITY
    Jika turbidity > 25 NTU:
    Motor mati
    LED kuning ON
    Buzzer ON
  */
  if (turbidity > TURBIDITY_LIMIT_NTU)
  {
    Pump_OFF();

    Green_LED_OFF();
    Yellow_LED_ON();
    Red_LED_OFF();

    Buzzer_ON();

    strcpy(systemStatus, "AIR KERUH");
    return;
  }

  /*
    PRIORITAS 3: FLOW
    Jika flow < 1.3 L/min:
    Motor mati
    LED merah ON
    Buzzer ON
  */
  if (flow < FLOW_LIMIT_LMIN)
  {
    Pump_OFF();

    Green_LED_OFF();
    Yellow_LED_OFF();
    Red_LED_ON();

    Buzzer_ON();

    strcpy(systemStatus, "FLOW KECIL");
    return;
  }

  /*
    NORMAL
    Jika ultrasonic > 3 cm,
    turbidity <= 25 NTU,
    flow >= 1.3 L/min
  */
  Pump_ON();

  Green_LED_ON();
  Yellow_LED_OFF();
  Red_LED_OFF();

  Buzzer_OFF();

  strcpy(systemStatus, "NORMAL");
}

/* ===================== CLOCK CONFIG ===================== */

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /*
    Menggunakan HSI internal.
    Cocok untuk Proteus tanpa crystal eksternal.

    HSI = 8 MHz
    PLL Source = HSI / 2 = 4 MHz
    PLL x16 = 64 MHz
    SYSCLK = 64 MHz
  */

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;

  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_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }

  /*
    ADC Clock = 64 MHz / 6 = 10.67 MHz
  */
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;

  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/* ===================== ADC1 INIT ===================== */

static void MX_ADC1_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};

  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;

  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;

  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

/* ===================== TIM2 INIT ===================== */

static void MX_TIM2_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /*
    SYSCLK = 64 MHz
    TIM2 Prescaler = 63
    Timer clock = 1 MHz
    1 count = 1 us
  */

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 63;
  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_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

/* ===================== GPIO INIT ===================== */

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*
    Kondisi awal output
  */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);

  HAL_GPIO_WritePin(GPIOB,
                    GPIO_PIN_0 |
                    GPIO_PIN_1 |
                    GPIO_PIN_2 |
                    GPIO_PIN_10 |
                    GPIO_PIN_12,
                    GPIO_PIN_RESET);

  /*
    PA0 = Turbidity ADC input
  */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*
    PA1 = Ultrasonic TRIG
  */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*
    PA2 = Ultrasonic ECHO
  */
  GPIO_InitStruct.Pin  = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN; /* ← ganti dari GPIO_NOPULL */
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*
    PA3 = Flow sensor interrupt
  */
  GPIO_InitStruct.Pin = GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*
    PB0  = LED Hijau
    PB1  = LED Kuning
    PB2  = LED Merah
    PB10 = Buzzer
    PB12 = Relay Pompa
  */
  GPIO_InitStruct.Pin = GPIO_PIN_0 |
                         GPIO_PIN_1 |
                         GPIO_PIN_2 |
                         GPIO_PIN_10 |
                         GPIO_PIN_12;

  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);

  /*
    Interrupt PA3 untuk flow sensor
  */
  HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI3_IRQn);
}

/* ===================== ERROR HANDLER ===================== */

void Error_Handler(void)
{
  __disable_irq();

  while (1)
  {
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_2);
    HAL_Delay(300);
  }
}

e. Video Demo [kembali]

Video Penjelesan Prinsip Kerja

Video Demo

f. Kesimpulan dan Saran [kembali]

Kesimpulan

  1. Prototype Smart Clean Water Supply System with Settling Tank and Monitoring Sensors berhasil dirancang sebagai sistem penyediaan air bersih pascabencana berbasis mikrokontroler STM32F103C8T6.
  2. Sistem mampu memantau kualitas air, ketinggian air pada tandon, dan debit aliran air secara otomatis menggunakan sensor turbidity, sensor ultrasonik, dan flow sensor.
  3. Integrasi sensor dengan sistem kendali memungkinkan pompa bekerja secara otomatis serta memberikan peringatan melalui LED, buzzer, dan OLED ketika terdeteksi kondisi yang tidak sesuai.
  4. Penggunaan settling tank dan sistem monitoring membantu meningkatkan efektivitas proses penyediaan air bersih sehingga lebih aman untuk didistribusikan kepada masyarakat terdampak bencana.
  5. Prototype ini menunjukkan bahwa teknologi berbasis mikrokontroler dapat menjadi solusi sederhana dan efisien dalam mendukung penyediaan air bersih pada kondisi darurat atau pascabencana.

Saran

  1. Menambahkan sistem filtrasi yang lebih lengkap agar kualitas air hasil pengolahan semakin baik dan memenuhi standar air bersih.
  2. Mengembangkan sistem dengan sumber energi alternatif, seperti panel surya atau baterai cadangan, sehingga tetap dapat beroperasi saat pasokan listrik terganggu akibat bencana.
  3. Melakukan kalibrasi dan pengujian sensor secara berkala untuk meningkatkan akurasi pembacaan pada berbagai kondisi air pascabencana.
  4. Mengembangkan prototype menjadi skala yang lebih besar sehingga dapat diterapkan sebagai sistem penyediaan air bersih sementara di lokasi pengungsian atau daerah terdampak bencana.
g. Download file [kembali]

    

Komentar

Postingan populer dari blog ini

2.12 Voltage-Multiplier Circuits

Tugas Besar - Pengamanan ATM

Modul 1- Potensiometer & Tahanan Geser dan Jembatan Wheatstone