Tugas Pendahuluan Percobaan 8 Kondisi 1
a. Baca terlebih dahulu kondisi yang akan diambil
b. Buka aplikasi yang digunakan, STM CUBE IDE dan Proteus
c. Setelah itu siapkan komponen - komponen yang dibutuhkan, seperti STM32F103C8T6, Sensor Touch, Potensiometer, Motor,Motor Stepper dan Modul Control motor stepper
d. Hubungkan komponen - komponen menjadi rangkaian yang
sesuai dengan kondisi
e. Buat codingan atau program c di STM32CUBE IDEuntuk menjalankan
rangkaian tersebut
f. Lalu simulasikan rangkaian
g. Selesai


B. Blok Diagram
Rangkaian ini bekerja dengan memanfaatkan mikrokontroler STM32F103C8T6 sebagai pusat kendali untuk mengatur dua buah motor, yaitu motor DC dan motor stepper, berdasarkan input dari sensor sentuh dan sebuah potensiometer yang terhubung ke kanal ADC. Sensor sentuh bertindak sebagai pemicu utama sistem; ketika sensor ini disentuh, akan terjadi interupsi pada pin PB0 yang kemudian memicu mikrokontroler untuk menyalakan motor DC melalui pin PB7 yang dikonfigurasi sebagai output digital, sementara seluruh keluaran stepper motor pada pin PB8 sampai PB11 dimatikan agar motor stepper tidak bergerak. Ketika sensor tidak disentuh, maka sistem akan kembali memantau nilai tegangan analog yang berasal dari potensiometer melalui pin ADC pada kanal PA0. Nilai tegangan ini kemudian dikonversi menjadi nilai digital menggunakan fitur ADC internal dari STM32. Berdasarkan nilai tersebut, mikrokontroler akan memutuskan arah putaran motor stepper: jika nilai ADC lebih kecil dari 2048 (dari rentang 0–4095 untuk ADC 12-bit), maka motor stepper akan bergerak berlawanan arah jarum jam (CCW), sedangkan jika lebih besar, motor akan berputar searah jarum jam (CW). Untuk menggerakkan motor stepper, digunakan driver ULN2003A yang menerima logika input dari PB8–PB11 dan meneruskan arus ke masing-masing fasa motor stepper secara berurutan sesuai pola sinyal. Rangkaian juga dilengkapi dengan resistor dan potensiometer sebagai pembagi tegangan untuk input ADC, serta kapasitor dan sumber tegangan eksternal untuk memastikan kestabilan operasional sistem. Dengan demikian, rangkaian ini memungkinkan pengendalian dinamis dua jenis motor menggunakan input sederhana berupa sentuhan dan nilai analog, serta mendemonstrasikan interaksi antar sistem input, pemrosesan, dan output dalam kendali berbasis mikrokontroler.
Prinsip kerja dari kode program pada sistem ini adalah untuk mengatur dua jenis aktuator, yaitu motor DC dan motor stepper, menggunakan mikrokontroler STM32F103C8T6 berdasarkan dua jenis masukan: sensor sentuh (touch sensor) dan pembacaan nilai analog dari ADC (Analog to Digital Converter). Proses dimulai dengan inisialisasi sistem melalui pemanggilan beberapa fungsi utama seperti HAL_Init()
untuk menginisialisasi HAL library STM32, SystemClock_Config()
untuk mengatur clock internal mikrokontroler, MX_GPIO_Init()
untuk mengatur konfigurasi input-output digital, serta MX_ADC1_Init()
untuk konfigurasi ADC1 sebagai pembaca sinyal analog dari pin PA0. Setelah semua perangkat keras dikonfigurasi, sistem masuk ke loop utama (while (1)
) yang akan terus berjalan selama mikrokontroler aktif.
Di dalam loop utama, program pertama-tama memeriksa apakah sensor sentuh dalam keadaan tidak ditekan. Sensor sentuh dihubungkan ke pin PB0 dan dikonfigurasi sebagai input dengan interrupt, yang berarti sistem akan segera menanggapi perubahan kondisi sensor. Ketika sensor tidak ditekan (logika LOW), maka motor DC dimatikan, dan sistem mulai membaca nilai tegangan dari ADC yang berasal dari potensiometer atau sensor analog lainnya. Proses pembacaan ADC dilakukan dengan memulai konversi menggunakan HAL_ADC_Start(&hadc1)
, lalu sistem menunggu konversi selesai menggunakan HAL_ADC_PollForConversion()
, dan akhirnya mengambil nilai hasil konversi dengan HAL_ADC_GetValue(&hadc1)
. Nilai ini berupa bilangan 12-bit (0–4095) yang kemudian dibandingkan dengan angka tengah yaitu 2048. Jika nilai ADC lebih dari 2048, maka motor stepper akan digerakkan berputar searah jarum jam (clockwise/CW) dengan memanggil fungsi RunStepper()
menggunakan urutan pulsa yang disimpan dalam array STEP_SEQ_CW
. Jika nilai kurang dari 2048, maka motor stepper akan berputar berlawanan arah jarum jam (counter-clockwise/CCW) dengan menggunakan array STEP_SEQ_CCW
.
Fungsi RunStepper()
digunakan untuk mengatur urutan aktifasi empat pin motor stepper (PB8–PB11). Di dalam fungsi ini, setiap langkah motor ditentukan oleh elemen dalam array urutan stepper, yang kemudian digunakan untuk menyalakan atau mematikan masing-masing pin GPIO sesuai kebutuhan langkah tersebut. Setelah setiap langkah, terdapat delay pendek (5 ms) agar motor tidak bergerak terlalu cepat dan tetap stabil.
Jika pada saat kapan pun sensor sentuh ditekan (logika HIGH), maka interrupt akan dipicu dan fungsi callback HAL_GPIO_EXTI_Callback()
akan dijalankan. Dalam fungsi ini, sistem membaca status logika pin sensor, dan jika terdeteksi ditekan, maka motor DC akan langsung dinyalakan (pin PB7 diberi logika HIGH), dan keempat pin motor stepper langsung dimatikan agar tidak ada sinyal step yang dikirim. Saat sensor tidak ditekan lagi, maka motor DC dimatikan kembali, dan sistem kembali membaca nilai ADC untuk mengatur perputaran motor stepper.
Selain itu, handler interrupt EXTI0_IRQHandler()
juga tersedia untuk menangani interrupt dari pin PB0 (EXTI line 0), yang kemudian akan memanggil HAL_GPIO_EXTI_IRQHandler()
agar sistem mengetahui bahwa sebuah interupsi dari sensor sentuh telah terjadi. Sistem ini memanfaatkan fitur interrupt agar dapat merespon dengan cepat ketika ada perubahan dari sensor sentuh, tanpa perlu menunggu polling di dalam loop utama. Secara keseluruhan, kode ini mendemonstrasikan sistem kendali motor yang adaptif, di mana arah dan jenis motor yang aktif ditentukan oleh masukan sensor, dengan struktur program yang memanfaatkan baik polling (untuk ADC) maupun interrupt (untuk sensor sentuh), serta konfigurasi GPIO yang cukup efisien untuk mengendalikan dua jenis motor dalam satu mikrokontroler.
#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
// Touch Sensor input dengan 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);
HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
// 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);
// 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) {
// Saat 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 {
// Saat 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) {}
}
Tidak ada komentar:
Posting Komentar