Laporan Akhir 2 M2

 [KEMBALI KE MENU SEBELUMNYA]



Laporan Akhir 2
  Motor DC (Dinamo DC),Push Button, Buzzer, & LDR/Photodioda

1. Prosedur 
[Kembali]

1. Rangkai rangkaian di proteus sesuai dengan kondisi percobaan.
2. Buat program untuk mikrokontroler STM32
3. Running Program di STM 32
5. Selesai.

2. Hardware dan Diagram Blok [Kembali]

Hardware :

a) Mikrokontroler STM32








2. LDR



3. Transistor



4. Power Supply

 
5. Buzzer


6. Resistor

7. Motor DC



Diagram Blok  :








3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]
Rangkaian Simulasi



Prinsip Kerja : 

Pada sistem ini STM32 pertama‐tama menginisialisasi semua periferal: kanal ADC untuk membaca tegangan dari potensiometer (atau LDR), timer PWM (TIMx) untuk mengendalikan kecepatan motor DC dan modulasi buzzer, serta GPIO input untuk tombol tekan. Setelah reset, mikrokontroler melakukan konversi ADC untuk mendapatkan nilai analog 0–100 % yang mewakili posisi potensiometer; nilai ini dibagi menjadi tiga rentang: rendah (< 33 %), sedang (33–66 %) dan tinggi (> 66 %). Jika ADC < 33 %, STM32 menetapkan duty cycle PWM motor pada 20 % sehingga motor berputar lambat dan mematikan buzzer. Untuk nilai 33–66 %, duty cycle diubah ke 60 % (kecepatan menengah) tetap tanpa suara buzzer. Saat nilai > 66 %, motor dipacu pada duty 100 % (kecepatan maksimal) dan STM32 selanjutnya membaca status tombol; jika tombol ditekan maka ia mengaktifkan PWM buzzer pada frekuensi tertentu untuk alarm, sementara jika tombol tidak ditekan maka buzzer tetap mati. Loop ini berjalan terus‐menerus sehingga motor dan buzzer secara otomatis merespons perubahan tegangan potensiometer dan input tombol

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); } 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_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) { } } #ifdef USE_FULL_ASSERT void assert_failed(uint8_t *file, uint32_t line) { } #endif /* USE_FULL_ASSERT */



5. Video Demo [Kembali]



6. Analisa [Kembali]

1. Perbedaan implementasi PWM antara STM32 dan Raspberry Pi Pico berdampak langsung pada kualitas kontrol motor dan buzzer. STM32 menggunakan timer hardware khusus (TIMx) yang mampu menghasilkan sinyal PWM dengan resolusi tinggi dan frekuensi yang stabil, bahkan dapat dikontrol secara real-time melalui DMA atau register langsung. Hal ini membuat STM32 sangat ideal untuk mengatur kecepatan motor DC maupun menghasilkan nada yang akurat untuk buzzer. Di sisi lain, Raspberry Pi Pico menggunakan unit PWM slice internal yang dikendalikan melalui Micropython atau C SDK. Meskipun penggunaannya relatif mudah, sinyal PWM pada Pico bergantung pada clock divider dan kontrol perangkat lunak, yang dapat menyebabkan jitter atau delay pada kontrol motor jika beban CPU meningkat. Akibatnya, STM32 lebih unggul dalam aplikasi yang membutuhkan kontrol presisi tinggi dan respon cepat.

2. Pembacaan nilai sensor analog seperti LDR menggunakan ADC pada STM32 dan Raspberry Pi Pico memiliki perbedaan dari segi kecepatan dan kemudahan pemrograman. STM32 dilengkapi ADC 12-bit yang bisa dikonfigurasi untuk melakukan sampling cepat dan dapat dihubungkan dengan DMA agar pembacaan lebih efisien. STM32 juga memiliki kemampuan multi-channel ADC yang memungkinkan pembacaan banyak sensor dalam satu waktu. Sedangkan pada Raspberry Pi Pico, pembacaan ADC dilakukan melalui fungsi read_u16() dalam Micropython, yang mengkonversi hasil ADC 12-bit menjadi nilai 16-bit untuk kemudahan. Walau mudah digunakan, kecepatan pembacaan ADC pada Pico lebih rendah dibanding STM32 dan bergantung pada beban prosesor, sehingga kurang cocok untuk aplikasi sensor analog yang memerlukan kecepatan sampling tinggi.

3. Penggunaan interrupt eksternal pada STM32 dan Raspberry Pi Pico memungkinkan sistem mendeteksi input dari sensor atau tombol secara efisien, namun dengan cara kerja yang berbeda. Pada STM32, interrupt eksternal dikelola melalui EXTI (External Interrupt) yang terhubung dengan NVIC, memungkinkan deteksi sinyal input secara hardware dengan latensi sangat rendah. Konfigurasi interrupt pada STM32 juga mendukung prioritas dan masking, cocok untuk sistem real-time. Sementara itu, Raspberry Pi Pico menangani interrupt melalui fungsi irq() pada objek pin dalam Micropython. Interrupt ini cukup mudah digunakan namun bekerja di level perangkat lunak, sehingga memiliki latensi yang lebih tinggi dan kurang cocok untuk aplikasi yang memerlukan respons instan.

4. Fungsi utime.ticks_ms() pada Raspberry Pi Pico digunakan untuk menghitung waktu dalam milidetik sejak sistem dinyalakan. Fungsi ini bekerja dengan membaca nilai dari timer internal yang terus bertambah sejak sistem boot. Dengan memanfaatkan ticks_ms() dan ticks_diff(), pengguna dapat mengukur durasi waktu antar peristiwa tanpa khawatir terhadap overflow, karena sistem ini menangani wrap-around secara otomatis. Fungsi ini sangat berguna dalam membuat delay non-blocking, mengatur waktu polling sensor, atau memicu event berdasarkan waktu secara efisien dalam program Micropython.

5. Konfigurasi dan kontrol pin PWM serta pemanfaatan timer internal pada STM32 dan Raspberry Pi Pico menunjukkan perbedaan arsitektural yang signifikan. Pada STM32, pin PWM dikontrol oleh timer hardware yang sangat fleksibel dan presisi tinggi. Setiap timer memiliki channel-channel yang bisa dikonfigurasi secara individu dengan frekuensi, duty cycle, serta mode output yang kompleks, bahkan mendukung sinyal komplementer dan dead time untuk mengontrol motor inverter. Sedangkan Raspberry Pi Pico menggunakan 8 slice PWM yang masing-masing memiliki dua channel. Meskipun cukup untuk menghasilkan sinyal gelombang persegi sederhana, kontrolnya lebih terbatas dan tidak sepresisi STM32. Hal ini membuat STM32 unggul dalam aplikasi yang membutuhkan timing kompleks dan kontrol presisi seperti motor servo, inverter, dan sinyal-sinyal digital presisi lainnya.

7. Download File [Kembali]

Download File Rangkaian [Download]
Download Video Simulasi [Download]
Download Listing Program [Download]

Komentar

Postingan populer dari blog ini