Pendeteksi Detak Jantung Dan Saturasi Oksigen (Oximeter)

by Angelene in Circuits > Electronics

356 Views, 1 Favorites, 0 Comments

Pendeteksi Detak Jantung Dan Saturasi Oksigen (Oximeter)

trs4.jpg

Anggota Kelompok:

  • ANGELENE AGUSTINA (2502013952)
  • BISMA AGAM GUNAWAN (2502010414)
  • MOHAMMAD HISYAM ABDUR RAUF NASRULLAH (2502032730)
  • Kevin Juan (2540118183)


BAB 1. PENDAHULUAN

1.1 Latar Belakang

Jantung merupakan salah satu organ terpenting dengan pekerjaan yang sulit. Beberapa indikator yang dapat mempengaruhi kesehatan jantung dan paru seseorang adalah faktor detak jantung dan saturasi oksigen (SPO2). Tugas jantung adalah mengalirkan darah ke seluruh tubuh. Segala sesuatu yang dikonsumsi orang dan aktivitas sehari-hari dapat mempengaruhi penyakit jantung. Seiring bertambahnya usia, fungsi jantung menjadi semakin terganggu. Jantung terus berdetak terus menerus dan melambat seiring bertambahnya usia (Pearce, 2000).

Dalam kondisi normal, detak jantung manusia adalah 60–100 detak per menit (Gamara & Hendryani, 2019). Detak jantung yang normal dapat membantu mengangkut oksigen ke seluruh tubuh. Fungsi jantung juga dipengaruhi oleh saturasi oksigen. Saturasi oksigen mempengaruhi sistem pernapasan. Jika pernapasan terganggu, saturasi oksigen rendah. Saturasi oksigen normal mendukung fungsi jantung dan mencegah kelelahan. Saturasi oksigen yang rendah menyebabkan peningkatan detak jantung, kelelahan, penurunan penglihatan dan pusing. Karena itu, pemantauan detak jantung dan saturasi oksigen sangat penting. Dan salah satu cara memeriksa detak jantung yaitu melalui denyut nadi.

Denyut nadi diukur di pergelangan tangan untuk memeriksa detak jantung dan saturasi oksigen secara manual. Namun pengukuran dengan metode ini tidak memungkinkan pencatatan langsung aktivitas detak jantung atau saturasi oksigen (Qahar, 2018). Kemajuan ilmu pengetahuan modern telah mengantarkan pada perkembangan teknologi yang dapat digunakan untuk mendukung dan memudahkan aktivitas manusia di berbagai bidang, termasuk kedokteran. Ketertarikan orang pada hal-hal teknis yang dapat membantu mereka dalam pekerjaannya berarti bahwa teknologi berkembang lebih cepat untuk membantu orang melakukan pekerjaannya. Desain yang meningkatkan dan memudahkan pekerjaan khususnya di bidang kesehatan sangat bermanfaat bagi masyarakat (Aldi et al., 2021). 

Oleh karena itu penelitian ini akan mengembangkan alat yang dapat mengukur detak jantung dan saturasi oksigen secara online, sehingga dapat dicek langsung dengan smartphone. Pemantauan ini menggunakan sistem IoT (Internet of Things). Teknologi IoT digunakan di berbagai industri dalam pengembangan perangkat kendali jarak jauh, termasuk sektor kesehatan. Penelitian ini menggunakan sensor max30100 yang menggunakan ardion pada platform.io dan firebase dan menerapkannya pada flutter. 

Teknologi elektronik khususnya sensor telah berkembang untuk melayani kebutuhan manusia dengan baik (Hidayatullah & Sudirman, 2017). Sensor MAX30100 adalah sensor detak jantung dan saturasi oksigen darah (SPO2) yang terbukti menawarkan akurasi tinggi dengan harga murah (Zafia, 2020).  

Flutter adalah program yang menampilkan apa yang dibuat oleh pengguna ke aplikasi atau website sendiri. Kelebihan aplikasi flutter adalah dapat mewujudkan apa yang ingin kita tunjukan dan juga bersifat online. Pada penelitian menggunakan tampilan LCD dan flutter untuk menampilkan hasil pembacaan sensor MAX30100. Flutter digunakan karena memiliki keunggulan dapat menampilkan lebih banyak hal di dalamnya, sedangkan LCD menampilkan lebih sedikit karena komponennya berukuran kecil. Selain itu juga penggunaan flutter memudahkan pengguna alat ini untuk memantau kesehatan jantung dan saturasi oksigen dengan jarak jauh. Tujuan dari penelitian ini adalah menggunakan flutter untuk memonitor denyut jantung dan saturasi oksigen (SPO2). Dengan cara tersebut tentunya dibandingkan cara manual akan lebih memudahkan masyarakat (Rohmah et al., 2020).


1.2 Rumusan Masalah

Berdasarkan latar belakang tersebut, maka penelitian ini memiliki rumusan masalah yaitu:

  1. Bagaimana merancang monitor detak jantung dan saturasi oksigen (SPO2) dengan sensor MAX30100 berdasarkan Internet of Things (IoT)? 
  2. Apakah perkembangan teknologi IoT dan sensor dalam pengembangan alat pemantau detak jantung dan saturasi oksigen bisa secara online yang dapat diakses melalui smartphone?
  3. Bagaimana cara menggunakan aplikasi Flutter dan layar LCD untuk memantau detak jantung dan saturasi oksigen serta apa manfaat dan keuntungan memantau kesehatan jantung dan saturasi oksigen dibandingkan metode manual?
  4. Bagaimana cara merancang dan mengimplementasikan sensor MAX30100 dalam aplikasi yang memantau detak jantung dan tingkat oksigen dalam darah secara real-time?
  5. Bagaimana mengatasi gangguan cahaya ambient agar pengukuran dengan sensor MAX30100 dapat akurat dan konsisten?
  6. Bagaimana mengoptimalkan kinerja sensor MAX30100 untuk mengukur detak jantung dan tingkat oksigen dalam darah pada berbagai kondisi fisik dan lingkungan yang berbeda?


