LA 2 MOD 2 MIKRO





Laporan Akhir 2 Modul 2
(Percobaan 2)

1. Prosedur [kembali]


    1. Rangkai sesuai gambar percobaan dengan inputnya sensor kelembaban tanah, untuk outputnya yaitu buzzer dan LED RGB.

    2. Hubungkan sensor kelembaban, buzzer, dan LED RGB dengan kabel jumper sesuai pin pada programnya.

    3. Buatlah program dengan konfigurasi pin input dan output berdasarkan pin GP STM32 yang telah dirangkai sebelumnya.

    4. Upload program ke STM32.

    5. Lihat perubahan ketika sensor mendeteksi tanah kering dan tanah basah.

2. Hardware dan Diagram Blok [kembali]
  • Hardware :









    Diagram Blok :







3. Rangkaian Simulasi dan Prinsip Kerja [kembali]

  • Rangkaian Simulasi :



    Prinsip Kerja : 

         Rangkaian dan program ini dirancang untuk mengontrol arah gerak motor stepper berdasarkan kelembaban tanah menggunakan mikrokontroler STM32. Sensor soil moisture mengirimkan sinyal analog ke ADC1 STM32, yang kemudian digunakan untuk menentukan mode gerak motor: searah jarum jam (CW), berlawanan arah jarum jam (CCW), atau bolak-balik (oscillate).

    Jika nilai ADC < 1365, motor bergerak CW dan LED merah menyala. Untuk nilai 1365–2730, motor bergerak CCW dan LED hijau menyala. Jika >2730, motor bergerak bolak-balik dan LED biru menyala.

    Motor dikendalikan melalui empat pin GPIOB (IN1–IN4) menggunakan urutan bit dari array STEP_SEQ_CW dan STEP_SEQ_CCW. Fungsi RunStepper mengatur langkah motor dengan delay sesuai kecepatan. Sistem ini merespons otomatis terhadap perubahan kelembaban tanpa perlu kontrol manual.

4. Flowchart dan Listing Program [kembali]
  • Listing Program pada Thonny 
from machine import Pin, PWM, ADC
from time import sleep
import utime

# Inisialisasi
pot = ADC(26)  # GP26 = ADC0
servo = PWM(Pin(16))
buzzer = PWM(Pin(14))

# Konfigurasi PWM
servo.freq(50)       # 50 Hz untuk servo
buzzer.freq(1000)    # Awal frekuensi buzzer

