LA2 kontrol suhu ruangan
1. Rangkai alat sesuai prosedur modul
2. Buka software proteus lalu rangkai komponen sesuai dengan gambar yang ada di modul
3. Buka software STM32CubeIDE lalu lakukan konfigurasi pin pada STM untuk menentukan GPIO input dan GPIO output
4. Masukan program ke dalam STM32
5. Jalankan program
2. Hardware dan diagram blok [Kembali]
3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]
Deteksi Suhu (Input Analog): Sensor LM35 mendeteksi suhu lingkungan dan menghasilkan output tegangan linier sebesar $10\text{ mV}$ untuk setiap kenaikan suhu satu derajat Celcius.
Konversi Data (ADC): Tegangan analog dari sensor tersebut masuk ke pin ADC STM32F103C8T6 untuk dikonversi menjadi nilai digital 12-bit (0–4095).
Pengolahan Logika Kontrol: Mikrokontroler menghitung nilai suhu sebenarnya dari data ADC tersebut, kemudian membandingkannya dengan parameter suhu yang diinginkan untuk menentukan kecepatan kipas.
Penggerak Daya (Motor Driver): Karena pin mikrokontroler tidak dapat menyuplai arus besar, sinyal kendali diteruskan ke Motor Driver L298N yang berfungsi sebagai sakelar daya untuk menggerakkan kipas DC.
Modulasi Kecepatan (PWM): Mikrokontroler menggunakan sinyal PWM untuk mengatur kecepatan kipas; semakin tinggi suhu yang terdeteksi, semakin besar duty cycle yang diberikan sehingga kipas berputar lebih cepat.
Interaksi Manual (Interrupt): Push Button yang dikonfigurasi dengan sistem Interrupt (EXTI) memungkinkan pengguna untuk mematikan atau menyalakan sistem secara instan tanpa terhambat oleh proses pembacaan sensor yang sedang berjalan.
Manajemen Waktu: Sistem menggunakan fungsi
HAL_GetTick()untuk mengatur interval pembacaan sensor dan pembaruan kecepatan kipas secara berkala tanpa menghentikan aliran program utama (non-blocking).
- Flowchart
- Listing Program
#include "main.h" // HANDLE ADC_HandleTypeDef hadc1; TIM_HandleTypeDef htim3; // VARIABLE uint8_t manual_mode = 0; uint8_t posisi_servo = 0; uint8_t last_button = 1; // THRESHOLD #define LDR_THRESHOLD 2000 // ================= CLOCK ================= 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; HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0); } // ================= GPIO ================= void MX_GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; // LDR PA0 GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // BUTTON PB1 GPIO_InitStruct.Pin = GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// SERVO PA6
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
// ================= ADC =================
void MX_ADC1_Init(void)
{
__HAL_RCC_ADC_CLK_ENABLE();
hadc1.Instance = ADC1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
HAL_ADC_Init(&hadc1);
}
// ================= PWM (FIX SERVO) =================
void MX_TIM3_Init(void)
{
__HAL_RCC_TIM3_CLK_ENABLE();
htim3.Instance = TIM3;
// FIX: 1us tick (assume 48MHz clock)
htim3.Init.Prescaler = 48 - 1;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 20000 - 1; // 20ms = 50Hz (servo standard)
HAL_TIM_PWM_Init(&htim3);
TIM_OC_InitTypeDef sConfigOC = {0};
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 1500; // posisi tengah awal
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);
}
// ================= SERVO CONTROL =================
void set_servo(uint8_t state)
{
if (state == 0)
{
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 1000); // masuk atap
}
else
{
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 2000); // keluar
atap
}
}
// ================= ADC READ =================
uint16_t read_LDR(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
return HAL_ADC_GetValue(&hadc1);
}
// ================= MAIN =================
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_TIM3_Init();
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
while (1)
{
// ===== BUTTON TOGGLE =====
uint8_t button = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);
if (last_button == 1 && button == 0)
{
manual_mode = !manual_mode;
posisi_servo = !posisi_servo;
set_servo(posisi_servo);
HAL_Delay(50);
}
last_button = button;
// ===== MODE OTOMATIS =====
if (!manual_mode)
{
uint16_t ldr = read_LDR();
if (ldr < LDR_THRESHOLD)
{
posisi_servo = 0; // mendung → masuk
}
else
{
posisi_servo = 1; // terang → keluar
}
set_servo(posisi_servo);
}
HAL_Delay(100);
}
}
Komentar
Posting Komentar