1.3 Tujuan dan Manfaat

Tujuan dari penelitian ini adalah sebagai berikut:

  1. mengembangkan alat yang dapat mengukur detak jantung dan saturasi oksigen secara online menggunakan sistem IoT dan sensor MAX30100.
  2. Menerapkan teknologi Flutter untuk pemantauan detak jantung dan saturasi oksigen secara real-time yang dapat digunakan di smartphone.
  3. Memudahkan akses dan kemudahan dalam memantau kesehatan jantung dan saturasi oksigen di masyarakat dengan menggunakan web-enabled tools.
  4. Mengetahui Kesehatan jantung serta mengetahui jumlah kadar oksigen dalam tubuh

Keunggulan dari penelitian ini adalah sebagai berikut:

  1. Meningkatnya pemahaman dan kesadaran masyarakat akan pentingnya pemantauan detak jantung dan saturasi oksigen sebagai indikator kesehatan jantung dan paru.
  2. membantu mengidentifikasi dan memantau kecepatan detak jantung Anda dalam berbagai situasi, seperti saat berolahraga, istirahat, stres, atau aktivitas sehari-hari.
  3. Memberikan solusi teknologi yang efektif dan terjangkau untuk pemantauan kesehatan jantung dan saturasi oksigen secara real-time untuk memfasilitasi deteksi dini dan pengobatan yang tepat.
  4. Meningkatkan aksesibilitas pemantauan kesehatan jantung dan saturasi oksigen pada smartphone sehingga dapat dilakukan di mana saja, kapan saja.
  5. meningkatkan efisiensi dan akurasi pengukuran detak jantung dan saturasi oksigen dengan sensor MAX30100 dengan akurasi tinggi yang terbukti dengan harga terjangkau.
  6. Mengurangi ketergantungan pada metode pemantauan detak jantung dan saturasi oksigen manual, menghemat waktu dan tenaga dalam pemantauan kesehatan.


1.4 Ruang Lingkup

Ruang lingkup dari penelitian ini adalah sebagai berikut:

  1. Penelitian ini membatasi penggunaan sensor MAX30100 untuk mengukur detak jantung dan saturasi oksigen. Tidak ada sensor atau metode lain yang digunakan untuk pengukuran.
  2. Penelitian ini menggunakan teknologi Arduino, OLED, Flutter dan Firebase untuk menampilkan pembacaan dari sensor MAX30100. Tidak termasuk penggunaan platform atau teknologi lain untuk membuat aplikasi.
  3. Penelitian ini berfokus pada pemantauan detak jantung dan saturasi oksigen secara online dan real-time. Tidak termasuk mengukur atau memantau aspek kesehatan lainnya seperti tekanan darah atau suhu tubuh.
  4. Penelitian ini membatasi pengujian dan validasi alat pada tingkat penggunaan individu. Pengujian ekstensif atau penggunaan perangkat ini di lingkungan klinis atau rumah sakit tidak tercakup.
  5. Penelitian ini berfokus pada pengembangan alat dan implementasinya menggunakan sensor MAX30100, Arduino, Flutter, Firebase dan display LCD. Aspek pengembangan perangkat tambahan atau perubahan komponen lain tidak tercakup. 


1.5 Tinjauan Pustaka

Pada penelitian sebelumnya oleh Ramadhan (2021) untuk mengembangkan teknologi pemantauan berbasis IoT yang mampu menganalisis kesehatan manusia menggunakan parameter detak jantung. Pada alat ini mikrokontroler NodeMCU digunakan untuk mengontrol sistem Internet of Things dan pulse sensor digunakan untuk mendeteksi detak jantung. Data keluaran kemudian dikirim ke 2 keluaran, yang pertama ditampilkan di layar LCD dan dikirim ke aplikasi smartphone. Dua buah mikrokontroler digunakan dalam penelitian ini, yaitu Arduino Uno dan nodeMCU 8266. Mikrokontroler Arduino Uno berfungsi sebagai transfer data ke sensor MAX30100 dan layar LCD sedangkan NodeMCU 8266 berfungsi sebagai komunikasi transfer data ke aplikasi Telegram. 

Penelitian serupa lainnya dilakukan oleh Imanda et al. (2020) dengan tujuan mengembangkan alat untuk memantau detak jantung, saturasi oksigen darah (SPO2) dan suhu tubuh pada pasien COVID-19. Alat pendeteksi ini hadir dalam bentuk gelang yang terdiri dari beberapa perangkat penting yaitu NodeMCU ESP8266 sebagai mikrokontroler, TCA9548A sebagai multiplexer, sensor AD8232 untuk mendeteksi detak jantung, sensor MAX30100 untuk sensor saturasi oksigen dan sensor suhu tubuh dengan MPU6050. Metode analisis penelitian ini adalah metode komparatif, yaitu membandingkan hasil pengukuran oksimeter klinis dan termometer dengan alat yang dikembangkan. Hasil penelitian ini menunjukkan kesalahan besar pada pengukuran detak jantung yaitu 4,12%, sedangkan kesalahan kecil pada pengukuran saturasi oksigen dan suhu tubuh yaitu 1,27 x 0,35%. 

