// ==========================================================
// HEALTHGUARD AI HEALTHCARE SYSTEM
// FINAL COMPLETE VERSION
// ESP32 + OLED + ECG + ThingSpeak + Telegram
// ==========================================================
#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <math.h>
// ================= WIFI =================
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// ================= THINGSPEAK =================
String apiKey = "GXWQCVCZKNZQ9YDB";
// ================= TELEGRAM =================
String botToken = "8756116302:AAGrg2pjgnuDNO8pEMzT4nLIPTiJHyti9IA";
String chatID = "7053488830";
// ================= OLED =================
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(
SCREEN_WIDTH,
SCREEN_HEIGHT,
&Wire,
-1
);
// ================= PINS =================
#define BUZZER 13
#define LED_GREEN 25
#define LED_YELLOW 26
#define LED_RED 27
// ================= VARIABLES =================
float hr, spo2, sysBP, diaBP, bpm;
// ECG
float ecgX = 0;
int lastY = 32;
int xPos = 0;
// ================= DEMO =================
#define DEMO_DURATION 7000UL
int demoState = 0;
unsigned long demoStateStart = 0;
// ================= TIMING =================
unsigned long lastUpload = 0;
unsigned long lastAlert = 0;
#define UPLOAD_INTERVAL 15000UL
#define ALERT_INTERVAL 5000UL
// ==========================================================
// ECG FUNCTION
// ==========================================================
float ecgFunc(float x) {
return 0.12 * exp(-pow((x - 0.20) / 0.040, 2))
- 0.25 * exp(-pow((x - 0.37) / 0.015, 2))
+ 1.20 * exp(-pow((x - 0.40) / 0.010, 2))
- 0.35 * exp(-pow((x - 0.43) / 0.012, 2))
+ 0.35 * exp(-pow((x - 0.70) / 0.040, 2));
}
// ==========================================================
// DEMO STATES
// ==========================================================
void applyDemoState() {
unsigned long now = millis();
if (now - demoStateStart >= DEMO_DURATION) {
demoState = (demoState + 1) % 3;
demoStateStart = now;
}
// SAFE
if (demoState == 0) {
hr = 82;
spo2 = 98;
sysBP = 118;
diaBP = 78;
bpm = 80;
}
// ARRHYTHMIA
else if (demoState == 1) {
hr = 123;
spo2 = 95;
sysBP = 140;
diaBP = 92;
bpm = 110;
}
// STROKE
else {
hr = 135;
spo2 = 89;
sysBP = 160;
diaBP = 100;
bpm = 130;
}
}
// ==========================================================
// THINGSPEAK
// ==========================================================
void uploadCloud() {
if (WiFi.status() != WL_CONNECTED)
return;
HTTPClient http;
String url =
"http://api.thingspeak.com/update?api_key=" + apiKey +
"&field1=" + String((int)hr) +
"&field2=" + String((int)spo2) +
"&field3=" + String((int)sysBP) +
"&field4=" + String((int)diaBP) +
"&field5=" + String((int)bpm);
http.begin(url);
int code = http.GET();
Serial.print("ThingSpeak HTTP: ");
Serial.println(code);
http.end();
}
// ==========================================================
// TELEGRAM
// ==========================================================
void sendTelegram(String message) {
if (WiFi.status() != WL_CONNECTED)
return;
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
message.replace(" ", "%20");
message.replace("\n", "%0A");
String url =
"https://api.telegram.org/bot" + botToken +
"/sendMessage?chat_id=" + chatID +
"&text=" + message;
http.begin(client, url);
int code = http.GET();
Serial.print("Telegram HTTP: ");
Serial.println(code);
http.end();
}
// ==========================================================
// SETUP
// ==========================================================
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
pinMode(BUZZER, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_YELLOW, OUTPUT);
pinMode(LED_RED, OUTPUT);
// ================= OLED =================
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED Failed");
while (1);
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(10, 20);
display.println("HealthGuard AI");
display.setCursor(10, 35);
display.println("System Ready");
display.display();
// ================= WIFI =================
WiFi.begin(ssid, password);
Serial.print("Connecting WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi Connected");
Serial.println(WiFi.localIP());
sendTelegram("ā
HealthGuard System Started");
delay(2000);
display.clearDisplay();
demoStateStart = millis();
}
// ==========================================================
// LOOP
// ==========================================================
void loop() {
// ================= DEMO =================
applyDemoState();
String statusText = "";
// RESET OUTPUTS
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_RED, LOW);
noTone(BUZZER);
// ================= SAFE =================
if (demoState == 0) {
statusText = "STATUS SAFE";
digitalWrite(LED_GREEN, HIGH);
}
// ================= ARRHYTHMIA =================
else if (demoState == 1) {
statusText = "! ARRHYTHMIA !";
digitalWrite(LED_YELLOW, HIGH);
tone(BUZZER, 1000);
}
// ================= STROKE =================
else {
statusText = "** STROKE ALERT **";
digitalWrite(LED_RED, HIGH);
tone(BUZZER, 2000);
}
unsigned long now = millis();
// ================= THINGSPEAK =================
if (now - lastUpload >= UPLOAD_INTERVAL) {
lastUpload = now;
uploadCloud();
}
// ================= TELEGRAM =================
if (now - lastAlert >= ALERT_INTERVAL) {
lastAlert = now;
// ARRHYTHMIA
if (demoState == 1) {
sendTelegram(
"šØ HEALTH ALERT šØ\n\n"
"ā ļø Arrhythmia Detected\n\n"
"ā¤ļø HR: " + String((int)hr) +
"\nš« SpO2: " + String((int)spo2) +
"\n𩸠BP: " + String((int)sysBP) + "/" + String((int)diaBP) +
"\nš BPM: " + String((int)bpm) +
"\n\nš Patient Location:"
"\nhttps://maps.google.com/?q=11.0168,76.9558"
"\n\nš„ Nearby Hospitals:"
"\n1. KMCH Hospital - 2.4 km"
"\n2. Ganga Hospital - 3.1 km"
"\n3. PSG Hospital - 4.8 km"
"\n\nš Immediate monitoring recommended"
);
}
// STROKE
else if (demoState == 2) {
sendTelegram(
"šØ CRITICAL HEALTH ALERT šØ\n\n"
"š§ Stroke Risk Detected\n\n"
"ā¤ļø HR: " + String((int)hr) +
"\nš« SpO2: " + String((int)spo2) +
"\n𩸠BP: " + String((int)sysBP) + "/" + String((int)diaBP) +
"\nš BPM: " + String((int)bpm) +
"\n\nš Patient Location:"
"\nhttps://maps.google.com/?q=11.0168,76.9558"
"\n\nš„ Nearby Emergency Hospitals:"
"\n1. KMCH Hospital - 2.4 km"
"\n2. Ganga Hospital - 3.1 km"
"\n3. PSG Hospital - 4.8 km"
"\n\nš Emergency medical attention required immediately"
);
}
}
// =====================================================
// OLED UPDATE
// =====================================================
// CLEAR TOP + STATUS ONLY
display.fillRect(0, 0, 128, 16, BLACK);
display.fillRect(0, 54, 128, 10, BLACK);
// ================= TOP INFO =================
display.setTextSize(1);
display.setCursor(0, 0);
display.print("HR:");
display.print((int)hr);
display.setCursor(64, 0);
display.print("SpO2:");
display.print((int)spo2);
display.setCursor(0, 8);
display.print("BP:");
display.print((int)sysBP);
display.print("/");
display.print((int)diaBP);
display.setCursor(64, 8);
display.print("BPM:");
display.print((int)bpm);
// ================= ECG =================
float yVal = ecgFunc(fmod(ecgX, 1.0));
int y = 42 - (int)(yVal * 25);
display.drawLine(xPos, lastY, xPos + 1, y, WHITE);
lastY = y;
xPos++;
if (xPos >= 128) {
xPos = 0;
// CLEAR ONLY ECG AREA
display.fillRect(0, 16, 128, 34, BLACK);
}
ecgX += 0.01;
// ================= STATUS =================
display.fillRect(0, 54, 128, 10, BLACK);
display.setCursor(0, 54);
display.print(statusText);
// SHOW OLED
display.display();
delay(100);
}