Tugas Pendahuluan 2




a) Prosedur

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


b) Hardware

1. STM32 NUCLEO-G474RE


2. LDR Sensor

4. Motor Servo


5. Breadboard



6. Adaptor


Diagram blok:

c) Rangkaian Simulasi dan Prinsip Kerja



Gambar Rangkaian Modul 2 Percobaan 2 Kondisi 5

Prinsip kerja:

Prinsip kerja rangkaian ini dirancang agar sistem jemuran dapat berpindah secara otomatis berdasarkan perubahan intensitas cahaya yang terdeteksi oleh sensor LDR Sensor Module. Sensor LDR akan membaca kondisi cahaya lingkungan secara kontinu, kemudian mengubah intensitas cahaya yang diterima menjadi sinyal tegangan yang dikirim ke mikrokontroler STM32 Nucleo-C031C6 melalui pin input analog (ADC). Saat kondisi lingkungan terang, nilai pembacaan sensor berada pada level tinggi, sehingga sistem menganggap jemuran berada di area luar untuk mendapatkan sinar matahari. Ketika intensitas cahaya mulai berkurang secara bertahap, misalnya karena cuaca mendung atau memasuki sore hari, nilai tegangan keluaran sensor juga berubah secara perlahan.

Mikrokontroler kemudian mengolah perubahan nilai analog tersebut dan mengubahnya menjadi sinyal PWM yang diberikan ke Servo Motor. Karena perubahan nilai sensor terjadi secara bertahap, duty cycle PWM yang dihasilkan juga berubah secara bertahap. Hal ini menyebabkan servo tidak langsung berpindah ke posisi akhir, tetapi bergerak sedikit demi sedikit mengikuti perubahan cahaya. Pada kondisi terang servo berada pada posisi awal yang merepresentasikan jemuran berada di luar atap. Ketika cahaya semakin redup, servo secara perlahan berputar menuju sudut tertentu hingga akhirnya mencapai posisi akhir yang merepresentasikan jemuran berpindah ke dalam atap. Dengan metode ini, perpindahan jemuran terjadi secara halus, stabil, dan tidak bergerak secara tiba-tiba, sehingga sistem lebih aman dan sesuai dengan kondisi perubahan lingkungan secara nyata.


d) Flowchart


Listing Program
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

main.c
#include "main.h"

// HANDLE
ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim3;

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

uint16_t current_pwm = 2000;   // posisi awal = jemuran di luar
uint16_t target_pwm = 2000;

// ================= THRESHOLD =================
#define ADC_MIN     500
#define ADC_MAX     3500

#define SERVO_MIN   1000   // 0 derajat
#define SERVO_MAX   2000   // 180 derajat


// ================= 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};

    // 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 PWM = 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 =================
void MX_TIM3_Init(void)
{
    __HAL_RCC_TIM3_CLK_ENABLE();

    htim3.Instance = TIM3;

    // clock 48MHz -> 1 tick = 1 us
    htim3.Init.Prescaler = 48 - 1;
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim3.Init.Period = 20000 - 1;

    HAL_TIM_PWM_Init(&htim3);

    TIM_OC_InitTypeDef sConfigOC = {0};

    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 2000;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

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


// ================= 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);
}


// ================= MAPPING =================
uint16_t map_adc_to_servo(uint16_t adc)
{
    if(adc < ADC_MIN)
        adc = ADC_MIN;

    if(adc > ADC_MAX)
        adc = ADC_MAX;

    // terang = keluar
    // gelap = masuk
    return SERVO_MIN +
          ((adc - ADC_MIN) *
          (SERVO_MAX - SERVO_MIN))
          / (ADC_MAX - ADC_MIN);
}


// ================= SERVO SMOOTH =================
void servo_smooth_move(uint16_t target)
{
    if(current_pwm < target)
    {
        current_pwm += 5;

        if(current_pwm > target)
            current_pwm = target;
    }
    else if(current_pwm > target)
    {
        current_pwm -= 5;

        if(current_pwm < target)
            current_pwm = target;
    }

    __HAL_TIM_SET_COMPARE(
        &htim3,
        TIM_CHANNEL_1,
        current_pwm
    );
}


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

        if(last_button == 1 && button == 0)
        {
            manual_mode = !manual_mode;

            HAL_Delay(200);
        }

        last_button = button;


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

            // Mapping cahaya -> posisi servo
            target_pwm =
                map_adc_to_servo(ldr);
        }


        // Gerakan halus
        servo_smooth_move(target_pwm);

        HAL_Delay(20);
    }
}


e) Video Demo


f) Kondisi

Buatlah rangkaian dengan kondisi ketika sensor cahaya (LDR) mendeteksi perubahan dari terang ke gelap secara bertahap maka servo akan bergerak secara bertahap mengikuti perubahan tersebut hingga jemuran berpindah dari luar ke dalam atap secara halus.

g) Video Simulasi


Video Penjelasan Percobaan 2 Kondisi 5

h) Download File

Komentar

Postingan populer dari blog ini

Figure 7.21

Figure 8.17

Figure 12.19