Berdasarkan tinjauan pustaka ini, kami ingin membuat penelitian ini dikarenakan adanya tugas rancang untuk membuat suatu alat yang dihubungkan ke arduino, firebase, dan flutter, serta keingintahuan kami untuk menggunakan alat yang mirip lalu disambungkan ke firebase dan flutter dan menjadikan alatnya.



Supplies

  • Sensor MAX30100
  • Flutter
  • VS Code
  • Arduino
  • ESP32 DevKit V1
  • Jumper
  • Display OLED
  • Button
  • Firebase

Landasan Teori

Prinsip Pengukuran Detak Jantung dan Saturasi Oksigen

Pengukuran detak jantung dan saturasi oksigen non-invasif dapat dilakukan dengan menggunakan teknik photoplethysmography. PPG menggunakan perubahan cahaya yang diserap oleh hemoglobin dalam darah saat melewati jaringan tubuh. Saat jantung berdetak, volume darah di pembuluh darah berubah, memengaruhi jumlah cahaya yang dipantulkan atau diserap. Perubahan ini digunakan untuk menghitung detak jantung. Pada saat yang sama, saturasi oksigen dapat diukur dengan membandingkan jumlah cahaya merah dan inframerah yang dipantulkan oleh darah. Kadar oksigen darah dapat ditentukan dengan membandingkan intensitas cahaya. 

Dalam mewujudkan penelitian kami, penelitian ini diperlukan informasi serta alat-alat untuk membuat sensor detak jantung dan saturasi oksigen secara online. Berikut adalah beberapa hal yang diperlukan: 

2.1 Sensor MAX30100

Sensor MAX30100 adalah sensor detak jantung dan saturasi oksigen darah (SPO2). Sensor ini menggunakan teknologi photoplethysmography (PPG) untuk mendeteksi perubahan volume darah pada pembuluh darah di bawah kulit. Sensor MAX30100 mengirimkan cahaya inframerah melalui kulit dan mendeteksi cahaya yang dipantulkan. Perubahan intensitas cahaya yang dipantulkan digunakan untuk menghitung detak jantung dan mengukur kadar oksigen dalam darah. 

2.2 Teknologi Flutter

Flutter adalah framework open-source yang dikembangkan oleh Google untuk membuat antarmuka pengguna (UI) yang menarik dan responsif yang dapat digunakan di berbagai platform termasuk Android dan iOS. Flutter menggunakan bahasa pemrograman Dart untuk mengembangkan aplikasi seluler menggunakan pendekatan pemrograman deklaratif. Kekuatan Flutter adalah kemampuannya untuk membuat antarmuka pengguna yang kaya dan interaktif serta kemudahan pengembangannya di seluruh platform. 

2.3 Prinsip Pengukuran Detak Jantung dan Saturasi Oksigen

Pengukuran detak jantung dan saturasi oksigen non-invasif dapat dilakukan dengan menggunakan teknik photoplethysmography. PPG menggunakan perubahan cahaya yang diserap oleh hemoglobin dalam darah saat melewati jaringan tubuh. Saat jantung berdetak, volume darah di pembuluh darah berubah, memengaruhi jumlah cahaya yang dipantulkan atau diserap. Perubahan ini digunakan untuk menghitung detak jantung. Pada saat yang sama, saturasi oksigen dapat diukur dengan membandingkan jumlah cahaya merah dan inframerah yang dipantulkan oleh darah. Kadar oksigen darah dapat ditentukan dengan membandingkan intensitas cahaya. 

2.4 Teknologi Arduino

Arduino adalah platform open source untuk mengembangkan perangkat elektronik. Arduino menggunakan bahasa pemrograman yang mudah dipahami dan memiliki development environment (IDE) yang mudah digunakan. Arduino dapat digunakan untuk mengontrol dan memproses data dari sensor seperti MAX30100. Pada penelitian ini Arduino digunakan untuk menghubungkan dan mengintegrasikan sensor MAX30100 ke platform Flutter melalui komunikasi serial. 

2.5 Firebase

Firebase adalah platform pengembangan aplikasi yang disediakan oleh Google. Firebase menawarkan layanan seperti penyimpanan data real-time, autentikasi pengguna, dan hosting aplikasi. Pada penelitian ini, Firebase dapat digunakan untuk menyimpan dan mengelola data detak jantung dan saturasi oksigen yang dihasilkan oleh sensor MAX30100. Data ini dapat dilihat dan dilihat secara online menggunakan aplikasi Flutter. Firebase juga menawarkan kemampuan untuk mengaktifkan fitur tambahan seperti notifikasi dan analisis data. 

2.6 OLED (Organic Light-Emitting Diode) Display

OLED adalah teknologi tampilan di mana bahan organik menghasilkan cahaya saat arus listrik dialirkan. OLED menawarkan keunggulan seperti kontras tinggi, waktu respons cepat, dan sudut pandang lebar. Pada penelitian ini, lampu OLED digunakan sebagai display untuk menampilkan data detak jantung dan saturasi oksigen yang diukur oleh sensor MAX30100. Data yang diperoleh dapat ditampilkan secara real time pada layar OLED sehingga memungkinkan pemantauan langsung terhadap pengguna. 

2.7 Tombol (Button)

