Percobaan 2 Kondisi 5




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


c) Rangkaian Simulasi dan Prinsip Kerja



Rangkaian ini bekerja otomatis untuk memindahkan jemuran berdasarkan intensitas cahaya yang dibaca oleh sensor LDR. Sensor LDR mendeteksi cahaya lingkungan lalu mengirimkan nilai tegangan ke mikrokontroler STM32 melalui ADC. Saat kondisi terang, sistem menganggap jemuran berada di luar agar terkena sinar matahari. Ketika cahaya mulai redup, nilai sensor berubah secara perlahan.

Mikrokontroler kemudian mengolah perubahan tersebut menjadi sinyal PWM untuk menggerakkan servo motor. Karena perubahan nilai cahaya terjadi bertahap, servo juga bergerak sedikit demi sedikit dan tidak langsung berpindah posisi. Saat terang servo berada pada posisi jemuran di luar, sedangkan saat gelap servo perlahan bergerak hingga jemuran masuk ke bawah atap. Dengan cara ini, perpindahan jemuran menjadi lebih halus, stabil, dan aman.


d) Flowchart





Listing Program
#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 TOGGLE ===== if { 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); }
  // ===== MODE OTOMATIS =====
else if(!manual_mode)
{
    uint16_t ldr = read_LDR();

    // batas ADC
    if(ldr < ADC_MIN)
        ldr = ADC_MIN;

    if(ldr > ADC_MAX)
        ldr = ADC_MAX;

    /*
        GELAP  -> servo masuk
        TERANG -> servo keluar

        Nilai LDR langsung menentukan posisi servo
        sehingga servo bergerak mengikuti perubahan cahaya
        secara real-time dan bertahap
    */

    target_pwm =
        SERVO_MAX -
        ((ldr - ADC_MIN) *
        (SERVO_MAX - SERVO_MIN))
        / (ADC_MAX - ADC_MIN);

    // langsung update posisi servo
    __HAL_TIM_SET_COMPARE(
        &htim3,
        TIM_CHANNEL_1,
        target_pwm
    );

    HAL_Delay(20);
}
    }
}

e) Video Demo

Tempel kode embed video demo di sini...

f) Kondisi

percobaan 2 kondisi 2

g) Video Simulasi








h) Download File

Komentar

Postingan populer dari blog ini

kuliah