Laporan Akhir Percobaan 2




Percobaan 3
Led RGB, Motor Stepper, & Soil Moisture

1. Prosedur
[Kembali]

1. Rangkai semua komponen pada breadboard yang terhubung ke mikrokontroler STM32F103C8.
2. Buat program untuk mikrokontroler STM32F103C8 di software STM32 CubeIDE.
3. Build program yang telah dibuat, lalu inputkan program ke dalam mikrokontroler melalui stlink.
4. Setelah program diinputkan, uji rangkaian yang telah dirangkai sesuai dengan output yang ditentukan.
5. Selesai.

2. Hardware dan Diagram Blok [Kembali]

Hardware :

1. Mikrokontroler STM32F103C8
STM32F103C8 board – Microscale

2. Sensor Soil Moisture

3. Stepper Driver ULN2003

 
4. Motor Stepper

 
5. Breadboard
BREADBOARD / PROJECTBOARD / PROTOBOARD 400 HOLES di M-kontrol | Tokopedia
 
6. RGB LED
Jual LED RGB 4 PIN WARNA MERAH HIJAU BIRU 5mm ( ARDUINO ) - Common Cathode  - Jakarta Barat - Ardushop-id | Tokopedia
 
7. Resistor

8. Jumper 


Diagram Blok  :


3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]

Rangkaian Simulasi:

 

Prinsip Kerja : 

Rangkaian ini menggunakan mikrokontroler STM32F103C8T6 sebagai pusat kendali utama, dengan input dari potensiometer yang terhubung ke pin ADC PA0 untuk membaca nilai tegangan analog yang dihasilkan oleh potensiometer. Nilai tegangan ini akan mewakili posisi putaran potensiometer, yang kemudian diproses untuk mengatur kecepatan motor DC dan mengontrol buzzer. Motor DC dikendalikan melalui transistor BD139 yang bertindak sebagai saklar elektronik, dengan basis transistor dihubungkan ke pin PA8 mikrokontroler menggunakan resistor pembatas. Pengendalian motor dilakukan melalui sinyal PWM (Pulse Width Modulation), yang dihasilkan dari Timer 1 pada kanal 1 (TIM1_CH1), mengatur kecepatan motor berdasarkan duty cycle yang ditentukan oleh nilai ADC dari potensiometer. Motor mendapatkan suplai 5V langsung dan dikendalikan melalui jalur ground oleh transistor. Sebagai langkah proteksi, dioda D1 dipasang paralel dengan motor untuk melindungi transistor dari lonjakan tegangan balik saat motor dimatikan.

Selain motor, rangkaian ini juga mengontrol sebuah buzzer yang dihubungkan langsung ke pin PA2 mikrokontroler, yang menerima sinyal PWM dari Timer 2 pada kanal 3 (TIM2_CH3). Setelah inisialisasi, sistem membaca nilai potensiometer yang digunakan untuk menentukan kecepatan motor dengan teknik Pulse Width Modulation (PWM) dan juga untuk mengatur kondisi buzzer.

Nilai potensiometer kemudian diklasifikasikan menjadi tiga kondisi berdasarkan persentase ambang batas (threshold). Pada kondisi pertama, jika nilai potensiometer berada di bawah 33%, motor berjalan dengan kecepatan lambat (PWM = 20%) dan buzzer dalam keadaan mati. Pada kondisi kedua, jika nilai potensiometer berada antara 33% hingga 66%, motor berjalan dengan kecepatan sedang (PWM = 60%) dan buzzer tetap tidak aktif. Pada kondisi ketiga, ketika nilai potensiometer melebihi 66% namun kurang dari 99%, terdapat pengecekan tambahan pada tombol kontrol. Jika tombol tidak aktif, motor berjalan dengan kecepatan penuh (PWM = 100%) dan buzzer tetap mati. Namun, jika tombol ditekan (aktif), motor tetap berkecepatan penuh, tetapi buzzer akan menyala sebagai tanda peringatan.  


4. Flowchart dan Listing Program [Kembali]

Flowchart :

Listing Program :

#include "main.h" ADC_HandleTypeDef hadc1; TIM_HandleTypeDef htim1; TIM_HandleTypeDef htim2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_ADC1_Init(void); static void MX_TIM1_Init(void); static void MX_TIM2_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_ADC1_Init(); MX_TIM1_Init(); MX_TIM2_Init(); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // Motor PWM HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); // Buzzer PWM HAL_ADC_Start(&hadc1); uint8_t buzzer_enabled = 1; uint32_t last_buzzer_change = 0; uint8_t buzzer_freq_index = 0; const uint32_t buzzer_periods[] = {143999, 71999, 47999}; // Frekuensi berbeda // Threshold (dari rendah → sedang → tinggi) const uint16_t THRESH_LOW = 1500; const uint16_t THRESH_MID = 3000;

   while (1)

{ HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1, 10); uint32_t adc_val = HAL_ADC_GetValue(&hadc1); // --- Motor Control --- if (adc_val < THRESH_LOW) { __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 200); // Lambat } else if (adc_val < THRESH_MID) { __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 600); // Sedang } else { __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 1000); // Cepat } // --- Buzzer Logic --- if (adc_val < THRESH_LOW && buzzer_enabled) { // Ubah frekuensi buzzer setiap 500ms if (HAL_GetTick() - last_buzzer_change >= 500) { last_buzzer_change = HAL_GetTick(); buzzer_freq_index = (buzzer_freq_index + 1) % 3; uint32_t period = buzzer_periods[buzzer_freq_index]; __HAL_TIM_SET_AUTORELOAD(&htim2, period); __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, period / 2); // 50% duty } }

else { } __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0); // Matikan buzzer // --- Button Logic (PB0 ditekan = nonaktifkan buzzer) --- if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_SET) { buzzer_enabled = 0; __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0); // Paksa matikan buzzer } HAL_Delay(10); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; 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(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2; 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_TIM1_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; htim1.Instance = TIM1; htim1.Init.Prescaler = 0; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 65535; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { Error_Handler(); }

sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; sBreakDeadTimeConfig.DeadTime = 0; sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) { Error_Handler(); } HAL_TIM_MspPostInit(&htim1); } 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_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin : PB0 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } void Error_Handler(void) { __disable_irq(); while (1) { } } } #endif /* USE_FULL_ASSERT */ #ifdef USE_FULL_ASSERT void assert_failed(uint8_t *file, uint32_t line)

5. Video Demo [Kembali]




6. Analisa [Kembali]









7. Download File [Kembali]

Download HTML [Download]
Download Video Demo [Download]
Datasheet Mikrokontroler STM32F103C8 [Download]
Datasheet Sensor Soil Moisture [Download]

Datasheet RGB LED [Download]
Datasheet Motor Stepper [Download]
Download Datasheet Resistor [Download]
 

Komentar