Tombol (Button) adalah perangkat input yang digunakan untuk mengaktifkan atau menonaktifkan fungsi tertentu dari suatu alat. Dalam penelitian ini, tombol digunakan untuk memberi pengguna kendali atas fungsi pemantauan detak jantung dan saturasi oksigen. Dengan menekan tombol tersebut, pengguna dapat memulai atau menghentikan pemantauan. Tombol ini bertindak sebagai input pengguna yang menggerakkan Arduino untuk mengontrol monitor. 

2.8 ESP32 WROOM DevKit V1

ESP32 WROOM DevKit V1 adalah modul mikrokontroler berbasis ESP32 dengan kemampuan Wi-Fi dan Bluetooth yang kuat. Modul ini memiliki kecepatan prosesor yang tinggi, memori yang cukup, serta dukungan komunikasi dan koneksi yang luas. Pada penelitian ini digunakan ESP32 WROOM DevKit V1 sebagai main controller yang mengintegrasikan semua komponen seperti sensor MAX30100, OLED, tombol dan komunikasi dengan Firebase melalui WiFi. 

Berikut adalah fungsi pin NodeMCU:

  1. EN, RST: pin yang digunakan untuk mereset program pada mikrokontroler
  2. ADC: merupakan pin yang digunakan untuk membaca input data secara analog.
  3. 3.3 V: digunakan sebagai sumber tegangan untuk beberapa perangkat lain.
  4. GND: Ground, sebagai tegangan 0 atau nilai negatif untuk mengalirkan arus
  5. Vin: sebagai sumber daya eksternal yang mempengaruhi output semua pin.
  6. GPIO 1 – GPIO 16: pin input dan pin output yang dapat membaca dan mengirimkan data secara analog juga
  7. SD1, CMD, SD0, CLK: pin untuk komunikasi SPI (Serial Peripheral Interface), dimana clock akan digunakan untuk menyinkronkan bit deteksi pada penerima
  8. TXD0, RXD0, TXD2, RXD2: TXDO dengan RXD0 dan TXD2 dengan RXD2 adalah pasangan antarmuka UART. TXD1 adalah perangkat yang memungkinkan anda mengunggah firmware atau program.
  9. SDA, SCL (I2C Pin): digunakan untuk perangkat yang membutuhkan I2C.


Metode Pelaksanaan

bdtriots4.png
fctriots4.png
21332.jpg

Program pengembangan alat pemantau detak jantung dan saturasi oksigen online mencakup beberapa langkah penting. Fase perencanaan melibatkan identifikasi masalah, menetapkan tujuan dan merencanakan pekerjaan. Tahap pengumpulan data awal meliputi persiapan sensor dan perangkat, pemasangan sensor, dan uji pendahuluan untuk memastikan kesiapan pemantauan. Selain itu, fase desain meliputi desain sistem, koneksi dan komunikasi antar komponen, dan implementasi desain unit kontrol. Fase pengujian pekerjaan yang andal memastikan fungsionalitas, konektivitas, dan penggunaan alat dengan baik. Terakhir, langkah pengumpulan, pengolahan, dan analisis data dilakukan untuk mengumpulkan, mengolah, dan menganalisis data untuk mendapatkan informasi yang relevan. Dengan melakukan langkah-langkah tersebut, diharapkan program ini dapat mencapai tujuannya untuk menciptakan pelacak yang efektif yang dapat bermanfaat bagi pengguna. Berikut adalah penjelasan lebih rinci dari langkah-langkah tersebut:

  • Tahap Perencanaan:

- Identifikasi Permasalahan: Identifikasi masalah yang akan dipecahkan yaitu mengembangkan alat monitoring detak jantung dan saturasi oksigen online menggunakan sensor MAX30100, ESP32 WROOM DevKit V1, OLED, Buttons, Flutter dan Firebase.

- Penentuan Tujuan: Tentukan tujuan yang ingin dicapai oleh program ini yaitu membuat alat monitoring yang dapat mengukur dan memonitor detak jantung dan saturasi oksigen secara online dengan menggunakan teknologi di atas.

- Perencanaan Pekerjaan: Merencanakan tahapan pekerjaan yang diperlukan untuk mencapai tujuan program, seperti koleksi data awal, rekayasa keteknikan, uji keandalan karya, teknik koleksi, pengolahan, dan analisis data.

  • Tahap Koleksi Data Awal:

- Persiapan Sensor dan Perangkat: Menghubungkan dan memastikan sensor MAX30100, ESP32 WROOM DevKit V1, OLED, tombol, dan komponen lainnya terpasang dengan benar dan berfungsi dengan baik.

- Pengaturan Sensor: Atur dan kalibrasikan sensor MAX30100 sesuai dengan spesifikasi yang diberikan untuk mendapatkan pembacaan yang akurat.

- Pengujian Awal: Uji kinerja sensor dan perangkat lain untuk memastikan bahwa nilai detak jantung dan saturasi oksigen yang diberikan oleh sensor MAX30100 sesuai dengan referensi yang diuji.

  • Tahap Rekayasa Keteknikan:

- Perancangan Sistem: Sistem pemantauan detak jantung dan saturasi oksigen dikembangkan dengan ESP32 WROOM DevKit V1 sebagai pengontrol utama. Untuk antarmuka pengguna dilakukan dengan Flutter dan terdapat hardware lainnya yang menyambungkan ke OLED dan Button.

- Koneksi dan Komunikasi: Siapkan koneksi WiFi untuk ESP32 agar terhubung ke Firebase dan mengirimkan data detak jantung dan saturasi oksigen secara online.

- Implementasi Desain: Membuat dan menyusun komponen-komponen alat pemantau sesuai dengan desain yang telah direncanakan, termasuk rangkaian sensor, mikrokontroler, layar OLED, tombol, dan koneksi ke Firebase.

  • Tahap Uji Keandalan Karya:

