LAPORAN AKHIR 1
Prosedur
Pada tahap awal, sistem melakukan konfigurasi internal, termasuk inisialisasi pin GPIO yang terhubung ke berbagai komponen eksternal, serta pengaturan clock yang menggunakan internal oscillator HSI. Hal ini menunjukkan orientasi sistem terhadap efisiensi dan kemudahan implementasi tanpa memerlukan sumber clock eksternal tambahan. Mikrokontroler juga mengatur ADC1 pada channel 0 untuk membaca sinyal analog dari potensiometer yang terhubung ke pin PA0. Data ini menjadi dasar utama dalam menentukan arah gerak motor stepper.
Salah satu keunggulan dari sistem ini adalah penerapan mekanisme interrupt untuk touch sensor yang dikonfigurasi melalui pin PB0 sebagai sumber interrupt eksternal (EXTI0). Dengan pengaturan interrupt yang aktif pada perubahan sinyal baik rising maupun falling edge, sistem dapat memberikan respons langsung terhadap setiap perubahan status pada touch sensor tanpa harus menunggu polling pada loop utama. Saat interrupt terjadi, fungsi callback HAL_GPIO_EXTI_Callback() akan dieksekusi untuk menangani perubahan tersebut secara efisien.
Dalam loop utama, sistem terus-menerus memantau kondisi sensor dan mengambil keputusan logika berdasarkan input yang diterima. Jika touch sensor tidak aktif, maka fokus sistem beralih ke pembacaan nilai potensiometer. Berdasarkan ambang batas nilai ADC sebesar 2048, sistem menentukan arah putaran motor stepper: searah jarum jam (CW) untuk nilai di bawah 2048 dan berlawanan arah jarum jam (CCW) untuk nilai di atas atau sama dengan 2048. Fungsi RunStepper() akan mengatur urutan aktivasi logika (step sequence) pada pin PB8 hingga PB11 yang terhubung ke driver ULN2003A. Driver ini bertugas menguatkan sinyal kendali dari mikrokontroler sebelum disalurkan ke motor stepper, yang membutuhkan arus lebih besar daripada yang bisa disuplai langsung oleh GPIO mikrokontroler.
Sebaliknya, ketika touch sensor mendeteksi adanya sentuhan, sistem memprioritaskan aktivasi motor DC pada pin PB7 dengan memberikan sinyal HIGH, sementara motor stepper dimatikan total dengan menyetel semua pin kendalinya ke LOW. Ini mencerminkan implementasi sistem prioritas berbasis intervensi pengguna: ketika terjadi sentuhan, semua aktivitas otomatisasi yang bergantung pada potensiometer dihentikan, dan kontrol sistem dialihkan sepenuhnya ke motor DC.
Pengaturan ini menciptakan sistem yang responsif dan efisien, karena mampu berpindah antar mode operasi secara langsung berdasarkan perubahan input eksternal. Seluruh proses ini berlangsung dalam waktu nyata (real-time) berkat kombinasi antara pembacaan ADC secara periodik dalam loop utama dan penanganan interrupt secara asinkron. Sistem juga dilengkapi dengan prosedur Error_Handler() untuk menanggapi potensi kegagalan saat inisialisasi periferal, yang memastikan bahwa sistem tidak melanjutkan operasi dalam kondisi error.
- STM32F103C8 sebagai mikrokontroler utama untuk mengontrol input dari sensor dan output ke LED.
- Touch Sensor, Sensor sentuh yang menghasilkan sinyal digital saat disentuh, digunakan untuk mengaktifkan/mematikan motor DC melalui interrupt.
- Potensiometer, komponen variabel yang digunakan sebagai input analog untuk menentukan arah putaran stepper motor melalui ADC.
- Resistor, Pull-down resistor pada jalur touch sensor untuk memastikan sinyal stabil saat tidak disentuh.
- ULN2003A (U2), Driver motor stepper yang memperkuat arus dari mikrokontroler agar dapat menggerakkan motor stepper.
- Motor Stepper, motor yang dikontrol secara bertahap (step-by-step) untuk bergerak CW atau CCW sesuai nilai potensiometer.
- Motor DC, motor searah yang diaktifkan saat touch sensor disentuh sebagai respon interrupt.
Rangkaian ini bekerja dengan prinsip utama pemilihan dan pengendalian dua jenis motor—motor DC dan motor stepper—berdasarkan masukan dari sensor sentuh dan potensiometer. Saat sistem pertama kali dijalankan, mikrokontroler STM32 akan melakukan inisialisasi terhadap berbagai periferal seperti HAL, clock sistem, GPIO, dan ADC. Setelah inisialisasi selesai, program masuk ke dalam loop utama yang akan terus berjalan selama sistem aktif.
Di dalam loop utama, sistem akan mengecek kondisi dari touch sensor. Jika sensor disentuh, maka terjadi interupsi yang mengaktifkan motor DC dan secara bersamaan mematikan motor stepper untuk mencegah keduanya berjalan secara bersamaan. Hal ini bertujuan agar hanya satu motor yang aktif pada satu waktu berdasarkan input yang diterima.
Namun, jika sensor tidak disentuh, maka sistem akan membaca nilai analog dari potensiometer menggunakan ADC (Analog to Digital Converter). Nilai ini kemudian digunakan untuk menentukan arah putaran motor stepper. Jika nilai ADC kurang dari 2048, maka motor stepper akan berputar searah jarum jam. Sebaliknya, jika nilai ADC lebih besar atau sama dengan 2048, motor stepper akan berputar berlawanan arah jarum jam. Setiap langkah putaran motor diberikan delay selama 1ms untuk mengatur kecepatan rotasi dan menjaga kestabilan.
Listing Program
|
#include
"stm32f1xx_hal.h" //
Konfigurasi Hardware #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
TOUCH_SENSOR_PORT GPIOB #define
TOUCH_SENSOR_PIN GPIO_PIN_0 #define
MOTOR_DC_PORT GPIOB #define
MOTOR_DC_PIN GPIO_PIN_7 //
Mode Stepper const
uint8_t STEP_SEQ_CW[4] = { (1<<0),
// IN1 (1<<1),
// IN2 (1<<2),
// IN3 (1<<3)
// IN4 }; const
uint8_t STEP_SEQ_CCW[4] = { (1<<3),
// IN4 (1<<2),
// IN3 (1<<1),
// IN2 (1<<0)
// IN1 }; ADC_HandleTypeDef
hadc1; uint8_t
current_mode = 0; // 0=CW, 1=CCW volatile
uint8_t touch_state = 0; void
SystemClock_Config(void); void
MX_GPIO_Init(void); void
MX_ADC1_Init(void); void
RunStepper(const uint8_t *sequence, uint8_t speed); void
Error_Handler(void); int
main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_ADC1_Init(); while
(1) { //
Saat tidak disentuh, jalankan stepper seperti biasa if
(HAL_GPIO_ReadPin(TOUCH_SENSOR_PORT, TOUCH_SENSOR_PIN) == GPIO_PIN_RESET)
{ HAL_ADC_Start(&hadc1); if
(HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) { uint16_t
adc_val = HAL_ADC_GetValue(&hadc1); current_mode
= (adc_val < 2048) ? 0 : 1; // 0 = CW, 1 = CCW } if
(current_mode == 0) { RunStepper(STEP_SEQ_CW,
5); }
else { RunStepper(STEP_SEQ_CCW,
5); } } HAL_Delay(1); } } void
RunStepper(const uint8_t *sequence, uint8_t speed) { static
uint8_t step = 0; HAL_GPIO_WritePin(STEPPER_PORT,
IN1_PIN, (sequence[step] & (1<<0)) ? GPIO_PIN_SET
: GPIO_PIN_RESET); HAL_GPIO_WritePin(STEPPER_PORT,
IN2_PIN, (sequence[step] & (1<<1)) ? GPIO_PIN_SET
: GPIO_PIN_RESET); HAL_GPIO_WritePin(STEPPER_PORT,
IN3_PIN, (sequence[step] & (1<<2)) ? GPIO_PIN_SET
: GPIO_PIN_RESET); HAL_GPIO_WritePin(STEPPER_PORT,
IN4_PIN, (sequence[step] & (1<<3)) ? GPIO_PIN_SET
: GPIO_PIN_RESET); step
= (step + 1) % 4; HAL_Delay(speed); } void
MX_GPIO_Init(void) { GPIO_InitTypeDef
GPIO_InitStruct = {0}; __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_AFIO_REMAP_SWJ_NOJTAG();
// Optional: disable JTAG to free PB3-PB4 if needed //
Konfigurasi Touch Sensor sebagai input dengan EXTI (interrupt) GPIO_InitStruct.Pin
= TOUCH_SENSOR_PIN; GPIO_InitStruct.Mode
= GPIO_MODE_IT_RISING_FALLING; GPIO_InitStruct.Pull
= GPIO_NOPULL; HAL_GPIO_Init(TOUCH_SENSOR_PORT,
&GPIO_InitStruct); //
Aktifkan NVIC untuk EXTI0 HAL_NVIC_SetPriority(EXTI0_IRQn,
0, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); //
Konfigurasi Motor DC (PB7) GPIO_InitStruct.Pin
= MOTOR_DC_PIN; GPIO_InitStruct.Mode
= GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull
= GPIO_NOPULL; GPIO_InitStruct.Speed
= GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(MOTOR_DC_PORT,
&GPIO_InitStruct); //
Konfigurasi Stepper Motor (PB8-PB11) GPIO_InitStruct.Pin
= IN1_PIN | IN2_PIN | IN3_PIN | IN4_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull
= GPIO_NOPULL; GPIO_InitStruct.Speed
= GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(STEPPER_PORT,
&GPIO_InitStruct); } 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(); } } 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(); } } void
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if
(GPIO_Pin == TOUCH_SENSOR_PIN) { GPIO_PinState
pinState = HAL_GPIO_ReadPin(TOUCH_SENSOR_PORT, TOUCH_SENSOR_PIN); if
(pinState == GPIO_PIN_SET) { //
Touch sensor ditekan - nyalakan motor DC, matikan stepper HAL_GPIO_WritePin(MOTOR_DC_PORT,
MOTOR_DC_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(STEPPER_PORT,
IN1_PIN|IN2_PIN|IN3_PIN|IN4_PIN, GPIO_PIN_RESET); }
else { //
Touch sensor dilepas - matikan motor DC HAL_GPIO_WritePin(MOTOR_DC_PORT,
MOTOR_DC_PIN, GPIO_PIN_RESET); } } } //
IRQ Handler untuk EXTI0 void
EXTI0_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(TOUCH_SENSOR_PIN); } void
Error_Handler(void) { while(1)
{} } |
File HTML [disini]
Listing Program [disini]
Video [disini]
Datasheet STM32F103C8 [disini]
Datasheet Touch Sensor [disini]










Komentar
Posting Komentar