// Sertakan Library
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Ukuran layar OLED dalam piksel
#define SCREEN_WIDTH 128 // Lebar layar OLED, dalam piksel
#define SCREEN_HEIGHT 64 // Tinggi layar OLED, dalam piksel
//#define OLED_DC 8
//#define OLED_CS 10
//#define OLED_RESET 9
//Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
//&SPI, OLED_DC, OLED_RESET, OLED_CS);
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Deklarasi Variabel
unsigned long previousMillisGetHR = 0; // Simpan terakhir kali Millis (untuk mendapatkan Heartbeat) diperbarui.
unsigned long previousMillisResultHR = 0; // Simpan terakhir kali Millis (untuk mendapatkan BPM) diperbarui.
const long intervalGetHR = 20; // Interval pembacaan detak jantung (Detak Jantung) = 10ms.
const long intervalResultHR = 10000; // Interval pembacaan hasil perhitungan Heart Rate adalah 10 detik.
int PulseSensorSignal; // Variabel untuk menampung nilai sinyal dari sensor
const int PulseSensorHRWire = 0; // PulseSensor terhubung ke ANALOG PIN 0 (A0 / ADC 0).
const int LED_A1 = A1; // LED untuk mendeteksi kapan jantung berdetak. LED dihubungkan ke PIN A1 pada Arduino UNO.
int UpperThreshold = 550; // Tentukan Sinyal mana yang "dihitung sebagai ketukan", dan mana yang diabaikan.
int LowerThreshold = 500;
int cntHB = 0; // Variabel untuk menghitung jumlah detak jantung.
boolean ThresholdStat = true; // Variabel pemicu dalam menghitung detak jantung.
int BPMval = 0; // Variabel untuk menampung hasil perhitungan detak jantung.
int x=0; // Nilai grafik x sumbu variabel untuk ditampilkan pada OLED
int y=0; // Nilai grafik sumbu variabel y untuk ditampilkan pada OLED
int lastx=0; // Nilai variabel sumbu x terakhir pada grafik yang ditampilkan pada OLED
int lasty=0; // Nilai variabel sumbu y terakhir pada grafik yang ditampilkan pada OLED
// 'Ikon_Hati', 16x16 piksel
const unsigned char Heart_Icon [] PROGMEM = {
0x00, 0x00, 0x18, 0x30, 0x3c, 0x78, 0x7e, 0xfc, 0xff, 0xfe, 0xff, 0xfe, 0xee, 0xee, 0xd5, 0x56,
0x7b, 0xbc, 0x3f, 0xf8, 0x1f, 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00
};
// Fungsi Setup
void setup() {
pinMode(LED_A1,OUTPUT); // Tetapkan PIN LED_3 sebagai Keluaran.
Serial.begin(9600); // Mengatur Komunikasi Serial dengan kecepatan tertentu.
// SSD1306_SWITCHCAPVCC = menghasilkan tegangan tampilan dari 3.3V secara internal
// Alamat 0x3C untuk 128x32 dan Alamat 0x3D untuk 128x64.
// Tetapi pada modul 128x64 saya, alamat 0x3D tidak berfungsi. Yang berfungsi adalah alamat 0x3C.
// Jadi silakan coba alamat mana yang berfungsi pada modul Anda.
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); //--> Jangan lanjutkan, ulangi selamanya
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setCursor(22,20);
display.setTextSize(1);
display.println("1022111053");
display.setTextColor(BLACK, WHITE); // teks 'terbalik'
display.setCursor(40,37);
display.println("Mfrp");
display.display();
delay(1000);
display.clearDisplay();
// Displays Loading..
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 22); //--> (x position, y position)
display.print(" Loading...");
display.display();
delay(3000);
// Displays the initial display of BPM value
display.clearDisplay(); //--> for Clearing the display
display.drawBitmap(0, 47, Heart_Icon, 16, 16, WHITE); //--> display.drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)
display.drawLine(0, 43, 127, 43, WHITE); //--> drawLine(x1, y1, x2, y2, color)
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(20, 48); //--> (x position, y position)
display.print(": 0 BPM");
display.display();
Serial.println();
Serial.println("Silakan tunggu 3 detik untuk mendapatkan Nilai BPM");
}
void loop() {
GetHeartRate(); // Memanggil subrutin GetHeartRate()
}
void GetHeartRate() {
// Proses membaca detak jantung.
unsigned long currentMillisGetHR = millis();
if (currentMillisGetHR - previousMillisGetHR >= intervalGetHR) {
previousMillisGetHR = currentMillisGetHR;
PulseSensorSignal = analogRead(PulseSensorHRWire);
if (PulseSensorSignal > UpperThreshold && ThresholdStat == true) {
cntHB++;
ThresholdStat = false;
digitalWrite(LED_A1, HIGH);
}
if (PulseSensorSignal < LowerThreshold) {
ThresholdStat = true;
digitalWrite(LED_A1, LOW);
}
DrawGraph(); // Memanggil subrutin DrawGraph()
}
// Proses untuk mendapatkan nilai BPM.
unsigned long currentMillisResultHR = millis();
if (currentMillisResultHR - previousMillisResultHR >= intervalResultHR) {
previousMillisResultHR = currentMillisResultHR;
BPMval = cntHB * 6; // Denyut jantung yang diambil adalah selama 3 detik. Jadi untuk mendapatkan nilai BPM, total detak jantung dalam 3 detik x 6.
Serial.print("BPM : ");
Serial.println(BPMval);
display.fillRect(20, 48, 108, 18, BLACK);
display.drawBitmap(0, 47, Heart_Icon, 16, 16, WHITE);
display.drawLine(0, 43, 127, 43, WHITE);
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(20, 48);
display.print(": ");
display.print(BPMval);
display.print(" BPM");
display.display();
cntHB = 0;
}
}
void DrawGraph() {
// Syarat untuk mereset tampilan grafis jika memenuhi lebar layar OLED
if (x > 127) {
display.fillRect(0, 0, 128, 42, BLACK);
x = 0;
lastx = 0;
}
// Memproses data sinyal untuk ditampilkan pada OLED dalam bentuk grafik
int ySignal = PulseSensorSignal;
if (ySignal > 850) ySignal = 850;
if (ySignal < 350) ySignal = 350;
int ySignalMap = map(ySignal, 350, 850, 0, 40);
y = 40 - ySignalMap;
// Menampilkan grafik detak jantung
display.writeLine(lastx, lasty, x, y, WHITE);
display.display();
lastx = x;
lasty = y;
x++;
}