Tugas Pendahuluan 1




a) Prosedur

- Siapkan seluruh komponen yang dibutuhkan seperti STM32F103C8, sensor heartbeat, LED hijau, LED kuning, LED merah, buzzer, resistor 220Ω, breadboard, kabel jumper, dan sumber tegangan.

- Rangkai komponen sesuai dengan diagram rangkaian, yaitu sensor heartbeat ke pin PA0, LED ke pin PB0, PB1, dan PB10, serta buzzer ke pin PB11.

- Pastikan semua koneksi sudah sesuai, tidak ada kabel yang longgar, dan jalur VCC serta GND terhubung dengan benar.

- Hubungkan board STM32 ke komputer menggunakan ST-LINK, lalu lakukan pemrograman sesuai dengan kode atau flowchart yang telah dibuat.

- Setelah program berhasil di-upload, jalankan sistem dan lakukan pengujian dengan menempelkan jari pada sensor heartbeat untuk memastikan rangkaian dan logika program bekerja dengan benar.


b) Hardware

1. STM32F103C8


2.Sensor HeartBeat

4. LED



6. Adaptor


Diagram blok:


c) Rangkaian Simulasi dan Prinsip Kerja



Gambar Rangkaian Modul 2 Percobaan 1 Kondisi 5

Prinsip kerja:

Prinsip kerja rangkaian ketika sensor heartbeat mendeteksi denyut nadi dari jari pengguna yang ditempelkan pada bagian sensor. Sensor heartbeat akan menghasilkan sinyal analog yang nilainya berubah-ubah mengikuti irama detak jantung. Sinyal tersebut kemudian dikirimkan ke mikrokontroler STM32F103C8 melalui pin ADC pada PA0 untuk diproses menjadi data BPM (Beat Per Minute). Pada rangkaian ini, STM32 berfungsi sebagai pusat pengendali yang membaca data sensor secara terus-menerus, menghitung jumlah denyut jantung per menit, lalu menentukan kondisi detak jantung berdasarkan batas nilai yang telah diprogram sebelumnya.

Setelah nilai BPM diperoleh, mikrokontroler akan membandingkan hasil pembacaan dengan rentang kondisi yang telah ditentukan. Jika nilai BPM kurang dari 30 atau lebih dari 80, maka sistem akan menganggap kondisi detak jantung berada pada keadaan tidak normal atau berbahaya. Dalam kondisi tersebut, STM32 akan memberikan logika HIGH pada pin output yang terhubung ke LED merah dan buzzer sehingga LED merah menyala dan buzzer berbunyi sebagai tanda peringatan kepada pengguna. Kondisi ini menunjukkan bahwa detak jantung terlalu lambat atau terlalu cepat sehingga memerlukan perhatian lebih lanjut.

Apabila nilai BPM berada pada rentang 30 hingga 60, maka sistem menganggap detak jantung berada pada kondisi rendah atau di bawah normal. Pada kondisi ini, mikrokontroler akan mengaktifkan LED kuning sebagai indikator peringatan sedang. LED merah dan buzzer akan tetap mati karena kondisi belum masuk kategori bahaya. Selanjutnya, jika nilai BPM berada pada rentang 60 hingga 80, maka sistem menganggap detak jantung berada dalam kondisi normal. STM32 kemudian mengaktifkan LED hijau sebagai indikator bahwa denyut jantung pengguna berada pada batas normal dan stabil.

Pada rangkaian tersebut juga digunakan resistor 220Ω pada masing-masing LED untuk membatasi arus agar LED tidak rusak saat dialiri tegangan. Selain itu, buzzer digunakan sebagai indikator suara ketika kondisi detak jantung berada di luar batas normal. Seluruh sistem bekerja menggunakan catu daya 3,3V yang sesuai dengan kebutuhan STM32 dan sensor heartbeat. 

d) Flowchart



Listing Program

#include "stm32f1xx_hal.h"


/* ================= HANDLE ================= */

ADC_HandleTypeDef hadc1;


/* ================= VARIABLE ================= */

uint32_t adcValue = 0;

uint32_t filteredValue = 0;

uint32_t baseline = 0;


uint8_t beatDetected = 0;

uint32_t BPM = 0;

uint32_t lastBeatTime = 0;

uint32_t interval = 0;


/* ================= STATUS SISTEM ================= */

/* 1 = ON, 0 = OFF */

volatile uint8_t systemOn = 1;


/* ================= FILTER ================= */

#define FILTER_SIZE 10