- Uji Fungsionalitas: Jalankan tes untuk memastikan monitor mengukur detak jantung dan saturasi oksigen secara akurat. Memastikan keandalan membaca dan menampilkan data pada layar OLED dengan membandingkannya dengan perangkat referensi atau pemantauan yang telah teruji.

- Uji Konektivitas: Uji koneksi Wi-Fi dan transfer data Anda dengan Firebase untuk memastikan data dikirim dan disimpan dengan benar. Periksa stabilitas koneksi dan kecepatan respons sistem juga.

- Uji Penggunaan: Melibatkan pengguna dalam penggunaan layar dan kumpulkan umpan balik tentang kegunaan, kemudahan penggunaan, dan kejelasan informasi pada layar OLED.

  • Tahap Koleksi, Pengolahan, dan Analisis Data:

- Koleksi Data: Monitor terus mengukur detak jantung dan saturasi oksigen Anda dan mengirimkannya ke Firebase. Data yang dikumpulkan disimpan dalam database Firebase untuk diproses dan dianalisis lebih lanjut.

- Pengolahan Data: Data yang dikumpulkan dapat diproses dan diproses menggunakan berbagai teknik, seperti pemulusan data, deteksi dan pemrosesan anomali, atau penghapusan data yang salah. Tujuan dari proses ini adalah untuk memastikan keakuratan data sebelum dilakukan analisis lebih lanjut.

- Analisis Data: Data detak jantung dan saturasi oksigen yang diproses dapat dianalisis untuk wawasan atau data yang relevan. Ini mungkin termasuk teknik analisis statistik seperti menghitung nilai rata-rata, standar deviasi atau analisis tren dari data yang dikumpulkan.

Sistem pemantauan detak jantung dan saturasi oksigen online dikembangkan menggunakan sensor MAX30100, ESP32 WROOM DevKit V1, OLED, Buttons, Flutter, dan Firebase. Alat ini dirancang untuk mengukur dan memantau detak jantung dan saturasi oksigen pengguna secara real time. Sensor MAX30100 digunakan untuk pengukuran detak jantung dan saturasi oksigen, yang kemudian dikirim ke ESP32 sebagai pengontrol utama. Data yang dihasilkan ditampilkan pada layar OLED dan dapat dikontrol dengan tombol. Sistem ini juga terhubung dengan Firebase, sehingga data dapat disimpan secara online. Pengguna dapat memantau detak jantung dan saturasi oksigen mereka melalui aplikasi Flutter yang terhubung dengan Firebase, yang menyediakan pemantauan kesehatan real-time yang nyaman dan mudah digunakan. 

3.2 Cara Kerja Sistem

Cara kerja sistem pemantauan detak jantung dan saturasi oksigen online ini dimulai dengan sensor MAX30100, yang mendeteksi dan mengukur detak jantung dan saturasi oksigen pengguna. Data yang diterima kemudian dikirim ke ESP32 WROOM DevKit V1 sebagai pengendali utama. ESP32 mengambil data ini dan mengirimkannya ke Firebase untuk penyimpanan online.

Lalu ESP32 juga mengontrol tampilan informasi di layar OLED. Informasi detak jantung dan saturasi oksigen real-time ditampilkan di layar OLED, memungkinkan pengguna memantau status kesehatan mereka dengan mudah. Tombol tersebut digunakan untuk interaksi pengguna dan memungkinkan pengguna untuk menyalakan dan mematikan proses pemantauan.

Pengguna juga dapat melihat data detak jantung dan saturasi oksigen secara online melalui aplikasi Flutter yang terhubung dengan Firebase. Melalui aplikasi, pengguna dapat melacak riwayat data mereka.

3.3 Blok Diagram

3.4 Diagram Alir (Flow Chart)

3.5 Perancangan Perangkat Keras (Skematik, Perancangan hardware)

3.6 Perancangan Perangkat Lunak 

  • PlatformIO:

#include <Arduino.h>

#include <WiFi.h>

#include <Wire.h>

#include "MAX30100_PulseOximeter.h"


#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#include <Firebase_ESP_Client.h>


// Provide the token generation process info.

#include "addons/TokenHelper.h"

// Provide the RTDB payload printing info and other helper functions.

#include "addons/RTDBHelper.h"


// Insert your network credentials

#define WIFI_SSID "Bisma"

#define WIFI_PASSWORD "12345678"


// Insert Firebase project API Key

#define API_KEY "AIzaSyChzoj8rsnEjWeiUeBNyzTw3-G1joZkJM8"


// Insert RTDB URLefine the RTDB URL

#define DATABASE_URL "https://lortbims-default-rtdb.asia-southeast1.firebasedatabase.app/"


// Define Firebase Data object

FirebaseData fbdo;

FirebaseAuth auth;

FirebaseConfig config;


unsigned long sendDataPrevMillis = 0;

int count = 150;

bool signupOK = false;

bool uploadFlag = false;


#define SCREEN_WIDTH 128

#define SCREEN_HEIGHT 64

#define OLED_RESET -1


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


// Put your SSID & Password/


const char *ssid = "Bisma";    // Enter SSID here

const char *password = "12345678"; // Enter Password here


#define REPORTING_PERIOD_MS 1000

float BPM, SpO2;

PulseOximeter pox;

uint32_t tsLastReport = 0;


void onBeatDetected()

{

  Serial.println("Beat Detected!");

}


void sendToFirebase()

