#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const int ecgPin = 34; // Potentiometer for ECG
const int buttonPin = 25; // Button for X-ray result
#define MAX_SAMPLES 128
int ecgBuffer[MAX_SAMPLES];
int bufferIndex = 0;
// ECG waveform parameters
float heartRateBase = 60.0;
const float pWave = 0.15, qrsWave = 0.7, tWave = 0.25;
const float pTime = 0.08, qrsTime = 0.04, tTime = 0.15;
void setup() {
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP); // Button with internal pull-up
Wire.begin(21, 22);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 failed"));
for (;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("ECG & X-Ray Kiosk");
display.display();
delay(2000);
for (int i = 0; i < MAX_SAMPLES; i++) {
ecgBuffer[i] = SCREEN_HEIGHT / 2;
}
}
float generateECGWaveform(float t, float period) {
float phase = fmod(t, period) / period;
float ecg = 0.0;
if (phase < 0.08) {
ecg += pWave * sin(2 * PI * phase / pTime);
}
else if (phase < 0.12) {
ecg += qrsWave * (sin(2 * PI * (phase - 0.08) / qrsTime) * 1.5 - 0.2);
}
else if (phase < 0.27) {
ecg += tWave * sin(2 * PI * (phase - 0.12) / tTime);
}
return constrain(ecg * 25 + SCREEN_HEIGHT / 2, 10, 50);
}
void loop() {
int potValue = analogRead(ecgPin);
float heartRate = map(potValue, 0, 4095, 60, 120);
float period = 1000.0 / (heartRate / 60.0);
float t = millis() % (unsigned long)period;
int ecgValue = (int)generateECGWaveform(t, period);
ecgBuffer[bufferIndex] = ecgValue;
static unsigned long lastPeak = 0;
static int peakCount = 0;
static unsigned long lastCheck = 0;
int calculatedHeartRate = heartRate;
if (ecgValue > SCREEN_HEIGHT / 2 + 15 && millis() - lastPeak > 150) {
peakCount++;
lastPeak = millis();
}
if (millis() - lastCheck > 60000) {
calculatedHeartRate = peakCount;
peakCount = 0;
lastCheck = millis();
}
String ecgStatus = (calculatedHeartRate > 100) ? "Abnormal" : "Normal";
static int xrayResult = 1; // Default: Normal
if (digitalRead(buttonPin) == LOW) { // Button pressed
xrayResult = !xrayResult; // Toggle
delay(200); // Debounce
}
String xrayStatus = (xrayResult == 1) ? "Normal" : "Pneumonia Detected";
display.clearDisplay();
for (int x = 0; x < SCREEN_WIDTH; x += 25) {
display.drawLine(x, 0, x, 48, SSD1306_WHITE);
}
for (int y = 0; y <= 48; y += 10) {
display.drawLine(0, y, SCREEN_WIDTH, y, SSD1306_WHITE);
}
for (int i = 0; i < MAX_SAMPLES - 1; i++) {
int x0 = i;
int x1 = i + 1;
int y0 = ecgBuffer[(bufferIndex + i) % MAX_SAMPLES];
int y1 = ecgBuffer[(bufferIndex + i + 1) % MAX_SAMPLES];
display.drawLine(x0, y0, x1, y1, SSD1306_WHITE);
}
display.setCursor(0, 50);
display.print("HR:");
display.print(calculatedHeartRate);
display.print("bpm ");
display.print(ecgStatus);
display.setCursor(0, 58);
display.print("X-Ray:");
display.println(xrayStatus);
display.display();
Serial.print("ECG Value: ");
Serial.print(potValue);
Serial.print(", Voltage: ");
Serial.print(potValue * (3.3 / 4095.0));
Serial.print("V, Heart Rate: ");
Serial.print(calculatedHeartRate);
Serial.print(" bpm, ECG Status: ");
Serial.print(ecgStatus);
Serial.print(", X-Ray Status: ");
Serial.println(xrayStatus);
bufferIndex = (bufferIndex + 1) % MAX_SAMPLES;
delay(20);
}