#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <ThingSpeak.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 potpin = 34;
int heartValue = 0;
int graphX = 0;
int lastGraphX = 0;
int lastGraphY = 0;
bool pulseReading = false; // Variable to control reading
bool thingSpeakConnected = false; // Flag to indicate ThingSpeak connection status
const int buttonPin1 = 15; // GPIO pin for Button 1 (Start/Stop ECG)
const int buttonPin2 = 13; // GPIO pin for Button 2 (Start/Stop ThingSpeak)
// Wi-Fi and ThingSpeak configuration
const char* ssid = "Wokwi-GUEST"; // Your Wi-Fi SSID
const char* password = ""; // Your Wi-Fi password
const char* thingSpeakApiKey = "T8XYZEEPHBYI5FY4"; // Your ThingSpeak API Key
unsigned long thingSpeakChannelID = 2316140; // Your ThingSpeak Channel ID
WiFiClient client;
unsigned long wifiConnectStartTime = 0;
unsigned long thingSpeakConnectStartTime = 0;
bool wifiConnected = false;
bool wifiConnecting = false;
bool thingSpeakConnecting = false;
bool wifiDotVisible = false;
bool thingSpeakDotVisible = false;
bool uploadToThingSpeak(int value);
void setup() {
Serial.begin(115200);
pinMode(buttonPin1, INPUT_PULLUP); // Configure Button 1 pin as an input with a pull-up resistor
pinMode(buttonPin2, INPUT_PULLUP); // Configure Button 2 pin as an input with a pull-up resistor
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C, OLED_RESET)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;) {
// Add any necessary error handling here.
}
}
display.clearDisplay();
display.display();
// Connect to Wi-Fi in the background
WiFi.begin(ssid, password);
wifiConnectStartTime = millis();
wifiConnecting = true;
}
void loop() {
// Check if Button 1 is pressed to toggle ECG reading
if (digitalRead(buttonPin1) == LOW) {
if (pulseReading) {
pulseReading = false;
display.setCursor(0, 20);
display.print("ECG: Stopped ");
} else {
pulseReading = true;
display.setCursor(0, 20);
display.print("ECG: Reading ");
}
delay(1000); // Long-press delay to avoid repeated toggles
}
// Check WiFi connection status
if (wifiConnecting) {
if (WiFi.status() == WL_CONNECTED) {
wifiConnected = true;
wifiConnecting = false;
wifiConnectStartTime = 0;
} else {
if (millis() - wifiConnectStartTime >= 500) {
wifiConnectStartTime = millis();
wifiDotVisible = !wifiDotVisible;
display.drawPixel(120, 0, wifiDotVisible ? SSD1306_WHITE : SSD1306_BLACK);
}
}
}
// Check if WiFi is connected before attempting ThingSpeak connection
if (wifiConnected && !thingSpeakConnected && !thingSpeakConnecting) {
display.setCursor(0, 10);
display.print("ThingSpeak: Connecting");
display.display();
ThingSpeak.begin(client);
thingSpeakConnecting = true;
thingSpeakConnectStartTime = millis();
}
// Check ThingSpeak connection status
if (thingSpeakConnecting) {
if (millis() - thingSpeakConnectStartTime >= 10000) {
thingSpeakConnectStartTime = millis();
if (uploadToThingSpeak(heartValue)) {
thingSpeakConnected = true;
thingSpeakConnecting = false;
}
}
}
// Handle ECG data and display
if (pulseReading) {
heartValue = analogRead(potpin);
// Update the ECG graph and display as before
// (Omitted for brevity)
}
// Display the BPM (heart rate) on the OLED
display.setCursor(0, 30);
display.print("BPM: "); // Label for BPM
display.print(heartValue);
// Set text size for ECG graph
display.setTextSize(1);
// Update the ECG graph
int graphHeight = map(heartValue, 0, 1023, 0, SCREEN_HEIGHT - 1);
int graphY = SCREEN_HEIGHT - graphHeight;
display.drawLine(lastGraphX, lastGraphY, graphX, graphY, SSD1306_WHITE);
lastGraphX = graphX;
lastGraphY = graphY;
graphX++;
if (graphX >= SCREEN_WIDTH) {
graphX = 0;
lastGraphX = 0;
lastGraphY = 0; // Reset lastGraphY
display.clearDisplay();
}
// Display a pulsing heart icon
display.setCursor(60, 50);
display.print("<3");
// Update the display
display.display();
delay(10); // You can adjust the delay to control the refresh rate
}
bool uploadToThingSpeak(int value) {
return ThingSpeak.writeField(thingSpeakChannelID, 1, value, thingSpeakApiKey);
}