#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_MPU6050.h>
// Standard I2C Pins for ESP32
#define SDA_PIN 21
#define SCL_PIN 22
// Analog Pin Definitions
const int HB100_PIN = 34; // Radar (Chest Motion)
const int THERM_PIN = 32; // Thermistor (Nasal Airflow)
const int ECG_PIN = 35; // AD8232 (Heart Activity)
const int BUZZER_PIN = 13; // Alarm
Adafruit_SSD1306 display(128, 64, &Wire, -1);
Adafruit_MPU6050 mpu;
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
pinMode(BUZZER_PIN, OUTPUT);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED missing");
}
if (!mpu.begin()) {
Serial.println("MPU6050 missing");
}
display.clearDisplay();
display.setTextColor(WHITE);
}
void loop() {
// 1. Read SpO2 (I2C Custom Chip)
Wire.requestFrom(0x57, 1);
int spo2 = Wire.available() ? Wire.read() : 98;
// 2. Read Analog Inputs (Custom Chips)
int hb100 = analogRead(HB100_PIN);
int therm = analogRead(THERM_PIN);
int ecg = analogRead(ECG_PIN);
// 3. Read Motion (MPU6050)
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
float motion = abs(a.acceleration.x) + abs(a.acceleration.y);
// --- 4/5 APNEA LOGIC ---
int alerts = 0;
if (spo2 < 92) alerts++; // Param 1: Low Oxygen
if (hb100 < 500) alerts++; // Param 2: No Chest Motion (Radar)
if (therm < 500) alerts++; // Param 3: No Nasal Airflow (Thermistor)
if (ecg > 3000) alerts++; // Param 4: Cardiac Stress (ECG)
if (motion > 15.0) alerts++; // Param 5: Sleep Fragmentation (Motion)
display.clearDisplay();
display.setCursor(0,0);
if (alerts >= 4) {
// APNEA DETECTED
display.invertDisplay(true);
display.setTextSize(2);
display.println("!! APNEA !!");
display.setTextSize(1);
display.println("\n4/5 Params Abnormal");
display.println("CHECK PATIENT!");
digitalWrite(BUZZER_PIN, HIGH); // Alarm ON
} else {
// NORMAL MONITORING
display.invertDisplay(false);
display.setTextSize(1);
display.println("MONITORING SYSTEM");
display.drawFastHLine(0, 10, 128, WHITE);
display.setCursor(0, 15);
display.print("SpO2: "); display.print(spo2); display.println("%");
display.print("Flow: "); display.println(therm < 500 ? "BLOCK" : "OK");
display.print("Chest:"); display.println(hb100 < 500 ? "STOP" : "OK");
display.print("Heart:"); display.println(ecg > 3000 ? "STRESS" : "Normal");
display.print("Move: "); display.println(motion > 10 ? "HIGH" : "Steady");
digitalWrite(BUZZER_PIN, LOW); // Alarm OFF
}
display.display();
delay(300);
}