Tugas Pendahuluan 2



1. Prosedur [kembali]

    1. Membuka website Wokwi dan membuat proyek baru dengan memilih board mikrokontroler yang
        digunakan.
    2. Menambahkan komponen yang diperlukan pada workspace, yaitu mikrokontroler, sensor cahaya
        (LDR), dan motor servo sebagai aktuator jemuran.
    3. Merangkai komponen dengan menghubungkan LDR ke pin analog (ADC) mikrokontroler, serta
        menghubungkan servo ke salah satu pin PWM.
    4. Menentukan nilai ambang (threshold) untuk membedakan kondisi cahaya tinggi dan rendah.
    5. Mengimplementasikan logika kontrol pada program, yaitu jika nilai cahaya lebih tinggi dari
        threshold maka servo bergerak ke posisi luar (jemuran keluar), sedangkan jika lebih rendah maka
        servo bergerak ke posisi dalam (jemuran masuk).
    6. Menjalankan simulasi pada Wokwi dan mengatur nilai intensitas cahaya untuk menguji respon
        sistem.

2. Hardware dan Diagram Blok [kembali]

    A. Hardware
    1. STM32 NUCLEO-G474RE
        

    2. LDR Sensor

    
    3. Push Button 
    4. Motor Servo

    B. Diagram Blok


3. Rangkaian Simulasi dan Prinsip Kerja [kembali]
    Prinsip Kerja:
    Rangkaian jemuran otomatis bekerja dengan memanfaatkan sensor cahaya (LDR) untuk mendeteksi
    intensitas cahaya di lingkungan. LDR menghasilkan perubahan nilai resistansi yang kemudian dibaca
    sebagai sinyal analog oleh mikrokontroler melalui pin ADC.    Nilai analog tersebut dikonversi
    menjadi data digital dan diproses oleh mikrokontroler untuk mengetahui tingkat intensitas cahaya.
    Selanjutnya, nilai tersebut dibandingkan dengan nilai ambang batas (threshold) yang telah ditentukan
    untuk membedakan kondisi cahaya tinggi dan rendah.

    Apabila intensitas cahaya yang terdeteksi lebih tinggi dari threshold, maka mikrokontroler akan
    mengirimkan sinyal PWM ke motor servo sehingga servo bergerak ke posisi tertentu yang
    merepresentasikan kondisi jemuran berada di luar atap. Sebaliknya, apabila intensitas cahaya lebih
    rendah dari threshold, maka mikrokontroler akan menggerakkan servo ke posisi lain sehingga
    jemuran masuk ke dalam atap sebagai bentuk perlindungan dari hujan atau kondisi gelap.

    Dengan demikian, sistem bekerja secara otomatis dengan LDR sebagai input, mikrokontroler sebagai
    pengolah data, dan motor servo sebagai aktuator yang menggerakkan posisi jemuran sesuai kondisi
    cahaya lingkungan.

4. Flowchart dan Listing Program [kembali]

    A. Flowchart
        

    B. Listing Program
        main.c
        #include "main.h"

// --- HANDLE ---
ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim3;

// --- VARIABLE ---
uint8_t manual_mode = 0;
uint8_t posisi_servo = 0;
uint8_t last_button = 1;

// --- THRESHOLD ---
#define LDR_THRESHOLD 2000

// --------------------------- 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) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();

    // LDR PA0
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // BUTTON PB1
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    // SERVO PA6
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

// --------------------------- 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;
    HAL_ADC_Init(&hadc1);
}

// --------------------------- PWM (FIX SERVO) ---------------------------
void MX_TIM3_Init(void) {
    TIM_OC_InitTypeDef sConfigOC = {0};

    __HAL_RCC_TIM3_CLK_ENABLE();

    htim3.Instance = TIM3;
    // FIX: us tick (assume 48MHz clock)
    htim3.Init.Prescaler = 48 - 1;
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim3.Init.Period = 20000 - 1; // 20ms = 50Hz (servo standard)
    HAL_TIM_PWM_Init(&htim3);

    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 1500; // posisi tengah awal
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);
}

// --------------------------- SERVO CONTROL ---------------------------
void set_servo(uint8_t state) {
    if (state == 0) {
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 1000); // masuk atap
    } else {
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 2000); // keluar atap
    }
}

// --------------------------- ADC READ ---------------------------
uint16_t read_LDR(void) {
    ADC_ChannelConfTypeDef sConfig = {0};

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

    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
    return HAL_ADC_GetValue(&hadc1);
}

// --------------------------- 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) {
        // ----- BUTTON TOGGLE -----
        uint8_t button = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);

        if (last_button == 1 && button == 0) {
            manual_mode = !manual_mode;
            posisi_servo = !posisi_servo;
            set_servo(posisi_servo);
            HAL_Delay(50); // Debounce sederhana
        }
        last_button = button;

        // ----- MODE OTOMATIS -----
        if (!manual_mode) {
            uint16_t ldr = read_LDR();

            if (ldr < LDR_THRESHOLD) {
                posisi_servo = 0; // mendung -> masuk
            } else {
                posisi_servo = 1; // terang -> keluar
            }
            set_servo(posisi_servo);
        }

        HAL_Delay(100);
    }
}

        main.h
#ifndef __MAIN_H
#define __MAIN_H
#include "stm32c0xx_hal.h"
// PIN
#define LDR_PIN GPIO_PIN_0
#define LDR_PORT GPIOA
#define BUTTON_PIN GPIO_PIN_1
#define BUTTON_PORT GPIOB
#define SERVO_PIN GPIO_PIN_6
#define SERVO_PORT GPIOA
// FUNCTION
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void MX_ADC1_Init(void);
void MX_TIM3_Init(void);
#endif

     

5. Video Demo [kembali]


6. Kondisi [kembali]

    Kondisi 4: Buatlah rangkaian dengan kondisi ketika sensor cahaya (LDR) mendeteksi cahaya tinggi,
                      maka jemuran berada di luar atap. Sebaliknya, jika cahaya rendah, jemuran berada di
                      dalam atap untuk perlindungan dari hujan.


7. Video Simulasi [kembali]




8. Download File [kembali]

    Download Rangkaian Tugas Pendahuluan 2 disini
    Download Listing Program disini
    Download Datasheet STM32 NUCLEO-G474RE disini
    Download Datasheet LDR Sensor disini


[menuju awal]




Komentar

Postingan populer dari blog ini