{

  Serial.println("sendToDb");

    if (Firebase.RTDB.setFloat(&fbdo, "data/BPM", BPM))

   {

     Serial.println("PATH: " + fbdo.dataPath());

     Serial.println("TYPE: " + fbdo.dataType());

     Serial.println("PASSED");

   }

   else

   {

     Serial.println("FAILED");

     Serial.println("REASON: " + fbdo.errorReason());

   }

   if (Firebase.RTDB.setFloat(&fbdo, "data/SpO2", SpO2))

   {

     Serial.println("PASSED");

     Serial.println("PATH: " + fbdo.dataPath());

     Serial.println("TYPE: " + fbdo.dataType());

   }

   else

   {

     Serial.println("FAILED");

     Serial.println("REASON: " + fbdo.errorReason());

   }

  uploadFlag = false;

}


void sendFirebaseFlag()

{

   uploadFlag = true;

  static unsigned long last_interrupt_time = 0;

  unsigned long interrupt_time = millis();

  if (interrupt_time - last_interrupt_time > 100)

  {

    uploadFlag = true;

    last_interrupt_time = interrupt_time;

  }

}


void setup()

{

  pinMode(5, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(5), sendFirebaseFlag, FALLING);

  Serial.begin(9600);

  pinMode(19, OUTPUT);

  delay(100);


  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  // Serial.print("Connecting to Wi-Fi");

  while (WiFi.status() != WL_CONNECTED)

  {

    Serial.print(".");

    delay(250);

  }

  Serial.println();

  Serial.print("Connected with IP: ");

  Serial.println(WiFi.localIP());

  Serial.println();


  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))

  {

    Serial.println(F("SSD1306 alokasi gagal!"));

    while (true)

      ;

  }


  Serial.print("Initializing pulse oximeter..");


  if (!pox.begin())

  {

    Serial.println("FAILED");

    for (;;)

      ;

  }

  else

  {

    Serial.println("SUCCESS");

    pox.setOnBeatDetectedCallback(onBeatDetected);

  }

  pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);


  display.clearDisplay();

  display.setTextColor(WHITE);

  display.setTextSize(1);

  display.setCursor(0, 0);

  display.println(F("MAX30100 Oximeter"));

  display.display();


  delay(2000);


  // Assign the api key (required)

  config.api_key = API_KEY;


  // Assign the RTDB URL (required)

  config.database_url = DATABASE_URL;


  /* Sign up */


  if (Firebase.signUp(&config, &auth, "", ""))

  {

    Serial.println("ok");

    signupOK = true;

  }

  else

  {

    Serial.printf("%s\n", config.signer.signupError.message.c_str());

  }


  // Assign the callback function for the long running token generation task

  config.token_status_callback = tokenStatusCallback; // see addons/TokenHelper.h


  Firebase.begin(&config, &auth);

  Firebase.reconnectWiFi(true);

}


void loop()

{

  pox.update();


  if (uploadFlag)

  {

    sendToFirebase();

  }


  if (millis() - tsLastReport > REPORTING_PERIOD_MS)

  {

    BPM = pox.getHeartRate();

    SpO2 = pox.getSpO2();

    Serial.print("BPM: ");

    Serial.println(BPM);

   

     


    Serial.print("SpO2: ");

    Serial.print(SpO2);

    Serial.println("%");

    Serial.println("*************");

    Serial.println();

    display.clearDisplay();

    display.setTextColor(WHITE);

    display.setCursor(0, 0);

    display.print(F("BPM:"));

    display.println(BPM);

    display.print(F("SpO2:"));

    display.println(SpO2);

    display.display();


    tsLastReport = millis();

  }

}


  • Flutter

-main.dart

import 'package:flutter/material.dart';

import 'package:firebase_auth/firebase_auth.dart';

import 'package:firebase_core/firebase_core.dart';


import 'screens/splash.dart';

import 'screens/home.dart';

import 'firebase_options.dart';

import 'screens/auth.dart';


void main() async {

 WidgetsFlutterBinding.ensureInitialized();

 await Firebase.initializeApp(

  options: DefaultFirebaseOptions.currentPlatform,

 );

 runApp(const App());

}


class App extends StatelessWidget {

 const App({super.key});


 @override

 Widget build(BuildContext context) {

  return MaterialApp(

   title: 'Oximeter App',

   theme: ThemeData(

    colorScheme: ColorScheme.fromSwatch(

     primarySwatch: Colors.lightGreen,

     brightness: Brightness.dark,

    ),

   ),

   // .copyWith(

   // useMaterial3: true,

   // colorScheme:

   //   ColorScheme.fromSeed(seedColor: Color.fromARGB(95, 39, 59, 62)),

   // );

   home: StreamBuilder(

     stream: FirebaseAuth.instance.authStateChanges(),

     builder: (ctx, snapshot) {

      if (snapshot.connectionState == ConnectionState.waiting) {

       return const SplashScreen();

      }


      if (snapshot.hasData) {

       return const VitalDataScreen();

      }


      return const AuthScreen();

     }),

   debugShowCheckedModeBanner: false,

  );

 }

}

-auth.dart

import 'dart:io';


import '../widgets/user_image_picker.dart';

import 'package:firebase_storage/firebase_storage.dart';

import 'package:flutter/material.dart';

import 'package:firebase_auth/firebase_auth.dart';


final _firebase = FirebaseAuth.instance;


class AuthScreen extends StatefulWidget {

 const AuthScreen({super.key});


 @override

 State<AuthScreen> createState() {

  return _AuthScreenState();

 }

}


class _AuthScreenState extends State<AuthScreen> {

 final _form = GlobalKey<FormState>();


