Tugas Pendahuluan 2
Percobaan 3 Smart Fan Control
a. Prosedur [Kembali]
b. Hardware dan Diagram Blok [Kembali]
A. Hardware
c. Rangkaian Simulasi dan Prinsip Kerja [Kembali]
- Rangkaian SimulasiPrinsip Kerja
Prinsip kerja rangkaian ini adalah sensor LM35 membaca suhu lingkungan, kemudian mengeluarkan tegangan analog sesuai suhu yang terdeteksi. Output LM35 masuk ke pin ADC STM32, lalu STM32 mengubah nilai ADC tersebut menjadi nilai suhu dalam derajat Celsius. Setelah suhu terbaca, STM32 menentukan besar PWM untuk mengatur kecepatan kipas melalui driver motor L298. Driver L298 digunakan karena motor kipas membutuhkan arus lebih besar daripada yang dapat diberikan langsung oleh pin STM32.
Pada program, jika suhu ≤ 10°C, maka nilai PWM dibuat 0% sehingga kipas benar-benar mati. Jika suhu berada di antara 10°C sampai < 20°C, kipas menyala dengan kecepatan yang berubah secara linear. Artinya pada suhu mendekati 10°C, kecepatan kipas semakin kecil, dan ketika mendekati 20°C, kecepatan kipas semakin besar. Jika suhu ≥ 20°C, PWM dibuat 100% sehingga kipas berputar dengan kecepatan penuh. Push button digunakan sebagai kontrol manual untuk mematikan kipas secara paksa; ketika tombol ditekan, variabel
fan_force_offaktif sehingga PWM menjadi 0 dan kipas mati. Program yang digunakan mengatur logika ini pada bagian pembacaan suhu, perhitunganpwmDuty, dan fungsiSoftware_PWM()
d. Flowchart dan Listing Program [Kembali]
- Flowchart
- Listing Program
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
ADC_HandleTypeDef hadc1;
volatile uint8_t fan_force_off = 0;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
uint32_t Read_ADC(void)
{
uint32_t adcValue = 0;
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
adcValue = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
return adcValue;
}
float Read_LM35_Temperature(void)
{
uint32_t adcValue = Read_ADC();
float voltage = ((float)adcValue * 3.3f) / 4095.0f;
return voltage * 100.0f;
}
void Software_PWM(uint16_t duty)
{
uint16_t i;
if (duty > 100)
{
duty = 100;
}
for (i = 0; i < 100; i++)
{
if (fan_force_off == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
break;
}
if (i < duty)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
}
HAL_Delay(1);
}
}
int main(void)
{
float suhu = 0.0f;
uint16_t pwmDuty = 0;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
while (1)
{
suhu = Read_LM35_Temperature();
if (fan_force_off == 1)
{
pwmDuty = 0;
}
else
{
if (suhu <= 10.0f)
{
pwmDuty = 0;
}
else if (suhu < 20.0f)
{
pwmDuty = (uint16_t)(((suhu - 10.0f) / 10.0f) * 100.0f);
}
else
{
pwmDuty = 100;
}
}
if (pwmDuty > 0)
{
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
}
Software_PWM(pwmDuty);
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
static uint32_t lastPress = 0;
if (GPIO_Pin == BUTTON_Pin)
{
// debounce tombol
if (HAL_GetTick() - lastPress < 200)
{
return;
}
lastPress = HAL_GetTick();
// toggle: tekan sekali OFF, tekan lagi ON
fan_force_off = !fan_force_off;
if (fan_force_off == 1)
{
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
}
}
}
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_71CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_AFIO_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOA, IN1_Pin | IN2_Pin | GPIO_PIN_8, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = IN1_Pin | IN2_Pin | GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = BUTTON_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(BUTTON_GPIO_Port, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
e. Video Demo [Kembali]
f. Kondisi [Kembali]
Percobaan 3 kondisi 4
Buatlah rangkaian dengan kondisi ketika sensor cahaya (LDR) mendeteksi cahaya sangat rendah, maka jemuran akan segera masuk ke dalam atap. Jika cahaya sedang, jemuran berada pada posisi setengah terbuka, dan jika terang, jemuran berada di luar atap.
g. Video Simulasi [Kembali]
h. Download File [Kembali]
File TP [Klik disini]
Video Simulasi [Disini]
Tidak ada komentar:
Posting Komentar