Langkah-langkah percobaan :
- Pahami terlebih dahulu kondisi yang
akan digunakan
- Buka
software Proteus 8.17
- Persiapkan
alat dan bahan
- Buat rangkaian sesuai dengan kondisi
dan modul
- Buka
software STM32Cube IDE
- Setelah membuka software, pilih
perangkat STM32F103C8T6
- Sesuaikan konfigurasi pin sesuai
dengan rangkaian proteus
- Buat kode program untuk
mengoperasikan rangkaian tersebut sesuai dengan kondisi
- Konfigurasi kan program dengan
software Proteus
- Jalankan
simulasi rangkaian.
- Proses selesai
2. Hardware dan Diagram Blok [Kembali]
a. Hardware
1. STM32F103C8
HeartBeat sensor
atau sensor detak jantung merupakan perangkat input analog yang berfungsi untuk
mendeteksi denyut nadi manusia dengan prinsip fotopletismografi (PPG). Sensor
ini biasanya bekerja menggunakan infra merah dan fototransistor untuk mengukur perubahan
volume darah di dalam pembuluh darah kecil di ujung jari atau telinga. Sinyal
yang dihasilkan bersifat analog, sehingga memerlukan fitur ADC (Analog to
Digital Converter) pada mikrokontroler agar data detak jantung dapat diproses
dan dikonversi menjadi nilai Beats Per Minute (BPM).
Push button
adalah komponen sakelar sederhana yang berfungsi untuk menghubungkan atau
memutuskan aliran arus listrik dalam suatu rangkaian dengan cara menekan
tombolnya. Pada penggunaan mikrokontroler, komponen ini berperan sebagai
perangkat input digital yang bekerja berdasarkan prinsip logika high atau low,
di mana status penekanannya dapat dibaca oleh pin GPIO atau digunakan untuk
memicu mekanisme interrupt eksternal. Agar pembacaan sinyal tetap stabil dan
terhindar dari kondisi floating, push button biasanya dikonfigurasi menggunakan
resistor pull-up atau pull-down yang memastikan level tegangan input tetap
berada pada kondisi logika yang jelas saat tombol tidak sedang ditekan.
4. LED
b. Diagram Blok
3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]
a. Flowchart
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
*/
/* USER CODE END Header */
#include "main.h"
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN PV */
uint32_t adcValue = 0;
uint32_t filteredValue = 0;
uint8_t beatDetected = 0;
uint32_t BPM = 0;
uint32_t lastBeatTime = 0;
uint32_t interval = 0;
uint8_t buzzerOff = 0;
#define FILTER_SIZE 10
uint16_t buffer[FILTER_SIZE] = {0};
uint8_t indexBuf = 0;
uint32_t buzzerTime = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN 0 */
/* ================= FILTER ================= */
uint16_t moving_average(uint16_t val)
{
buffer[indexBuf++] = val;
if(indexBuf >= FILTER_SIZE) indexBuf = 0;
uint32_t sum = 0;
for(int i=0;i<FILTER_SIZE;i++) sum += buffer[i];
return sum / FILTER_SIZE;
}
/* ================= LED RGB ================= */
void LED_RGB(uint8_t r, uint8_t g, uint8_t b)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, r ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, g ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, b ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
void LED_Hijau() { LED_RGB(0,1,0); }
void LED_Kuning() { LED_RGB(1,0,0); }
void LED_Merah() { LED_RGB(0,0,1); }
void LED_Mati() { LED_RGB(0,0,0); }
/* ================= BUZZER ================= */
void Buzzer_On() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET); }
void Buzzer_Off() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET); }
/* USER CODE END 0 */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
uint32_t baseline = 0;
/* USER CODE END 2 */
while (1)
{
/* USER CODE BEGIN 3 */
/* ==== BACA ADC ==== */
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 10);
adcValue = HAL_ADC_GetValue(&hadc1);
/* ==== FILTER ==== */
filteredValue = moving_average(adcValue);
/* ==== BASELINE ==== */
baseline = (baseline * 9 + filteredValue) / 10;
uint32_t threshold = baseline + 50;
/* ==== DETEKSI DETAK ==== */
if(filteredValue > threshold && beatDetected == 0)
{
beatDetected = 1;
uint32_t now = HAL_GetTick();
if(lastBeatTime != 0)
{
interval = now - lastBeatTime;
if(interval > 0)
BPM = 60000 / interval;
}
if(BPM > 0 && BPM < 60)
{
Buzzer_On();
buzzerTime = now;
}
lastBeatTime = now;
}
if(BPM > 0 && BPM < 60)
{
if(HAL_GetTick() - buzzerTime > 80)
{
Buzzer_Off();
}
}
if(filteredValue < threshold)
{
beatDetected = 0;
}
/* ==== TIMEOUT ==== */
if(HAL_GetTick() - lastBeatTime > 2000)
{
BPM = 0;
}
/* ==== OUTPUT ==== */
if(BPM > 60)
{
LED_RGB(1,1,1);
if(!buzzerOff)
Buzzer_On();
else
Buzzer_Off();
}
else
{
LED_Mati();
}
HAL_Delay(5);
/* USER CODE END 3 */
}
}
/* ================= CLOCK ================= */
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.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
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;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
}
/* ================= ADC ================= */
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.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc1);
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5; // IMPORTANT
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
/* ================= GPIO ================= */
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11, GPIO_PIN_RESET);
/* BUTTON */
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI1_IRQn);
/* LED RGB + BUZZER */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* ================= INTERRUPT ================= */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_1)
{
buzzerOff = !buzzerOff;
}
}
/* ================= ERROR ================= */
void Error_Handler(void)
{
__disable_irq();
while (1) {}
}
5. Video Demo [Kembali]
6. Kondisi [Kembali]
8. Download File [Kembali]
- Download file lengkap (Rangkaian dan Program) (klik disini)
- Download video simulasi (klik disini)
- Download Datasheet Touch Sensor (klik disini)
- Download Datasheet Pir Sensor (klik disini)
- Download Datasheet Resistor (klik disini)
- Download Datasheet LED (klik disini)
- Download Datasheet Buzzer (klik disini)











