Tugas pendahuluan 1
a. Prosedur [Kembali]
1. Buka software proteus lalu rangkai komponen sesuai dengan gambar yang ada di modul
2. Buka software STM32CubeIDE lalu lakukan konfigurasi pin pada STM untuk menentukan GPIO input dan GPIO output
3. Masukan Program ke dalam software STM32CubeIDE lalu build untuk mendapatkan file .hex
4. Masukan file .hex ke dalam file library STM32F103C8 pada proteus
5. Simulasikan rangkaian
b. Hardware dan Diagram Blok [Kembali]
- Hardware
c. Rangkaian Simulasi dan Prinsip Kerja [Kembali]
Prinsip kerja sistem Smart Fan Control ini berjalan secara terus-menerus menggunakan metode pewaktuan non-blocking agar mikrokontroler dapat selalu responsif memantau kondisi lingkungan. Proses diawali oleh sensor LM35 yang membaca suhu sekitar dan mengirimkan keluaran tegangan analog ke mikrokontroler. Melalui modul ADC, tegangan tersebut dikonversi menjadi data digital dan dihitung secara matematis ke dalam besaran derajat Celcius. Apabila suhu yang terukur masih di bawah 30°C, mikrokontroler akan memastikan sinyal penggerak kipas dalam keadaan mati dan terus-menerus menahan catatan waktu siklusnya di angka nol. Penahanan waktu ini dirancang khusus agar saat suhu tiba-tiba memanas dan menyentuh angka 30°C, kipas dapat langsung merespons dan menyala pada detik itu juga, tanpa harus menunggu sisa perhitungan waktu dari memori sebelumnya.
Ketika sistem mendeteksi suhu telah mencapai 30°C atau lebih, mikrokontroler secara otomatis menjalankan siklus pendinginan berkala berdasarkan perhitungan waktu yang terus berjalan. Pada 5 detik pertama siklus, mikrokontroler mengaktifkan pin kendali arah putaran motor dan memberikan sinyal PWM secara penuh sehingga kipas berputar pada kecepatan maksimal. Begitu memasuki detik ke-5 hingga detik ke-10, sistem memutus pin kendali dan menurunkan nilai PWM menjadi nol, yang membuat kipas mati dan berhenti berputar. Setelah durasi 10 detik tersebut genap berlalu, sistem akan mereset catatan waktunya ke awal untuk terus mengulang siklus 5 detik nyala dan 5 detik mati selama suhu lingkungan belum turun.
Di samping proses otomatis tersebut, sistem ini juga dibekali dengan fitur kendali manual darurat (override) melalui sebuah tombol yang terhubung ke pin interupsi (EXTI). Kapan pun tombol ini ditekan, interupsi perangkat keras akan langsung mengambil alih operasi mikrokontroler untuk mengubah status aktif sistem. Fitur ini memungkinkan pengguna untuk mematikan paksa seluruh operasi kipas secara seketika, mengabaikan proses pembacaan suhu maupun siklus jeda yang sedang berjalan.
d. Flowchart dan Listing Program [Kembali]
- Flowchart
- Listing Program
ADC_HandleTypeDef hadc1; // Variabel handler/pengontrol untuk modul ADC1
TIM_HandleTypeDef htim1; // Variabel handler/pengontrol untuk modul Timer 1 (untuk PWM)
void SystemClock_Config(void); // Deklarasi fungsi pengaturan clock sistem
static void MX_GPIO_Init(void); // Deklarasi fungsi inisialisasi pin GPIO
static void MX_ADC1_Init(void); // Deklarasi fungsi inisialisasi ADC1
static void MX_TIM1_Init(void); // Deklarasi fungsi inisialisasi Timer 1
uint32_t adcValue = 0; // Variabel untuk menyimpan nilai mentah hasil pembacaan ADC (0-4095)
float voltage = 0; // Variabel untuk menyimpan hasil konversi ADC ke tegangan listrik (Volt)
float temperature = 0; // Variabel untuk menyimpan hasil konversi tegangan ke suhu (Celcius)
uint8_t system_on = 1; // Flag untuk status sistem utama (1 = menyala, 0 = dimatikan via tombol)
// Tambahan: Variabel untuk melacak waktu (Timer Non-Blocking)
uint32_t cycle_start_tick = 0; // Variabel untuk menyimpan catatan waktu saat siklus kipas dimulai (dalam milidetik)
int main(void) // Fungsi utama program tempat eksekusi dimulai
{
HAL_Init(); // Menginisialisasi library HAL (Hardware Abstraction Layer)
SystemClock_Config(); // Memanggil fungsi untuk mengatur clock sistem mikrokontroler
MX_GPIO_Init(); // Memanggil inisialisasi GPIO (pin input/output)
MX_ADC1_Init(); // Memanggil inisialisasi ADC (pembaca sensor LM35)
MX_TIM1_Init(); // Memanggil inisialisasi Timer 1 (penghasil sinyal PWM)
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // Memulai keluaran sinyal PWM pada Timer 1 Channel 1
while (1) // Looping utama (super loop) yang berjalan terus-menerus
{
HAL_ADC_Start(&hadc1); // Memulai proses konversi data analog ke digital pada ADC1
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY); // Menunggu hingga proses konversi ADC selesai sepenuhnya
adcValue = HAL_ADC_GetValue(&hadc1); // Mengambil nilai digital hasil konversi dan menyimpannya ke variabel adcValue
voltage = (adcValue / 4095.0) * 3.3; // Menghitung nilai tegangan: (Nilai ADC / Resolusi Maksimal 12-bit) * Tegangan Referensi 3.3V
temperature = (voltage * 100); // Mengonversi tegangan menjadi suhu untuk sensor LM35 (10mV = 1 derajat Celcius)
if(system_on) // Mengecek apakah sistem dalam keadaan aktif (tombol belum mematikan sistem)
{
// Logika baru: Jika suhu 30C atau lebih
if(temperature >= 30.0) // Jika suhu terukur mencapai atau melebihi 30 derajat Celcius
{
// Hitung waktu yang berlalu sejak siklus dimulai
uint32_t elapsed_time = HAL_GetTick() - cycle_start_tick; // Menghitung selisih waktu saat ini dengan waktu awal siklus
if(elapsed_time < 5000) // Jika waktu yang berlalu masih di bawah 5000 ms (5 detik pertama)
{
// 0 - 5 detik pertama: Kipas Menyala (Kecepatan Penuh)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); // Set Pin PA2 menjadi HIGH (Kendali arah motor driver)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); // Set Pin PA3 menjadi LOW (Kendali arah motor driver)
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 65535); // Set PWM ke nilai maksimal (100% duty cycle) agar kipas berputar penuh
}
else if(elapsed_time < 10000) // Jika waktu berlalu antara 5000 ms hingga 10000 ms (5 detik kedua)
{
// 5 - 10 detik berikutnya: Kipas Mati
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); // Matikan Pin PA2
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); // Matikan Pin PA3
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0); // Set PWM ke 0 (0% duty cycle) agar kipas berhenti
}
else // Jika waktu berlalu sudah mencapai atau melebihi 10000 ms (10 detik)
{
// Setelah 10 detik, reset timer untuk mengulang siklus dari awal
cycle_start_tick = HAL_GetTick(); // Perbarui catatan waktu awal siklus dengan waktu saat ini
}
}
else // Jika suhu masih di bawah 30 derajat Celcius
{
// Jika suhu di bawah 30C, pastikan kipas mati
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); // Matikan Pin PA2
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); // Matikan Pin PA3
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0); // Set PWM ke 0 agar kipas tidak berputar
// Reset timer terus-menerus.
// Ini memastikan saat suhu naik ke 30C, kipas LANGSUNG menyala di detik ke-0
cycle_start_tick = HAL_GetTick(); // Tahan waktu siklus awal agar selisih waktu (elapsed_time) selalu 0 saat suhu normal
}
}
else // Jika sistem dalam keadaan dimatikan via tombol (system_on = 0)
{
// Sistem dimatikan (system_on = 0)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); // Pastikan Pin PA2 mati
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); // Pastikan Pin PA3 mati
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 0); // Pastikan PWM di-nol-kan
cycle_start_tick = HAL_GetTick(); // Tahan waktu siklus agar tidak berjalan saat sistem mati
}
HAL_Delay(200); // Beri jeda 200 ms sebelum membaca suhu lagi agar pembacaan ADC stabil dan tidak membebani CPU
}
}
void SystemClock_Config(void) // Fungsi untuk mengonfigurasi sumber dan kecepatan clock
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0}; // Membuat struktur konfigurasi osilator bernilai awal 0
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; // Membuat struktur konfigurasi clock bernilai awal 0
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; // Membuat struktur konfigurasi clock peripheral bernilai awal 0
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; // Memilih HSI (High Speed Internal) sebagai osilator utama
RCC_OscInitStruct.HSIState = RCC_HSI_ON; // Menyalakan osilator internal HSI
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mematikan fitur PLL (Phase Locked Loop) karena tidak dibutuhkan
HAL_RCC_OscConfig(&RCC_OscInitStruct); // Menerapkan konfigurasi osilator yang telah diatur
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; // Menentukan jalur clock yang akan dikonfigurasi
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; // Menjadikan HSI sebagai sumber System Clock (SYSCLK)
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0); // Menerapkan konfigurasi clock dengan latensi flash 0
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; // Memilih clock untuk peripheral ADC
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2; // Mengatur sumber clock ADC dari PCLK2 dibagi 2
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); // Menerapkan konfigurasi clock peripheral
}
static void MX_ADC1_Init(void) // Fungsi untuk inisialisasi ADC1
{
ADC_ChannelConfTypeDef sConfig = {0}; // Struktur konfigurasi channel ADC bernilai awal 0
hadc1.Instance = ADC1; // Memilih modul ADC1 yang akan dipakai
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; // Mematikan mode pemindaian (karena hanya 1 channel yang dipakai)
hadc1.Init.ContinuousConvMode = DISABLE; // Mematikan mode konversi kontinu (konversi dilakukan manual saat dipanggil)
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; // Trigger konversi dilakukan melalui software (kode program)
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // Menyusun data hasil ADC rata ke kanan
hadc1.Init.NbrOfConversion = 1; // Jumlah konversi hanya 1 (hanya baca 1 sensor)
HAL_ADC_Init(&hadc1); // Menerapkan konfigurasi dasar ADC1
sConfig.Channel = ADC_CHANNEL_0; // Memilih Channel 0 (biasanya Pin PA0) untuk sensor suhu
sConfig.Rank = ADC_REGULAR_RANK_1; // Menempatkan channel ini di urutan pertama pembacaan
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5; // Waktu sampling diatur ke 71.5 siklus clock agar konversi lebih presisi
HAL_ADC_ConfigChannel(&hadc1, &sConfig); // Menerapkan konfigurasi channel pada modul ADC1
}
static void MX_TIM1_Init(void) // Fungsi untuk inisialisasi Timer 1 sebagai penghasil PWM
{
TIM_OC_InitTypeDef sConfigOC = {0}; // Struktur konfigurasi Output Compare (PWM) bernilai awal 0
htim1.Instance = TIM1; // Memilih modul Timer 1
htim1.Init.Prescaler = 0; // Nilai prescaler 0 (timer berjalan di kecepatan maksimal clock)
htim1.Init.CounterMode = TIM_COUNTERMODE_UP; // Mode penghitungan timer naik dari 0
htim1.Init.Period = 65535; // Nilai maksimal timer (resolusi PWM 16-bit)
HAL_TIM_PWM_Init(&htim1); // Menginisialisasi Timer 1 untuk mode PWM
sConfigOC.OCMode = TIM_OCMODE_PWM1; // Mengatur mode operasi ke PWM Mode 1 (aktif HIGH)
sConfigOC.Pulse = 0; // Lebar pulsa awal (duty cycle) diatur ke 0
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // Polaritas output aktif saat kondisi logika HIGH (1)
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1); // Menerapkan konfigurasi ke Channel 1 Timer 1
HAL_TIM_MspPostInit(&htim1); // Memanggil fungsi tingkat bawah untuk menginisialisasi pin spesifik Timer 1
}
static void MX_GPIO_Init(void) // Fungsi untuk inisialisasi Pin GPIO
{
GPIO_InitTypeDef GPIO_InitStruct = {0}; // Struktur konfigurasi GPIO bernilai awal 0
__HAL_RCC_GPIOA_CLK_ENABLE(); // Menyalakan jalur clock ke Port A agar pin-pin di dalamnya bisa bekerja
GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3; // Memilih Pin PA2 dan PA3 sekaligus (untuk arah putaran motor/kipas)
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // Mengatur pin sebagai Output Push-Pull
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // Mengatur kecepatan saklar transisi pin menjadi rendah
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // Menerapkan konfigurasi tersebut ke Port A
GPIO_InitStruct.Pin = GPIO_PIN_4; // Memilih Pin PA4 (untuk tombol)
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // Mengatur pin sebagai mode Interupsi saat sinyal naik (ditekan)
GPIO_InitStruct.Pull = GPIO_PULLUP; // Mengaktifkan resistor internal Pull-Up agar pin default HIGH
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // Menerapkan konfigurasi tombol ke Port A
HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0); // Menetapkan prioritas interupsi Pin 4 ke tingkat tertinggi (0)
HAL_NVIC_EnableIRQ(EXTI4_IRQn); // Mengaktifkan interupsi Pin 4 (EXTI4) di sistem NVIC (Nested Vectored Interrupt Controller)
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) // Fungsi Callback yang otomatis berjalan saat ada Interupsi hardware terdeteksi
{
if(GPIO_Pin == GPIO_PIN_4) // Mengecek apakah pemicu interupsi benar-benar berasal dari Pin 4 (tombol kita)
{
system_on = !system_on; // Membalikkan keadaan sistem: dari 1 menjadi 0, atau dari 0 menjadi 1
}
}
void Error_Handler(void) // Fungsi khusus yang dipanggil jika terjadi fatal error selama inisialisasi
{
__disable_irq(); // Mematikan semua interupsi agar sistem berhenti merespons kondisi luar
while (1) {} // Sistem terjebak di dalam loop kosong tanpa batas untuk mencegah kerusakan lebih lanjut
}
e. Video Demo [Kembali]
f. Kondisi [Kembali]
Kondisi 5: Buatlah rangkaian seperti percobaan 3 dengan kondisi ketika sensor LM35 mendeteksi suhu 30C maka kipas menyala selama 5 detik lalu mati dan setelah 5 detik kipas menyala lagi.
g. Video Simulasi [Kembali]
h. Download File [Kembali]
File Tugas Pendahuluan(Zip) [Download]
Video Simulasi [Download]
Download Datasheet Resistor [Download]
Download Datasheet STM32F103C8T6 [Download]
Download Datasheet Sensor Suhu Lm35 [Download]
Download Datasheet Kipas DC [Download]
Download Datasheet Push Button [Download]
Download Datasheet Motor Driver l298N [Download]
Komentar
Posting Komentar