 var _isLogin = true;

 var _enteredEmail = '';

 var _enteredPassword = '';

 File? _selectedImage;

 var _isAuthenticating = false;


 void _submit() async {

  final isValid = _form.currentState!.validate();


  if (!isValid || !_isLogin && _selectedImage == null) {

   // show error message ...

   return;

  }


  _form.currentState!.save();


  try {

   setState(() {

    _isAuthenticating = true;

   });

   if (_isLogin) {

    final userCredentials = await _firebase.signInWithEmailAndPassword(

      email: _enteredEmail, password: _enteredPassword);

   } else {

    final userCredentials = await _firebase.createUserWithEmailAndPassword(

      email: _enteredEmail, password: _enteredPassword);


    final storageRef = FirebaseStorage.instance

      .ref()

      .child('user_images')

      .child('${userCredentials.user!.uid}.jpg');


    await storageRef.putFile(_selectedImage!);

    final imageUrl = await storageRef.getDownloadURL();

    print(imageUrl);

   }

  } on FirebaseAuthException catch (error) {

   if (error.code == 'email-already-in-use') {

    // ...

   }

   ScaffoldMessenger.of(context).clearSnackBars();

   ScaffoldMessenger.of(context).showSnackBar(

    SnackBar(

     content: Text(error.message ?? 'Authentication failed.'),

    ),

   );

  }

 }


 @override

 Widget build(BuildContext context) {

  return Scaffold(

   backgroundColor: Theme.of(context).colorScheme.primary,

   body: Center(

    child: SingleChildScrollView(

     child: Column(

      mainAxisAlignment: MainAxisAlignment.center,

      children: [

       Container(

        margin: const EdgeInsets.only(

         top: 30,

         bottom: 20,

         left: 20,

         right: 20,

        ),

        width: 200,

        child: Image.asset('assets/images/health.png'),

       ),

       Card(

        margin: const EdgeInsets.all(20),

        child: SingleChildScrollView(

         child: Padding(

          padding: const EdgeInsets.all(16),

          child: Form(

           key: _form,

           child: Column(

            mainAxisSize: MainAxisSize.min,

            children: [

             if (!_isLogin)

              UserImagePicker(

               onPickImage: (pickedImage) {

                _selectedImage = pickedImage;

               },

              ),

             TextFormField(

              decoration: const InputDecoration(

                labelText: 'Email Address'),

              keyboardType: TextInputType.emailAddress,

              autocorrect: false,

              textCapitalization: TextCapitalization.none,

              validator: (value) {

               if (value == null ||

                 value.trim().isEmpty ||

                 !value.contains('@')) {

                return 'Please enter a valid email address.';

               }


               return null;

              },

              onSaved: (value) {

               _enteredEmail = value!;

              },

             ),

             TextFormField(

              decoration:

                const InputDecoration(labelText: 'Password'),

              obscureText: true,

              validator: (value) {

               if (value == null || value.trim().length < 6) {

                return 'Password must be at least 6 characters long.';

               }

               return null;

              },

              onSaved: (value) {

               _enteredPassword = value!;

              },

             ),

             const SizedBox(height: 12),

             if (_isAuthenticating)

              const CircularProgressIndicator(),

             if (!_isAuthenticating)

              ElevatedButton(

               onPressed: _submit,

               style: ElevatedButton.styleFrom(

                backgroundColor: Theme.of(context)

                  .colorScheme

                  .primaryContainer,

               ),

               child: Text(_isLogin ? 'Login' : 'Signup'),

              ),

             if (!_isAuthenticating)

              TextButton(

               onPressed: () {

                setState(() {

                 _isLogin = !_isLogin;

                });

               },

               child: Text(_isLogin

                 ? 'Create an account'

                 : 'I already have an account'),

              ),

            ],

           ),

          ),

         ),

        ),

       ),

      ],

     ),

    ),

   ),

  );

 }

}

-home.dart

import 'dart:convert';

import 'package:http/http.dart' as http;

import 'package:firebase_auth/firebase_auth.dart';

import 'package:flutter/material.dart';

import 'dart:async';


class MyApp extends StatelessWidget {

 const MyApp({super.key});


 @override

 Widget build(BuildContext context) {

  return MaterialApp(

   title: 'Oximeter App',

   theme: ThemeData(

    primarySwatch: Colors.blue,

   ),

   home: const VitalDataScreen(),

   debugShowCheckedModeBanner: false,

  );

 }

}


class VitalDataScreen extends StatefulWidget {

 const VitalDataScreen({super.key});


 @override

 _VitalDataScreenState createState() => _VitalDataScreenState();

}


class _VitalDataScreenState extends State<VitalDataScreen> {

 double _bpm = 0;

 double _spo2 = 0;

 Timer? _timer;


 @override

 void initState() {

  super.initState();

  _startFetchingData();

 }


 void _startFetchingData() {

  _timer = Timer.periodic(Duration(seconds: 1), (Timer timer) {

   _fetchData();

  });

 }


 Future<void> _fetchData() async {

  final response = await http.get(Uri.parse(

    'https://lortbims-default-rtdb.asia-southeast1.firebasedatabase.app/data.json'));


  if (response.statusCode == 200) {

   final jsonData = json.decode(response.body);

   setState(() {

    _bpm = double.parse(jsonData['BPM'].toString());

    _spo2 = double.parse(jsonData['SpO2'].toString());

   });

  } else {

   throw Exception('Failed to fetch data');

  }

 }


 @override

 void dispose() {

  _timer?.cancel();

  super.dispose();

 }