# Fungsi mapping
def map_value(value, in_min, in_max, out_min, out_max):
    return int((value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)

# Loop utama
while True:
    val = pot.read_u16()  # Nilai ADC 16-bit (0 - 65535)

    # === Servo Motor ===
    pot_value = pot.read_u16()
    angle = map_value(pot_value, 0, 65535, 0, 180)
    duty = map_value(angle, 0, 180, 1500, 7500)
    servo.duty_u16(duty)

    # Debug
    print(f"Pot Value: {pot_value}, Angle: {angle}, Duty: {duty}")

    # === Buzzer ===
    freq = int(200 + (val / 65535) * (2000 - 200))
    buzzer.freq(freq)
    buzzer.duty_u16(30000)  # Volume/suaranya

    sleep(0.05)








  • Flowchart



Flowchart :



Listing Program :

#include "stm32f1xx_hal.h"

// === Konfigurasi Pin ===
#define STEPPER_PORT GPIOB
#define IN1_PIN      GPIO_PIN_8
#define IN2_PIN      GPIO_PIN_9
#define IN3_PIN      GPIO_PIN_10
#define IN4_PIN      GPIO_PIN_11

#define LED_PORT     GPIOB
#define LED_RED_PIN    GPIO_PIN_12
#define LED_GREEN_PIN  GPIO_PIN_13
#define LED_BLUE_PIN   GPIO_PIN_14

// === Urutan Langkah Stepper ===
const uint16_t STEP_SEQ_CW[4]  = {0x0100, 0x0200, 0x0400, 0x0800}; // Clockwise
const uint16_t STEP_SEQ_CCW[4] = {0x0800, 0x0400, 0x0200, 0x0100}; // Counter-clockwise

// === Global Variabel ===
ADC_HandleTypeDef hadc1;
uint8_t current_mode = 0; // 0=CW, 1=CCW, 2=Oscillate
uint8_t direction = 0;    // Untuk mode oscillate

// === Fungsi Prototipe ===
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void MX_ADC1_Init(void);
void RunStepper(const uint16_t *sequence, uint8_t speed);
void Error_Handler(void);

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

    while (1) {
        // Baca sensor kelembaban
        HAL_ADC_Start(&hadc1);
        if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) {
            uint16_t adc_val = HAL_ADC_GetValue(&hadc1);

            // Tentukan mode berdasarkan nilai ADC
            if (adc_val < 1365) {  // CW
                current_mode = 0;
                HAL_GPIO_WritePin(LED_PORT, LED_RED_PIN, GPIO_PIN_SET);
                HAL_GPIO_WritePin(LED_PORT, LED_GREEN_PIN | LED_BLUE_PIN, GPIO_PIN_RESET);
            }
            else if (adc_val < 2730) { // CCW
                current_mode = 1;
                HAL_GPIO_WritePin(LED_PORT, LED_GREEN_PIN, GPIO_PIN_SET);
                HAL_GPIO_WritePin(LED_PORT, LED_RED_PIN | LED_BLUE_PIN, GPIO_PIN_RESET);
            }
            else { // Oscillate
                current_mode = 2;
                HAL_GPIO_WritePin(LED_PORT, LED_BLUE_PIN, GPIO_PIN_SET);
                HAL_GPIO_WritePin(LED_PORT, LED_RED_PIN | LED_GREEN_PIN, GPIO_PIN_RESET);
            }
        }

        // Eksekusi mode gerakan motor
        switch (current_mode) {
            case 0: // CW
                RunStepper(STEP_SEQ_CW, 10);
                break;

            case 1: // CCW
                RunStepper(STEP_SEQ_CCW, 10);
                break;

            case 2: // Oscillate
                if (direction == 0) {
                    RunStepper(STEP_SEQ_CW, 5);
                    if ((STEPPER_PORT->ODR & 0xFF00) == STEP_SEQ_CW[3])
                        direction = 1;
                } else {
                    RunStepper(STEP_SEQ_CCW, 5);
                    if ((STEPPER_PORT->ODR & 0xFF00) == STEP_SEQ_CCW[3])
                        direction = 0;
                }
                break;
        }
    }
}

// === Fungsi Menggerakkan Motor Stepper ===
void RunStepper(const uint16_t *sequence, uint8_t speed) {
    static uint8_t step = 0;
    STEPPER_PORT->ODR = (STEPPER_PORT->ODR & 0x00FF) | sequence[step];
    step = (step + 1) % 4;
    HAL_Delay(speed);
}

// === Konfigurasi Clock STM32 ===
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.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        Error_Handler();
    }

    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
        Error_Handler();
    }
}

// === Inisialisasi GPIO untuk LED dan Motor ===
void MX_GPIO_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOB_CLK_ENABLE();

    // LED Output
    GPIO_InitStruct.Pin = LED_RED_PIN | LED_GREEN_PIN | LED_BLUE_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);

    // Stepper Motor Output
    GPIO_InitStruct.Pin = IN1_PIN | IN2_PIN | IN3_PIN | IN4_PIN;
    HAL_GPIO_Init(STEPPER_PORT, &GPIO_InitStruct);
}

// === Inisialisasi ADC1 untuk Sensor ===
void MX_ADC1_Init(void) {
    ADC_ChannelConfTypeDef sConfig = {0};

    hadc1.Instance = ADC1;
    hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
    hadc1.Init.ContinuousConvMode = DISABLE;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.NbrOfConversion = 1;

    if (HAL_ADC_Init(&hadc1) != HAL_OK) {
        Error_Handler();
    }

    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = ADC_REGULAR_RANK_1;
    sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;

    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
        Error_Handler();
    }
}

// === Penanganan Error ===
void Error_Handler(void) {
    while (1) {
        // Loop terus jika error
    }
}


5. Video Demo [kembali]






6. Analisa [kembali]












7. Download file [kembali]



Komentar

Postingan populer dari blog ini

BAHAN PRESENTASI UNTUK MATA KULIAH ELEKTRONIKA 2022