uint16_t buffer[FILTER_SIZE] = {0};

uint8_t indexBuf = 0;


/* ================= PROTOTYPE ================= */

void SystemClock_Config(void);

void MX_GPIO_Init(void);

void MX_ADC1_Init(void);


/* ================= FILTER ================= */

uint16_t moving_average(uint16_t val)

{

buffer[indexBuf] = val;


indexBuf++;


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(void)

{

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOB,

GPIO_PIN_1 | GPIO_PIN_10,

GPIO_PIN_RESET);

}


void LED_Kuning(void)

{

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOB,

GPIO_PIN_0 | GPIO_PIN_10,

GPIO_PIN_RESET);

}


void LED_Merah(void)

{

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOB,

GPIO_PIN_0 | GPIO_PIN_1,

GPIO_PIN_RESET);

}


void LED_Mati(void)

{

HAL_GPIO_WritePin(GPIOB,

GPIO_PIN_0 |

GPIO_PIN_1 |

GPIO_PIN_10,

GPIO_PIN_RESET);

}


/* ================= BUZZER ================= */

void Buzzer_On(void)

{

HAL_GPIO_WritePin(GPIOB,

GPIO_PIN_11,

GPIO_PIN_SET);

}


void Buzzer_Off(void)

{

HAL_GPIO_WritePin(GPIOB,

GPIO_PIN_11,

GPIO_PIN_RESET);

}


/* ================= INTERRUPT ================= */

/*

PA1 = Pushbutton ON/OFF sistem

Tekan sekali = OFF

Tekan lagi = ON

*/

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

static uint32_t debounceTime = 0;


if(GPIO_Pin == GPIO_PIN_1)

{

/* Debounce 200ms */

if(HAL_GetTick() - debounceTime < 200)

return;


debounceTime = HAL_GetTick();


/* Toggle sistem */

systemOn = !systemOn;


/* Jika sistem dimatikan */

if(systemOn == 0)

{

LED_Mati();

Buzzer_Off();


BPM = 0;

beatDetected = 0;

lastBeatTime = 0;

interval = 0;

baseline = 0;

}

}

}


/* ================= MAIN ================= */

int main(void)

{

HAL_Init();


SystemClock_Config();

MX_GPIO_Init();

MX_ADC1_Init();


while(1)

{

/* ================= SISTEM OFF ================= */

if(systemOn == 0)

{

LED_Mati();

Buzzer_Off();


HAL_Delay(50);

continue;

}


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

}

}


lastBeatTime = now;

}


/* Reset detector */

if(filteredValue < threshold)

{

beatDetected = 0;

}


/* Timeout sensor */

if(HAL_GetTick() - lastBeatTime > 2000)

{

BPM = 0;

}


/* ================= OUTPUT ================= */

if(BPM > 0)

{

/* BPM abnormal */

if(BPM < 30 || BPM > 80)

{

LED_Merah();

Buzzer_On();

}


/* BPM 30-60 */

else if(BPM >= 30 && BPM <= 60)

{

LED_Kuning();

Buzzer_Off();

}


/* BPM 60-80 */

else if(BPM > 60 && BPM <= 80)

{

LED_Hijau();

Buzzer_Off();

}

}

else

{

LED_Mati();

Buzzer_Off();

}


HAL_Delay(2);

}

}


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


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

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

void MX_GPIO_Init(void)

{

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();


GPIO_InitTypeDef GPIO_InitStruct = {0};


/* PA0 = Sensor ADC */

GPIO_InitStruct.Pin = GPIO_PIN_0;

GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;


HAL_GPIO_Init(GPIOA,

&GPIO_InitStruct);


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


/* Enable interrupt */

HAL_NVIC_SetPriority(EXTI1_IRQn,

0, 0);


HAL_NVIC_EnableIRQ(EXTI1_IRQn);


/* PB0, PB1, PB10, PB11 = output */

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);


HAL_GPIO_WritePin(GPIOB,

GPIO_PIN_0 |

GPIO_PIN_1 |

GPIO_PIN_10 |

GPIO_PIN_11,

GPIO_PIN_RESET);

}

e) Video Demo


f) Kondisi

Buatlah rangkaian seperti pada gambar percobaan 1 namun interuptnya berubah fungsi menjadi kontak on/off seluruh sistem

g) Video Simulasi


Video Penjelasan Percobaan 1 Kondisi 5

h) Download File

Komentar

Postingan populer dari blog ini

Figure 7.21

Figure 8.17

Figure 12.19