/*
========================================================
ElderGuard - Google Sheets Data Logger
Stores all data in cloud without email
========================================================
*/
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// ====================== WIFI ======================
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// ================== TELEGRAM ======================
String botToken = "8581638287:AAGq5ElYan-r8ylLaGAxbYdKiMwQRkPQaDg";
String chatID = "2112600021";
// ================== GOOGLE SHEETS ======================
// YOUR DEPLOYED WEB APP URL - ✅ FILLED IN!
String googleSheetsURL = "https://script.google.com/macros/s/AKfycbxLFVyd7q02e-iqggykaIEjePk8d2GglJ_8qjyMSED0uZ3p5kulaldAz-ArJYFv1J3t/exec";
// ==================== SYSTEM CONFIG ======================
String roomNumber = "3";
String deviceID = "ESP32_001";
String location = "Room 3, Building A";
// ==================== OLED ========================
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// ==================== PINS ========================
#define TRIG_PIN 19
#define ECHO_PIN 18
#define GREEN_LED 5
#define RED_LED 17
#define BUZZER 16
// ================= VARIABLES ======================
float distanceCM = 0;
float distanceFeet = 0;
float previousFeet = 0;
bool fallDetected = false;
bool wifiConnected = false;
int fallCount = 0;
unsigned long lastLogTime = 0;
// ==================================================
float getDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
float distance = duration * 0.034 / 2.0;
return distance;
}
// ==================================================
void showMessage(String line1, String line2, String line3 = "", String line4 = "") {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 5);
display.println(line1);
display.setCursor(0, 20);
display.println(line2);
if (line3 != "") {
display.setCursor(0, 35);
display.println(line3);
}
if (line4 != "") {
display.setCursor(0, 50);
display.println(line4);
}
display.display();
}
// ==================================================
String getStatusText(float distance) {
if (distance > 10.0) return "Standing";
else if (distance > 4.0) return "Sitting";
else if (distance > 1.0) return "Low";
else return "FALLEN!";
}
// ==================================================
// Send data to Google Sheets
void logToGoogleSheets(String status, float distance) {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi Disconnected - Cannot log data");
return;
}
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
// Prepare JSON payload
String payload = "{";
payload += "\"room\":\"" + roomNumber + "\",";
payload += "\"distance\":\"" + String(distance, 1) + "\",";
payload += "\"status\":\"" + status + "\",";
payload += "\"fallCount\":\"" + String(fallCount) + "\",";
payload += "\"device\":\"" + deviceID + "\"";
payload += "}";
Serial.println("Logging to Google Sheets...");
Serial.println("URL: " + googleSheetsURL);
Serial.println("Payload: " + payload);
http.begin(client, googleSheetsURL);
http.addHeader("Content-Type", "application/json");
int httpCode = http.POST(payload);
Serial.print("Response Code: ");
Serial.println(httpCode);
if (httpCode > 0) {
String response = http.getString();
Serial.println("Response: " + response);
} else {
Serial.println("Error logging data - Code: " + String(httpCode));
}
http.end();
}
// ==================================================
void sendTelegramMessage(String message) {
if (WiFi.status() != WL_CONNECTED) return;
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
String encodedMessage = message;
encodedMessage.replace(" ", "%20");
encodedMessage.replace("\n", "%0A");
String url = "https://api.telegram.org/bot" + botToken +
"/sendMessage?chat_id=" + chatID +
"&text=" + encodedMessage +
"&parse_mode=Markdown";
http.begin(client, url);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpCode = http.GET();
Serial.print("Telegram Response: ");
Serial.println(httpCode);
http.end();
}
// ==================================================
void connectToWiFi() {
Serial.println();
Serial.print("Connecting to WiFi: ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 30) {
delay(500);
Serial.print(".");
attempts++;
showMessage("Connecting WiFi", "Attempt: " + String(attempts) + "/30", "", "");
}
Serial.println();
if (WiFi.status() == WL_CONNECTED) {
wifiConnected = true;
Serial.println("WiFi Connected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
digitalWrite(GREEN_LED, HIGH);
showMessage("WiFi Connected!", "IP: " + WiFi.localIP().toString(), "Room: " + roomNumber, "Ready!");
delay(2000);
} else {
wifiConnected = false;
Serial.println("WiFi Connection Failed!");
showMessage("WiFi Failed!", "Check Settings", "", "");
}
}
// ==================================================
void handleFallDetection() {
if (previousFeet > 10.0 && distanceFeet <= 1.0 && !fallDetected) {
fallDetected = true;
fallCount++;
Serial.println("!!! FALL DETECTED !!!");
Serial.println("Distance: " + String(distanceFeet, 1) + " ft");
Serial.println("Fall Count: " + String(fallCount));
digitalWrite(RED_LED, HIGH);
tone(BUZZER, 1000);
showMessage("🚨 FALL DETECTED!", "Room: " + roomNumber, "Logging to Cloud...", "");
// Log fall to Google Sheets
logToGoogleSheets("FALLEN!", distanceFeet);
// Send Telegram alert
String msg = "🚨 *FALL DETECTED!*\n\n";
msg += "📍 Room: " + roomNumber + "\n";
msg += "📏 Distance: " + String(distanceFeet, 1) + " ft\n";
msg += "📊 Fall Count: " + String(fallCount) + "\n";
msg += "📤 Data logged to Google Sheets!";
sendTelegramMessage(msg);
delay(5000);
noTone(BUZZER);
digitalWrite(RED_LED, LOW);
}
if (distanceFeet > 4.0 && fallDetected) {
fallDetected = false;
Serial.println("Fall reset - Person stood up");
// Log status change
logToGoogleSheets("Standing", distanceFeet);
String msg = "🟢 *Person Stood Up*\n\n";
msg += "📍 Room: " + roomNumber + "\n";
msg += "📏 Distance: " + String(distanceFeet, 1) + " ft\n";
msg += "📊 Total Falls: " + String(fallCount);
sendTelegramMessage(msg);
}
}
// ==================================================
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println();
Serial.println("=== ElderGuard Cloud Logger ===");
Serial.println("Room: " + roomNumber);
Serial.println("Device: " + deviceID);
Serial.println("Google Sheets URL: " + googleSheetsURL);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(BUZZER, OUTPUT);
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, LOW);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED Failed");
while (1);
}
display.setRotation(2);
showMessage("ElderGuard v3.0", "Room: " + roomNumber, "Cloud Logger", "");
delay(1000);
connectToWiFi();
if (wifiConnected) {
String msg = "*🏥 ELDERGUARD CLOUD LOGGER ONLINE*\n\n";
msg += "✅ Device: " + deviceID + "\n";
msg += "📍 Room: " + roomNumber + "\n";
msg += "📊 Logging to Google Sheets\n";
msg += "🟢 System Ready!";
sendTelegramMessage(msg);
// Log initial status
logToGoogleSheets("System Started", 0);
}
}
// ==================================================
void loop() {
if (WiFi.status() != WL_CONNECTED) {
wifiConnected = false;
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, HIGH);
WiFi.reconnect();
delay(1000);
if (WiFi.status() == WL_CONNECTED) {
wifiConnected = true;
digitalWrite(GREEN_LED, HIGH);
digitalWrite(RED_LED, LOW);
}
}
previousFeet = distanceFeet;
distanceCM = getDistance();
distanceFeet = distanceCM / 30.48;
if (distanceFeet > 20.0 || distanceFeet < 0.1) {
distanceFeet = previousFeet;
}
Serial.print("Distance: ");
Serial.print(distanceFeet, 1);
Serial.println(" ft");
String status = getStatusText(distanceFeet);
showMessage("📊 Cloud Logger",
"Room: " + roomNumber,
"Dist: " + String(distanceFeet, 1) + " ft",
"Status: " + status + " | Falls: " + String(fallCount));
// Log data every 30 seconds
if (millis() - lastLogTime > 30000) {
lastLogTime = millis();
if (!fallDetected) {
logToGoogleSheets(status, distanceFeet);
}
}
handleFallDetection();
delay(500);
}