Laporan Akhir 2

 



1. Prosedur [Kembali]

  1. Menyiapkan alat dan bahan.
  2. Merangkai komponen pada breadboard sesuai dengan gambar rangkaian percobaan.
  3. Menghubungkan masing masing pin input output.
  4. Mengunggah program menggunakan ST-LINK ke mikrokontroler.
  5. Jalankan Rangkaian

2. Hardware dan Diagram Blok [Kembali]

  • STM32 Nucleo G474RE
  • Sensor LDR
  • Push Button
  • Motor Servo
  • Breadboard
  • Adaptor

3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]



Prinsip Kerja:

Rangkaian ini menerapkan sistem kendali berbasis kondisi (conditional control) menggunakan STM32 guna mengoptimalkan konsumsi daya pada lampu jalan. LDR berfungsi sebagai sakelar fotoselektif yang menentukan fase aktif sistem, sedangkan sensor PIR bertindak sebagai pemicu (trigger) berbasis aktivitas subjek. Integrasi kedua sensor ini memastikan LED hanya mengonsumsi energi saat lingkungan gelap dan terdapat kebutuhan pencahayaan (pergerakan), dengan tambahan fitur manual override melalui push button untuk fleksibilitas operasional.

4. Flowchart dan Listing Program [Kembali]



Flowchart


Listing program : 


#include "main.h"

/* ================= HANDLE ================= */
ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim2;

/* ================= VARIABLE ================= */
volatile uint8_t emergency_mode = 0;
volatile uint8_t button_pressed = 0;
uint32_t last_motion_time = 0;
uint8_t calibration_mode = 0;

/* ================= PARAMETER ================= */
#define LDR_THRESHOLD_HIGH   1800  // Ambang siang
#define LDR_THRESHOLD_LOW    1500  // Ambang malam
#define MOTION_TIMEOUT       8000  // 8 detik timeout gerakan
#define FADE_STEP            20    // Kecepatan fade
#define CALIBRATION_TIME     5000  // 5 detik kalibrasi

#define LED_OFF              0
#define LED_DIM              80
#define LED_MEDIUM           400
#define LED_FULL             950
#define LED_EMERGENCY        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 SENSOR → PA1 */
    GPIO_InitStruct.Pin  = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* EMERGENCY BUTTON → PB0 (PULL-UP + INTERRUPT) */
    GPIO_InitStruct.Pin  = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* CALIBRATION 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);

    /* STATUS LED → PB5 */
    GPIO_InitStruct.Pin  = GPIO_PIN_5;
    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);

    /* LED PWM → PA5 (TIM2_CH1) */
    GPIO_InitStruct.Pin       = GPIO_PIN_5;
    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* IRQ untuk tombol */
    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;
    hadc1.Init.NbrOfConversion = 1;

    HAL_ADC_Init(&hadc1);

    ADC_ChannelConfTypeDef sConfig = {0};
    sConfig.Channel = ADC_CHANNEL_0;  // PA0 untuk LDR
    sConfig.Rank = ADC_REGULAR_RANK_1;
    sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES;

    HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}

/* ================= PWM ================= */
void MX_TIM2_Init(void)
{
    __HAL_RCC_TIM2_CLK_ENABLE();

    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 48 - 1;  // 1MHz timer clock
    htim2.Init.Period = 1000 - 1;
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

    HAL_TIM_PWM_Init(&htim2);

    TIM_OC_InitTypeDef sConfigOC = {0};
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

    HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
}

/* ================= INTERRUPT ================= */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_0)  // Emergency button
    {
        emergency_mode = !emergency_mode;
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
    }
    else if (GPIO_Pin == GPIO_PIN_1)  // Calibration button
    {
        calibration_mode = 1;
    }
}

/* ================= HELPER ================= */
uint16_t read_LDR(void)
{
    HAL_ADC_Start(&hadc1);
    if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK)
    {
        return HAL_ADC_GetValue(&hadc1);
    }
    return 0;
}

void set_LED(uint16_t value)
{
    if (value > 1000) value = 1000;
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, value);
}

void fade_LED(uint16_t target, uint32_t delay_ms)
{
    uint16_t current = __HAL_TIM_GET_COMPARE(&htim2, TIM_CHANNEL_1);
    
    while (abs((int)current - (int)target) > FADE_STEP)
    {
        if (current < target)
            current += FADE_STEP;
        else
            current -= FADE_STEP;
        
        set_LED(current);
        HAL_Delay(delay_ms);
    }
    set_LED(target);
}

/* ================= KALIBRASI ================= */
uint16_t calibrate_LDR_threshold(void)
{
    uint32_t start_time = HAL_GetTick();
    uint32_t sum = 0;
    uint16_t samples = 0;
    
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);  // Status LED ON
    
    while (HAL_GetTick() - start_time < CALIBRATION_TIME)
    {
        sum += read_LDR();
        samples++;
        HAL_Delay(50);
    }
    
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
    calibration_mode = 0;
    
    return (samples > 0) ? (sum / samples) : LDR_THRESHOLD_HIGH;
}

/* ================= MAIN ================= */
int main(void)
{
    uint16_t ldr_threshold = LDR_THRESHOLD_HIGH;
    uint32_t calibration_start = 0;
    
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();
    MX_TIM2_Init();

    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
    set_LED(LED_OFF);

    while (1)
    {
        /* ===== KALIBRASI ===== */
        if (calibration_mode)
        {
            if (calibration_start == 0)
            {
                calibration_start = HAL_GetTick();
                ldr_threshold = calibrate_LDR_threshold();
            }
            continue;
        }

        /* ===== EMERGENCY MODE ===== */
        if (emergency_mode)
        {
            fade_LED(LED_EMERGENCY, 10);
            HAL_Delay(100);
            continue;
        }

        /* ===== BACA SENSOR ===== */
        uint16_t ldr_value = read_LDR();
        uint8_t pir_state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);

        /* ===== LOGIKA KONTROL ===== */
        if (ldr_value < ldr_threshold)
        {
            // SIANG - Matikan lampu
            fade_LED(LED_OFF, 20);
        }
        else
        {
            // MALAM
            if (pir_state == GPIO_PIN_SET)
            {
                last_motion_time = HAL_GetTick();
                fade_LED(LED_FULL, 15);
            }
            else if (HAL_GetTick() - last_motion_time < MOTION_TIMEOUT)
            {
                // Masih dalam timeout gerakan
                fade_LED(LED_MEDIUM, 25);
            }
            else
            {
                // Timeout - dim
                fade_LED(LED_DIM, 30);
            }
        }

        HAL_Delay(80);
    }
}


5. Video Demo [Kembali]

6. Kondisi [Kembali]

Buatlah rangkaian seperti pada gambar percobaan 3 dengan kondisi ketika Infrared sensor tidak mendeteksi benda dan sensor Touch  mendeteksi sentuhan, maka LED akan menyala

7. Analisa [Kembali]



8. Download File [Kembali]

 


Komentar

Postingan populer dari blog ini

modul 1

Modul 2 Mikro

Kontrol Rumah Kaca pada Greenhouse