1. Sediakan alat dan bahan percobaan
2. Rangkailah rangkaian di breadboard
3. Download stlink. dan masukkan listing program ke aplikasi STM32 IDE
4. Hubungkan rangkaian dengan software dengan kabel stlink
5. Jalankan program
6. Buzzer
Rangkaian ini merupakan sistem otomatisasi berbasis mikrokontroler STM32 yang menggunakan sensor kelembapan tanah (Soil Moisture Sensor) sebagai input utama untuk mengendalikan arah putaran motor stepper serta memberikan indikator visual melalui LED RGB. Proses dimulai ketika sensor kelembapan tanah mendeteksi kadar air pada media tanam. Sensor ini bekerja berdasarkan konduktivitas tanah; semakin basah tanah, semakin rendah resistansinya, sehingga menghasilkan tegangan analog yang lebih tinggi. Tegangan analog ini kemudian diteruskan ke pin ADC (Analog to Digital Converter) pada mikrokontroler STM32 untuk dikonversi menjadi nilai digital.
Nilai digital dari sensor digunakan sebagai dasar penentuan mode operasi motor stepper, yang terbagi menjadi tiga: Clockwise (CW), Counter Clockwise (CCW), dan Oscillate (bolak-balik). Berdasarkan program yang dijalankan, jika nilai ADC kurang dari 1365, maka sistem berada dalam mode CW, motor berputar searah jarum jam dan LED merah menyala. Jika nilainya antara 1365 hingga 2730, maka sistem berada dalam mode CCW, motor berputar berlawanan arah jarum jam dengan LED hijau yang menyala. Jika nilai ADC lebih dari 2730, maka sistem masuk ke mode Oscillate, yaitu motor berputar secara bolak-balik (CW-CCW) dan LED biru menyala.
Prinsip kerja motor stepper dikendalikan melalui sinyal digital dari mikrokontroler yang dikirim ke pin IN1 sampai IN4 pada driver ULN2003 atau langsung ke motor stepper, dengan urutan langkah sesuai dengan pola dalam array STEP_SEQ_CW atau STEP_SEQ_CCW. Pola ini mengatur aktivasi gulungan motor secara bergantian untuk menghasilkan rotasi yang halus. Fungsi RunStepper() akan mengeksekusi satu langkah motor sesuai arah dan kecepatan yang ditentukan, sementara LED RGB menyala sebagai indikator mode aktif.
#include "stm32f1xx_hal.h"
// Handle untuk ADC dan Timer
ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim2;
// Variabel Global
uint8_t sound_pattern = 0;
// Definisi Pin
#define LED_RED_PIN GPIO_PIN_12
#define LED_GREEN_PIN GPIO_PIN_13
#define LED_BLUE_PIN GPIO_PIN_14
#define LED_PORT GPIOB
#define BUTTON_PIN GPIO_PIN_0
#define BUTTON_PORT GPIOB
#define BUZZER_PIN GPIO_PIN_2
// Threshold ADC
#define ADC_THRESH_HIGH 3000
#define ADC_THRESH_MID 1500
// Periode PWM untuk buzzer
const uint32_t pwm_periods[] = {1000, 50000, 719999};
// Function Prototype
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM2_Init(void);
void update_leds_and_buzzer(uint32_t adc_val, uint8_t btn_state);
void change_sound_pattern(void);
void Error_Handler(void);
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_TIM2_Init();
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0);
HAL_ADC_Start(&hadc1);
while (1) {
static uint32_t last_adc_tick = 0;
static uint32_t last_sound_change = 0;
uint8_t button_state = HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
if (HAL_GetTick() - last_adc_tick > 200) {
last_adc_tick = HAL_GetTick();
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) {
update_leds_and_buzzer(HAL_ADC_GetValue(&hadc1), button_state);
}
}
if (button_state == GPIO_PIN_RESET && (HAL_ADC_GetValue(&hadc1) < ADC_THRESH_MID)) {
if (HAL_GetTick() - last_sound_change > 1000) {
last_sound_change = HAL_GetTick();
change_sound_pattern();
}
}
HAL_Delay(10);
}
}
void update_leds_and_buzzer(uint32_t adc_val, uint8_t btn_state) {
HAL_GPIO_WritePin(LED_PORT, LED_RED_PIN | LED_GREEN_PIN | LED_BLUE_PIN, GPIO_PIN_RESET);
if (adc_val >= ADC_THRESH_HIGH) {
HAL_GPIO_WritePin(LED_PORT, LED_GREEN_PIN, GPIO_PIN_SET);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0);
}
else if (adc_val >= ADC_THRESH_MID) {
HAL_GPIO_WritePin(LED_PORT, LED_BLUE_PIN, GPIO_PIN_SET);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0);
}
else {
HAL_GPIO_WritePin(LED_PORT, LED_RED_PIN, GPIO_PIN_SET);
if (btn_state == GPIO_PIN_RESET) {
__HAL_TIM_SET_AUTORELOAD(&htim2, pwm_periods[sound_pattern]);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, pwm_periods[sound_pattern] / 2);
} else {
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0);
}
}
}
void change_sound_pattern(void) {
sound_pattern = (sound_pattern + 1) % 3;
if (HAL_ADC_GetValue(&hadc1) < ADC_THRESH_MID && HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN) == GPIO_PIN_SET) {
__HAL_TIM_SET_AUTORELOAD(&htim2, pwm_periods[sound_pattern]);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, pwm_periods[sound_pattern] / 2);
}
}
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
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_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) Error_Handler();
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) Error_Handler();
}
static void MX_ADC1_Init(void) {
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
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_1CYCLE_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) Error_Handler();
}
static void MX_TIM2_Init(void) {
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 65535;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) Error_Handler();
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) Error_Handler();
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) Error_Handler();
HAL_TIM_MspPostInit(&htim2);
}
static void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
// LED Pins
GPIO_InitStruct.Pin = LED_RED_PIN | LED_GREEN_PIN | LED_BLUE_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
// Button Pin
GPIO_InitStruct.Pin = BUTTON_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct);
}
void Error_Handler(void) {
__disable_irq();
while (1) {}
}
ANALISA MODUL 2: PWM, ADC, INTERRUPT, & MILLIS \
Download HTML klik disiniDownload Video Demo klik disiniDownload Datashett STM32 klik disini
Download Datasheet RGB-LED klik disiniDownload Datasheet Resistor klik disini
.jpeg)
.jpeg)

.jpeg)
.png)



.png)



Tidak ada komentar:
Posting Komentar