Laporan Akhir 2



1. Prosedur[Kembali]

  1. Pahami terlebih dahulu kondisi yang akan digunakan
  2. Buka web Wokwi
  3. Persiapkan alat dan bahan
  4. Buat rangkaian sesuai dengan kondisi dan modul
  5. Buat kode program untuk mengoperasikan rangkaian tersebut sesuai dengan kondisi 
  6. Jalankan simulasi rangkaian.  
  7. Proses selesai

2. Hardware dan Diagram Blok[Kembali]

    a. Hardware


STM32 NUCLEO-G474RE


PIR Sensor


Push Button


LED


Resistor



Relay


LDR Sensor

Breadboard

Diagram Blok

3. Rangkaian Simulasi dan Prinsip Kerja[Kembali]



Rangkaian Simulasi


Rangkaian
Prinsip Kerja

Pada rangkaian tersebut, LDR bekerja sebagai sensor cahaya yang nilai resistansinya berubah terhadap intensitas cahaya. Saat kondisi terang (siang hari), resistansi LDR menurun sehingga tegangan pada titik pembagi tegangan berubah. Sebaliknya, saat kondisi gelap atau mendung (yang diasumsikan sebagai potensi hujan), resistansi LDR meningkat sehingga tegangan keluarannya juga berubah. Tegangan ini kemudian dikirim ke pin input mikrokontroler pada board NUCLEO C031C6, biasanya melalui pin ADC agar bisa dibaca sebagai nilai analog.

Mikrokontroler kemudian melakukan pembacaan kontinu terhadap nilai tegangan dari LDR. Di dalam program, terdapat nilai ambang (threshold) tertentu untuk membedakan kondisi terang dan gelap. Ketika intensitas cahaya tinggi (cuaca cerah), mikrokontroler akan mengirimkan sinyal PWM ke motor servo sehingga servo bergerak membuka jemuran. Sebaliknya, ketika cahaya rendah (gelap atau mendung), mikrokontroler menganggap kondisi tidak ideal untuk menjemur, lalu mengubah sinyal PWM sehingga servo bergerak menutup atau menarik jemuran ke tempat terlindung.

Motor servo sendiri dikendalikan menggunakan sinyal PWM, di mana lebar pulsa menentukan sudut posisi servo. Dengan demikian, perubahan kondisi cahaya akan langsung memengaruhi posisi mekanik jemuran melalui kendali mikrokontroler.

Selain itu, push button pada rangkaian berfungsi sebagai kontrol manual, misalnya untuk memaksa posisi servo terbuka/tertutup atau sebagai reset sistem. Secara keseluruhan, alur kerjanya adalah: LDR mendeteksi intensitas cahaya → sinyal analog dikirim ke mikrokontroler → diproses berdasarkan threshold → mikrokontroler mengontrol servo → jemuran otomatis membuka saat terang dan menutup saat gelap.

4. Flowchart dan Listing Program[Kembali]

Flowchart
Listing Program:

