LA1 Modul 2



1. Prosedur [Kembali]

1. Buka web WOKWI.COM dan cari STM 32 NUCLEO C031C6

2. Rangkai komponen sesuai dengan gambar rangkaian di modul

3. Klik pada Library Manager untuk membuat file baru yang bernama main.h dan main.c

4. Masukan program yang telah di buat sesuai kondisi pada kedua file tersebut

5. Simulasikan

2. Hardware dan Diagram Blok[Kembali]

  • STM NUCLEO

  • LDR sensor
  • PIR Sensor
  • LED


  • Buzzer
  • Resistor 
  • Heart Beat Sensor

Diagram blog

                            

3. Rangkaian Simulasi dan Prinsip Kerja[Kembali]






  • Prinsip Kerja Sistem Lampu Jalan Otomatis 

    1. Inisialisasi Sistem:

      • Mikrokontroler STM32 (misalnya STM32F4) melakukan inisialisasi pada pin GPIO yang terhubung ke sensor PIR (sebagai input digital), sensor LDR atau Potensiometer yang mensimulasikan LDR (sebagai input analog pada kanal ADC), dan LED (sebagai output).

    2. Pembacaan Sensor:

      • Secara real-time, mikrokontroler membaca data dari sensor LDR/Potensiometer melalui kanal ADC untuk menentukan kondisi cahaya lingkungan.

      • Secara bersamaan, mikrokontroler membaca status sinyal digital dari sensor PIR untuk mendeteksi keberadaan gerakan.

    3. Logika Pengendalian Berdasarkan Kondisi Cahaya Terang:

      • Jika hasil pembacaan LDR/Potensiometer menunjukkan kondisi cahaya terang (tegangan input analog berada di bawah ambang batas tertentu), sistem masuk ke mode siang hari.

    4. Respon Terhadap Gerakan (Selama Cahaya Terang):

      • Dalam kondisi cahaya terang tersebut, jika sensor PIR mendeteksi adanya gerakan, mikrokontroler akan segera mengirimkan sinyal logika rendah (low) ke pin output LED.

      • Akibatnya, LED akan mati atau tetap mati. Sinyal low ini akan terus dipertahankan selama sensor PIR masih mendeteksi adanya gerakan (misalnya, orang yang lewat tersebut berhenti di depan sensor).

    5. Pemulihan Kondisi (Gerakan Hilang):

      • Setelah sensor PIR tidak lagi mendeteksi adanya gerakan (orang tersebut sudah lewat dan menjauh), mikrokontroler mendeteksi perubahan sinyal input PIR dari high menjadi low (aktif rendah pada banyak modul PIR).

      • Mikrokontroler kemudian akan kembali mengirimkan sinyal logika tinggi (high) ke pin output LED, sehingga LED akan kembali menyala.

4. Flowchart dan Listing Program[Kembali]

  • Flowchart


Listing program:

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

/* ================================================
   PERCOBAAN 4 - KONDISI 6
   LDR gelap + PIR ada gerakan → LED SANGAT TERANG
   selama 5 detik lalu mati
   ================================================ */

/* Handle */
ADC_HandleTypeDef  hadc1;
TIM_HandleTypeDef  htim3;

/* Variable */
uint16_t ldrValue       = 0;
uint8_t  pirState       = 0;
uint32_t lastMotionTime = 0;
uint8_t  ledActive      = 0;

/* Threshold LDR: nilai > threshold = GELAP */
#define LDR_GELAP_THRESHOLD   1000
#define LED_DURATION_MS       5000   // 5 detik
#define PWM_MAX_DUTY          999    // Duty cycle 100% = sangat terang

/* ================================================ */

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();
    MX_TIM3_PWM_Init();

    LED_Off(); // Pastikan LED mati saat awal

    while (1)
    {
        /* Baca sensor LDR via ADC */
        HAL_ADC_Start(&hadc1);
        HAL_ADC_PollForConversion(&hadc1, 100);
        ldrValue = HAL_ADC_GetValue(&hadc1);

        /* Baca sensor PIR */
        pirState = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);

        /* ====== LOGIKA KONDISI 6 ====== */
        /* Jika LED belum aktif, ruangan GELAP, dan ada GERAKAN */
        if (ledActive == 0 &&
            ldrValue > LDR_GELAP_THRESHOLD &&
            pirState == GPIO_PIN_SET)
        {
            printf("Gelap + Ada Gerakan! LED SANGAT TERANG selama 5 detik\r\n");
            LED_On();                          // Nyalakan LED (PWM 100%)
            lastMotionTime = HAL_GetTick();    // Catat waktu nyala
            ledActive = 1;
        }

        /* Matikan LED setelah 5 detik */
        if (ledActive == 1 &&
           (HAL_GetTick() - lastMotionTime) >= LED_DURATION_MS)
        {
            LED_Off();
            ledActive = 0;
            printf("LED mati setelah 5 detik\r\n");
        }

        /* Tampilkan status setiap 800ms */
        static uint32_t lastPrint = 0;
        if (HAL_GetTick() - lastPrint > 800)
        {
            printf("LDR: %4d | PIR: %d | LED: %s\r\n",
                   ldrValue, pirState, ledActive ? "NYALA" : "MATI");
            lastPrint = HAL_GetTick();
        }

        HAL_Delay(100);
    }
}

