Percobaan 2 Kondisi 1

  

Tugas Pendahuluan 2

 [KEMBALI KE MENU SEBELUMNYA]



PERCOBAAN 2 KONDISI 2

1. Prosedur [Kembali]

  • Buatlah rangkaian seperti pada percobaan pada Wokwi
  • Tambahkan dan buatlah program main.h pada wokwi 
  • Tambahkan dan buatlah program main.c pada wokwi
  • Simulasikan rangkaian

2. Hardware dan Diagram Blok[Kembali]

1. STM32 NUCLEO-G474RE

2. Motor Servo

3. Resistor



4. Sensor LDR



5. Pushbutton




6. Breadboard
7. Buzzer



3. Rangkaian Simulasi dan Prinsip Kerja[Kembali]

Rangkaian Simulasi: 



Prinsip Kerja:

Rangkaian pada gambar tersebut bekerja dengan menggunakan papan pengembangan NUCLEO C031C6 sebagai unit pemrosesan utama untuk mengontrol motor servo berdasarkan input dari sensor dan tombol. Prinsip kerjanya dimulai saat sensor (kemungkinan sensor cahaya LDR atau infra merah di sebelah kiri) mendeteksi perubahan kondisi lingkungan dan mengirimkan sinyal analog ke pin A0. Secara bersamaan, sebuah tombol tekan (push button) terhubung ke pin A3 sebagai input digital untuk memicu instruksi tertentu secara manual.

Mikrokontroler STM32 kemudian memproses sinyal-sinyal tersebut dan mengirimkan perintah berupa sinyal PWM (Pulse Width Modulation) melalui pin D11 ke motor servo. Sinyal PWM ini menentukan posisi sudut putaran lengan servo, baik itu bergerak secara otomatis mengikuti intensitas sensor atau bereaksi ketika tombol ditekan. Seluruh komponen mendapatkan daya dari jalur VCC (kabel merah) dan terhubung ke jalur GND (kabel hitam) yang sama untuk memastikan aliran arus yang stabil di dalam sistem.

4. Flowchart dan Listing Program[Kembali] 


Flowchart:


Listing Program:

1. 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 CONFIG =================
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 INIT =================
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 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 INIT =================
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 INIT (FIX SERVO) =================
void MX_TIM3_Init(void) {
    __HAL_RCC_TIM3_CLK_ENABLE();
    htim3.Instance = TIM3;
   
    // FIX: 1us 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);

    TIM_OC_InitTypeDef sConfigOC = {0};
    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 PROGRAM =================
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);
    }
}

2. 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]
Buatlah rangkaian dengan kondisi ketika sensor cahaya (LDR) mendeteksi lingkungan terang, maka jemuran akan berada di luar atap (servo pada posisi keluar). Sebaliknya, ketika lingkungan gelap, jemuran akan masuk ke dalam atap (servo pada posisi masuk) untuk menghindari hujan.

7. Video Simulasi[Kembali]





8. Download File[Kembali]

Rangkaian [download]
Video Demo [download]
Video simulasi [download]
Datasheet STM32 NUCLEO-G474RE [Download]
Datasheet LDR [Download]
Datasheet Resistor [Download]
Laporan Akhir [download]










Komentar

Postingan populer dari blog ini

Tugas Besar

12-3

12-4