#include "main.h"
// HANDLE
ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim3;
// VARIABLE
volatile uint8_t emergency_mode = 0;
uint32_t last_motion_time = 0;
// fallback tombol
uint8_t last_button_state = 1;
// PARAMETER
#define LDR_THRESHOLD 2000
#define MOTION_TIMEOUT 5000
#define LED_OFF 0
#define LED_DIM 100
#define LED_FULL 1000
// ================= CLOCK =================
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;
 HAL_RCC_OscConfig(&RCC_OscInitStruct);
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_SYSCLK;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
}
// ================= GPIO =================
void MX_GPIO_Init(void)
{
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 // PIR → PA1
GPIO_InitStruct.Pin = GPIO_PIN_1;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 // BUTTON → PB1 (PULL-UP + INTERRUPT)
 GPIO_InitStruct.Pin = GPIO_PIN_1;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 // LED PWM → PA6
 GPIO_InitStruct.Pin = GPIO_PIN_6;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 // IRQ untuk PB1 (EXTI0_1)
 HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
}
// ================= ADC =================
void MX_ADC1_Init(void)
{
 __HAL_RCC_ADC_CLK_ENABLE();

hadc1.Instance = ADC1;
 hadc1.Init.Resolution = ADC_RESOLUTION_12B;
 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
 hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
 hadc1.Init.ContinuousConvMode = DISABLE;
 HAL_ADC_Init(&hadc1);
 ADC_ChannelConfTypeDef sConfig = {0};
 sConfig.Channel = ADC_CHANNEL_0;
 sConfig.Rank = ADC_REGULAR_RANK_1;
 HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
// ================= PWM =================
void MX_TIM3_Init(void)
{
 __HAL_RCC_TIM3_CLK_ENABLE();
htim3.Instance = TIM3;
 htim3.Init.Prescaler = 64;
 htim3.Init.Period = 1000;
 htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
 HAL_TIM_PWM_Init(&htim3);
 TIM_OC_InitTypeDef sConfigOC = {0};
 sConfigOC.OCMode = TIM_OCMODE_PWM1;
 sConfigOC.Pulse = 0;
 HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);
}
// ================= INTERRUPT =================
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
 if (GPIO_Pin == GPIO_PIN_1)
 {
 emergency_mode = !emergency_mode;
 }
}
// ================= HELPER =================
uint16_t read_LDR(void)
{
 HAL_ADC_Start(&hadc1);
 HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
 return HAL_ADC_GetValue(&hadc1);
}

void set_LED(uint16_t value)
{
 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, value);
}
// ================= MAIN =================
int main(void)
{
 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();
 MX_ADC1_Init();
 MX_TIM3_Init();
 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
while (1)
 {
 // ===== FALLBACK BUTTON =====
 uint8_t current_button = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);
 if (last_button_state == 1 && current_button == 0)
 {
 emergency_mode = !emergency_mode;
 HAL_Delay(50);
 }
 last_button_state = current_button;
 // ===== MODE DARURAT =====
 if (emergency_mode)
 {
 set_LED(LED_OFF);
 continue;
 }
 uint16_t ldr = read_LDR();
 uint8_t pir = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);
 
 // ===== LOGIC BARU: Cahaya terang + PIR = LED MATI =====
 if (ldr < LDR_THRESHOLD && pir == GPIO_PIN_SET)  // Cahaya terang (LDR rendah) + gerakan
 {
 set_LED(LED_OFF);
 last_motion_time = HAL_GetTick();
 }
 else if (ldr < LDR_THRESHOLD)  // Hanya cahaya terang (tanpa gerakan)
 {
 // Cek timeout gerakan
 if (HAL_GetTick() - last_motion_time < MOTION_TIMEOUT)
 {
  set_LED(LED_OFF);  // Masih ada gerakan (timeout belum habis)
 }
 else
 {
  set_LED(LED_DIM);  // Cahaya terang tapi tidak ada gerakan
 }
 }
 else  // MALAM (LDR tinggi)
 {
 if (pir == GPIO_PIN_SET)
 {
 last_motion_time = HAL_GetTick();
 set_LED(LED_FULL);
 }
 else if (HAL_GetTick() - last_motion_time < MOTION_TIMEOUT)
 {
 set_LED(LED_FULL);  // Masih ada gerakan
 }
 else
 {
 set_LED(LED_DIM);
 }
 }
 HAL_Delay(100);
}
}





5. Video Demo[Kembali]



6. Kondisi[Kembali]

Buatlah rangkaian seperti pada gambar percobaan 2

8. Download File[Kembali]

Download Datasheet STM32 Nucleo-G474RE (klik disini)

Download Datasheet LDR Sensor (klik disini)

Download Datasheet Motor Servo (klik disini)

Download Datasheet Push Button (klik disini)

Soal Analisa dan Kesimpulan Saran








Komentar

Postingan populer dari blog ini