 @override

 Widget build(BuildContext context) {

  return Scaffold(

   appBar: AppBar(

    title: const Text('Oximeter App'),

    backgroundColor: Colors.lightGreen,

    actions: [

     IconButton(

      onPressed: () {

       FirebaseAuth.instance.signOut();

      },

      icon: const Icon(

       Icons.exit_to_app,

       color: Colors.white,

      ),

     )

    ],

   ),

   body: Center(

    child: Row(

     mainAxisAlignment: MainAxisAlignment.center,

     children: [

      Container(

       margin: const EdgeInsets.only(

        top: 30,

        bottom: 20,

        left: 20,

        right: 20,

       ),

       width: 100,

       child: Image.asset('assets/images/health.png'),

      ),

      Column(

       mainAxisAlignment: MainAxisAlignment.center,

       children: [

        Text(

         'Heart Rate: $_bpm bpm',

         style: const TextStyle(fontSize: 24),

        ),

        const SizedBox(height: 16),

        Text(

         'SpO2: $_spo2%',

         style: const TextStyle(fontSize: 24),

        ),

       ],

      ),

     ],

    ),

   ),

  );

 }

}

-user_image_picker.dart

import 'dart:io';


import 'package:flutter/material.dart';

import 'package:image_picker/image_picker.dart';


class UserImagePicker extends StatefulWidget {

 const UserImagePicker({

  super.key,

  required this.onPickImage,

 });


 final void Function(File pickedImage) onPickImage;


 @override

 State<UserImagePicker> createState() {

  return _UserImagePickerState();

 }

}


class _UserImagePickerState extends State<UserImagePicker> {

 File? _pickedImageFile;


 void _pickImage() async {

  final pickedImage = await ImagePicker().pickImage(

   source: ImageSource.camera,

   imageQuality: 50,

   maxWidth: 150,

  );


  if (pickedImage == null) {

   return;

  }


  setState(() {

   _pickedImageFile = File(pickedImage.path);

  });


  widget.onPickImage(_pickedImageFile!);

 }


 @override

 Widget build(BuildContext context) {

  return Column(

   children: [

    CircleAvatar(

     radius: 40,

     backgroundColor: Colors.grey,

     foregroundImage:

       _pickedImageFile != null ? FileImage(_pickedImageFile!) : null,

    ),

    TextButton.icon(

     onPressed: _pickImage,

     icon: const Icon(Icons.image),

     label: Text(

      'Add Image',

      style: TextStyle(

       color: Theme.of(context).colorScheme.primary,

      ),

     ),

    )

   ],

  );

 }

}



Hasil Dan Pembahasan

hptriots4.png

Kesimpulan Dan Saran

Kesimpulan

  • memastikan akurasi pengukuran sensor. Mengkalibrasi sensor ke standar referensi yang valid membantu meningkatkan akurasi pengukuran.
  • Sensor MAX30100 adalah sensor detak jantung dan oksigen darah non-invasif.
  • keunggulan dalam hal ukuran yang kecil, konsumsi daya yang rendah, dan kemampuan pengukuran yang akurat.
  • MAX30100 dapat digunakan di banyak aplikasi termasuk monitor jantung portabel, peralatan kebugaran, dan perangkat medis lainnya.


Saran

  1. Lakukan tes tambahan untuk memastikan keakuratan dan keandalan sistem pemantauan detak jantung dan saturasi oksigen. Hal ini dapat dilakukan dengan membandingkan hasil pengukuran alat dengan alat pemantau yang telah teruji atau dengan standar medis yang telah ditetapkan.
  2. Mengoptimalkan desain layar dengan mempertimbangkan kenyamanan, portabilitas, dan ergonomis. Fungsi tambahan juga dapat dikembangkan, seperti pemantauan detak jantung saat istirahat, pemantauan aktivitas fisik, atau integrasi dengan aplikasi seluler untuk pengumpulan data yang lebih komprehensif.
  3. Berpartisipasi dalam pengembangan sistem dan berkolaborasi dengan profesional kesehatan seperti dokter atau perawat. Dengan bantuan para ahli ini, dimungkinkan untuk lebih memvalidasi hasil pengukuran dan memberikan saran klinis yang lebih akurat kepada pengguna.
  4. Bangun aplikasi yang terintegrasi dengan alat pemantauan untuk visualisasi data yang lebih kaya yang lebih mudah dipahami pengguna. Selain itu, analisis data yang lebih mendalam dilakukan untuk mengidentifikasi pola atau tren yang berguna untuk memantau kesehatan pengguna.
  5. Menambahkan casing yang sesuai agar dapat memaksimalkan kinerja sensor
  6. Hindari penggunaan sensor MAX30100 di lingkungan yang cahayanya terlalu terang atau terlalu gelap
  7. Melindungi dari interferensi sinyal eksternal yang dapat memengaruhi pengukuran sensor

Daftar Pustaka


Flutter packages

  • cupertino_icons. (2017, September 18). Dart Packages. https://pub.dev/packages/cupertino_icons
  • firebase_core. (2017, December 19). Dart Packages. https://pub.dev/packages/firebase_core
  • firebase_auth. (2017, May 11). Dart Packages. https://pub.dev/packages/firebase_auth
  • image_picker. (2017, May 11). Dart Packages. https://pub.dev/packages/image_picker
  • firebase_storage. (2017, May 11). Dart Packages. https://pub.dev/packages/firebase_storage
  • http. (2012, November 30). Dart Packages. https://pub.dev/packages/http


Lampiran

FDHD529LJ5Q5Q8K.jpg