/* ================================================
   LED Control via PWM (TIM3_CH1 → PA6)
   ================================================ */
void LED_On(void)
{
    /* Set duty cycle 100% = sangat terang */
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, PWM_MAX_DUTY);
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
}

void LED_Off(void)
{
    HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
}

/* ================================================
   System Clock Config - HSI 48MHz
   ================================================ */
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.HSIDiv              = RCC_HSI_DIV1;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    HAL_RCC_OscConfig(&RCC_OscInitStruct);

    RCC_ClkInitStruct.ClockType      = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
    RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
}

/* ================================================
   GPIO Init
   PA0 → ADC (LDR)
   PA1 → Input (PIR)
   PA6 → AF TIM3_CH1 (LED PWM) ← diubah dari OUTPUT ke AF
   PB1 → Interrupt Falling (Push Button)
   ================================================ */
void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();

    /* PA6 → Alternate Function TIM3_CH1 untuk PWM */
    GPIO_InitStruct.Pin       = GPIO_PIN_6;
    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;       // AF Push-Pull
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;         // AF1 = TIM3 pada PA6
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* PA1 → Input digital untuk PIR */
    GPIO_InitStruct.Pin       = GPIO_PIN_1;
    GPIO_InitStruct.Mode      = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* PB1 → Interrupt falling edge untuk Push Button */
    GPIO_InitStruct.Pin       = GPIO_PIN_1;
    GPIO_InitStruct.Mode      = GPIO_MODE_IT_FALLING;
    GPIO_InitStruct.Pull      = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    HAL_NVIC_SetPriority(EXTI0_1_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
}

/* ================================================
   ADC1 Init - Channel 0 (PA0) untuk LDR
   ================================================ */
void MX_ADC1_Init(void)
{
    ADC_ChannelConfTypeDef sConfig = {0};

    hadc1.Instance                   = ADC1;
    hadc1.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV2;
    hadc1.Init.Resolution            = ADC_RESOLUTION_12B;
    hadc1.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
    hadc1.Init.ScanConvMode          = ADC_SCAN_DISABLE;
    hadc1.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;
    hadc1.Init.ContinuousConvMode    = DISABLE;
    hadc1.Init.NbrOfConversion       = 1;
    HAL_ADC_Init(&hadc1);

    sConfig.Channel      = ADC_CHANNEL_0;
    sConfig.Rank         = ADC_REGULAR_RANK_1;
    sConfig.SamplingTime = ADC_SAMPLETIME_79CYCLES_5;
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}

/* ================================================
   TIM3 PWM Init - CH1 pada PA6
   Frekuensi PWM ≈ 48MHz / (47+1) / (999+1) = 1 kHz
   ================================================ */
void MX_TIM3_PWM_Init(void)
{
    TIM_OC_InitTypeDef sConfig = {0};

    __HAL_RCC_TIM3_CLK_ENABLE();

    htim3.Instance               = TIM3;
    htim3.Init.Prescaler         = 47;          // 48MHz / 48 = 1MHz timer clock
    htim3.Init.CounterMode       = TIM_COUNTERMODE_UP;
    htim3.Init.Period            = 999;          // 1MHz / 1000 = 1kHz PWM
    htim3.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV1;
    htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    HAL_TIM_PWM_Init(&htim3);

    sConfig.OCMode       = TIM_OCMODE_PWM1;
    sConfig.Pulse        = 0;                    // Mulai dengan duty 0 (mati)
    sConfig.OCPolarity   = TIM_OCPOLARITY_HIGH;
    sConfig.OCFastMode   = TIM_OCFAST_DISABLE;
    HAL_TIM_PWM_ConfigChannel(&htim3, &sConfig, TIM_CHANNEL_1);
}

/* ================================================
   Interrupt Callback - Push Button PB1
   ================================================ */
void HAL_GPIO_EXTICallback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_1)
    {
        printf(">>> Push Button PB1 DITEKAN!\r\n");
    }
}

void Error_Handler(void)
{
    while (1) {}
}

5. Video Demo [Kembali]



6. Analisa[Kembali]







7. Download File [Kembali]

1. Download HTML [disini]

2. Download Rangkaian Proteus  [disini]








Komentar

Postingan populer dari blog ini

TUGAS ELEKTRONIKA