// Sertakan Library
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DallasTemperature.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 SENSOR_PIN A4 // pin sensor DS18B20
#define BUZZER_PIN 11 // pin buzzer
//#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);
OneWire oneWire(SENSOR_PIN); // setup a oneWire
DallasTemperature tempSensor(&oneWire); // pass oneWire
// 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.
unsigned long previousMillis = 0;
String tempString,tempString1;
float batas = 35; // batas suhu biar alarm
float tempCelsius;
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("M.edwar putra p");
display.setTextColor(BLACK, WHITE); // teks 'terbalik'
display.setCursor(40,37);
display.println("Klmp 3");
display.display();
delay(5000);
// 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");
Serial.begin(9600);
pinMode(BUZZER_PIN,OUTPUT);
digitalWrite(BUZZER_PIN,LOW);
// initialize display display with address 0x3C for 128x64
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (true);
}
delay(2000); // wait for initializing
display.clearDisplay(); // clear display
display.setTextSize(1); // text size
display.setTextColor(WHITE); // text color
displayDisplayCenter("M.edwar putra pratama", 4);
displayDisplayCenter("22091387005",56);
display.setTextSize(2);
display.setCursor(0, 32); // position to display
tempSensor.begin(); // initialize the sensor
tempString.reserve(10); // to avoid fragmenting memory when using String
}
void loop() {
tempSensor.requestTemperatures(); // send the command to get temperatures
tempCelsius = tempSensor.getTempCByIndex(0); // read temperature in Celsius
tempString = String(tempCelsius, 2); // two decimal places
tempString += (char)247;
tempString += "C";
//biar ketumpuk hitam dulu jika suhu nya berubah
if(tempString != tempString1)
{
display.setTextColor(BLACK);
displayDisplayCenter(tempString1,28);
}
tempString1= tempString;
Serial.println(tempString); // print the temperature in Celsius to Serial Monitor
//lanjut tulis warna putih
display.setTextColor(WHITE);
displayDisplayCenter(tempString,28);
if( tempCelsius >= batas) //cek alarm vs buzzer
{
digitalWrite(BUZZER_PIN,HIGH);
delay(200);
digitalWrite(BUZZER_PIN,LOW);
delay(50);
}
else digitalWrite(BUZZER_PIN,LOW);
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);
}
}
// 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 displayDisplayCenter(String text, int posisi) {
int16_t x1;
int16_t y1;
uint16_t width;
uint16_t height;
display.getTextBounds(text, 0, 0, &x1, &y1, &width, &height);
display.setCursor((SCREEN_WIDTH - width) / 2, posisi);
display.println(text); // text to display
display.display();
}