Percobaan 1 Kondisi 10




1. 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

2. Hardware [Kembali]

  • STM32F103C8

  • Touch Sensor

  • PIR Sensor
  • LED


  • Buzzer
  • Resistor 
  • Heart Beat Sensor

Diagram blog

                            


3. Rangkaian Simulasi dan Prinsip Kerja [Kembali]





  • Deteksi Sinyal Analog: Sensor Heartbeat bekerja dengan memancarkan cahaya ke pembuluh darah dan mendeteksi perubahan intensitas cahaya yang dipantulkan, yang kemudian dikonversi menjadi tegangan analog sesuai dengan denyut jantung pengguna.
  • Konversi Data (ADC): Mikrokontroler menerima sinyal analog tersebut melalui pin ADC (Analog to Digital Converter) untuk mengubah fluktuasi tegangan menjadi data digital yang dapat diolah secara matematis oleh prosesor.
  • Perhitungan BPM: Perangkat lunak melakukan kalkulasi berdasarkan interval antar puncak sinyal yang dideteksi dalam satuan waktu tertentu untuk menentukan nilai Beats Per Minute (BPM).
  • Komparasi Logika: Program menjalankan instruksi logika untuk membandingkan nilai BPM yang terbaca dengan nilai ambang batas (threshold) yang telah ditentukan, dalam hal ini adalah angka 60.

  • Eksekusi Kondisi Kurang dari 60: Ketika hasil perhitungan menunjukkan angka di bawah 60 (BPM < 60), prosesor akan mengirimkan sinyal logika High ke pin GPIO yang terhubung dengan LED Merah dan Buzzer.
  • Aktivasi Indikator Output: LED Merah akan menyala sebagai peringatan visual dan Buzzer akan aktif menghasilkan suara sebagai peringatan audio bahwa detak jantung berada di bawah normal.
  • Umpan Balik Real-time: Sistem terus melakukan pemindaian (looping) secara kontinu sehingga jika nilai BPM kembali menyentuh angka 60 atau lebih, maka status LED dan Buzzer akan berubah sesuai dengan algoritma program yang telah diatur.
  • Flowchart


  • Listing Program
#include "stm32f1xx_hal.h"

/* ================= HANDLE ================= */
ADC_HandleTypeDef hadc1;

/* ================= VARIABLE ================= */
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;

/* ================= FILTER ================= */
#define FILTER_SIZE 10
uint16_t buffer[FILTER_SIZE];
uint8_t indexBuf = 0;

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 ================= */
void LED_Hijau() {
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
}
void LED_Kuning() {
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
}
void LED_Merah() {
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
}
void LED_Mati() {
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_10, GPIO_PIN_RESET);
}

/* ================= 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);
}

/* ================= INTERRUPT ================= */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin == GPIO_PIN_1) // Tombol di PA1 untuk Mute Buzzer
    {
        buzzerOff = !buzzerOff;
    }
}

/* ================= PROTOTYPE ================= */
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void MX_ADC1_Init(void);

/* ================= MAIN ================= */
int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();

    uint32_t baseline = 0;

    while (1)
    {
        /* ==== BACA ADC ==== */
        HAL_ADC_Start(&hadc1);
        HAL_ADC_PollForConversion(&hadc1, 10);
        adcValue = HAL_ADC_GetValue(&hadc1);

        /* ==== FILTER ==== */
        filteredValue = moving_average(adcValue);

        /* ==== BASELINE (ADAPTIF) ==== */
        baseline = (baseline * 9 + filteredValue) / 10;
        uint32_t threshold = baseline + 50;

        /* ==== DETEKSI DETAK + INTERVAL ==== */
        if(filteredValue > threshold && beatDetected == 0)
        {
            beatDetected = 1;
            uint32_t now = HAL_GetTick();
            if(lastBeatTime != 0)
            {
                interval = now - lastBeatTime; 
                if(interval > 0) BPM = 60000 / interval;
            }
            lastBeatTime = now;
        }

        if(filteredValue < threshold)
        {
            beatDetected = 0;
        }

        /* ==== TIMEOUT (TIDAK ADA DETAK) ==== */
        if(HAL_GetTick() - lastBeatTime > 2000)
        {
            BPM = 0;
        }

        /* ==== OUTPUT LOGIC (SESUAI PERMINTAAN) ==== */
        if(BPM > 0)
        {
            if(BPM < 60)
            {
                // LED Merah hidup jika BPM di bawah 60
                LED_Mati();
                LED_Merah();
                if(!buzzerOff) Buzzer_On();
                else Buzzer_Off();
            }
            else if(BPM <= 80)
            {
                // LED Kuning hidup jika BPM 60-80
                LED_Mati();
                LED_Kuning();
                Buzzer_Off();
                buzzerOff = 0; // Reset status mute saat kembali normal
            }
            else
            {
                // LED Hijau hidup jika BPM di atas 80
                LED_Mati();
                LED_Hijau();
                Buzzer_Off();
                buzzerOff = 0;
            }
        }
        else
        {
            LED_Mati();
            Buzzer_Off();
        }

        HAL_Delay(5);
    }
}

/* ================= CLOCK CONFIG ================= */
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.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);
}

/* ================= ADC INIT ================= */
void MX_ADC1_Init(void)
{
    ADC_ChannelConfTypeDef sConfig = {0};
    __HAL_RCC_ADC1_CLK_ENABLE();

    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;
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}

/* ================= GPIO INIT ================= */
void MX_GPIO_Init(void)
{
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* PA0 = Input Sensor ADC */
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* PA1 = Button (Interrupt) */
    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);

    /* GPIOB: PIN 0(Hijau), 1(Kuning), 10(Merah), 11(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);

    /* Reset semua output ke LOW */
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_10 | GPIO_PIN_11, GPIO_PIN_RESET);
}

5. Video Demo [Kembali]



6. Kondisi [Kembali]

M2 P1 K10: Buatlah rangkaian seperti pada gambar percobaan 1 dengan kondisi Sensor Heartbeat membaca BPM < 60 , maka LED menyala merah dan Buzzer berbunyi

7. Video Simulasi [Kembali]


                                      

8. Download File [Kembali]

  • Rangkaian Simulasi [Klik]
  • Video Simulasi [Klik]





 

Komentar