#include <Wire.h>
#include "MAX30105.h"
#include "heartRate.h"
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
// TFT Pins
#define TFT_CS 10
#define TFT_RST 8
#define TFT_DC 9
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// MAX30102
MAX30105 particleSensor;
// Buzzer
#define BUZZER 3
long lastBeat = 0;
float beatsPerMinute;
int beatAvg = 0;
int spo2 = 98;
void drawHeart()
{
tft.fillCircle(30, 35, 12, ST77XX_RED);
tft.fillCircle(50, 35, 12, ST77XX_RED);
tft.fillTriangle(18, 40, 62, 40, 40, 70, ST77XX_RED);
}
void drawBloodDrop()
{
tft.fillCircle(40, 105, 12, ST77XX_BLUE);
tft.fillTriangle(28, 105, 52, 105, 40, 75, ST77XX_BLUE);
}
void setup()
{
Serial.begin(115200);
pinMode(BUZZER, OUTPUT);
// TFT Start
tft.initR(INITR_BLACKTAB);
tft.setRotation(1);
tft.fillScreen(ST77XX_BLACK);
// Title
tft.setTextColor(ST77XX_GREEN);
tft.setTextSize(1);
tft.setCursor(15, 5);
tft.print("HEART & SPO2");
// MAX30102 Start
if (!particleSensor.begin(Wire, I2C_SPEED_STANDARD))
{
tft.fillScreen(ST77XX_BLACK);
tft.setTextColor(ST77XX_RED);
tft.setCursor(10, 60);
tft.print("MAX30102 ERROR");
while (1);
}
particleSensor.setup();
particleSensor.setPulseAmplitudeRed(0x0A);
particleSensor.setPulseAmplitudeGreen(0);
delay(1000);
}
void loop()
{
long irValue = particleSensor.getIR();
// Heart Beat Detection
if (checkForBeat(irValue))
{
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
if (beatsPerMinute > 20 && beatsPerMinute < 255)
{
beatAvg = (int)beatsPerMinute;
// Buzzer Beep
digitalWrite(BUZZER, HIGH);
delay(40);
digitalWrite(BUZZER, LOW);
}
}
// Demo SpO2
spo2 = 98 + random(-1, 2);
// Screen Clear
tft.fillRect(0, 15, 160, 128, ST77XX_BLACK);
// Draw Heart
drawHeart();
// Heart Rate Text
tft.setTextColor(ST77XX_WHITE);
tft.setTextSize(2);
tft.setCursor(80, 25);
tft.print("HR");
tft.setCursor(80, 50);
tft.setTextColor(ST77XX_GREEN);
tft.print(beatAvg);
// BPM
tft.setTextSize(1);
tft.setCursor(130, 58);
tft.setTextColor(ST77XX_WHITE);
tft.print("BPM");
// Divider Line
tft.drawLine(0, 75, 160, 75, ST77XX_WHITE);
// Blood Drop
drawBloodDrop();
// SPO2 Text
tft.setTextSize(2);
tft.setTextColor(ST77XX_WHITE);
tft.setCursor(80, 90);
tft.print("SpO2");
tft.setCursor(80, 112);
tft.setTextColor(ST77XX_CYAN);
tft.print(spo2);
tft.print("%");
// Finger Detect
if (irValue < 50000)
{
tft.fillRect(0, 0, 160, 15, ST77XX_BLACK);
tft.setCursor(20, 5);
tft.setTextColor(ST77XX_YELLOW);
tft.setTextSize(1);
tft.print("PLACE FINGER");
}
else
{
tft.fillRect(0, 0, 160, 15, ST77XX_BLACK);
tft.setCursor(15, 5);
tft.setTextColor(ST77XX_GREEN);
tft.print("HEART & SPO2");
}
delay(100);
}