Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- NTC Thermistor for ESP32 - Child Fever Monitor
- With WiFi, Telegram Bot alerts (loud/urgent) every X minutes while fever persists
- Alert behavior: Sends urgent loud Telegram notification every ALERT_INTERVAL_MINUTES
- while temperature stays above 38°C
- */
- #include <Thermistor.h>
- #include <NTC_Thermistor.h>
- #include <WiFi.h>
- #include <HTTPClient.h>
- #include <UrlEncode.h> // Install "URLEncode" by Masood Farquhar from Library Manager
- // ============================================================
- // CONFIGURE THESE BEFORE UPLOADING
- // ============================================================
- // WiFi credentials
- const char* WIFI_SSID = "BS Home1";
- const char* WIFI_PASSWORD = "0554418546";
- // Telegram Bot - get token from @BotFather, Chat ID from @userinfobot
- const String BOT_TOKEN = "8214034828:AAFgHIVpbouWFLBrkr4wVHQSZJFZK9y0NB0"; // e.g. "123456789:ABCDefgh..."
- const String CHAT_ID = "985890015"; // e.g. "987654321"
- // How often to re-send the alert while fever persists (in minutes)
- #define ALERT_INTERVAL_MINUTES 5
- // ============================================================
- // THERMISTOR CONFIG
- // ============================================================
- #define SENSOR_PIN D1
- #define REFERENCE_RESISTANCE 100000
- #define NOMINAL_RESISTANCE 100000
- #define NOMINAL_TEMPERATURE 25
- #define B_VALUE 3380
- #define ESP32_ANALOG_RESOLUTION 4095
- #define ESP32_ADC_VREF_MV 3300
- #define NUM_SAMPLES 100
- // ============================================================
- // FEVER THRESHOLDS
- // ============================================================
- #define FEVER_THRESHOLD 33.0 // Alert above this (°C)
- #define FEVER_RESET_THRESHOLD 32.5 // Re-arm alert below this (°C)
- // ============================================================
- Thermistor* thermistor;
- unsigned long lastAlertTime = 0; // Timestamp of last alert sent
- bool inFeverEpisode = false; // True while child is in fever
- unsigned long alertIntervalMs = (unsigned long)ALERT_INTERVAL_MINUTES * 60UL * 1000UL;
- // -------------------------------------------------------
- // WiFi Connection
- // -------------------------------------------------------
- void connectWiFi() {
- Serial.print("Connecting to WiFi: ");
- Serial.println(WIFI_SSID);
- WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
- int attempts = 0;
- while (WiFi.status() != WL_CONNECTED && attempts < 30) {
- delay(500);
- Serial.print(".");
- attempts++;
- }
- if (WiFi.status() == WL_CONNECTED) {
- Serial.println("\nWiFi connected! IP: " + WiFi.localIP().toString());
- } else {
- Serial.println("\nWiFi connection FAILED. Will retry later.");
- }
- }
- // -------------------------------------------------------
- // Send Urgent Telegram Message
- // notification_sound = 1 → loud/default sound
- // protect_content = false so user can forward/screenshot
- //
- // Telegram's "critical" loud alert is achieved by using
- // sendMessage with disable_notification=false (default) AND
- // sending a second "pinned" copy so it banner-alerts even
- // when phone is on silent (via pinChatMessage).
- // -------------------------------------------------------
- bool sendTelegramUrgentMessage(String message, double tempValue) {
- if (WiFi.status() != WL_CONNECTED) {
- Serial.println("[Telegram] Not connected to WiFi, skipping.");
- return false;
- }
- HTTPClient http;
- // --- Step 1: Send the message ---
- String url = "https://api.telegram.org/bot" + BOT_TOKEN +
- "/sendMessage"
- "?chat_id=" + CHAT_ID +
- "&text=" + urlEncode(message) +
- "&parse_mode=HTML"
- "&disable_notification=false"; // Ensures sound/vibration
- http.begin(url);
- int httpCode = http.GET();
- String response = http.getString();
- http.end();
- if (httpCode != 200) {
- Serial.println("[Telegram] Message failed. HTTP: " + String(httpCode));
- Serial.println("[Telegram] Response: " + response);
- return false;
- }
- Serial.println("[Telegram] Urgent message sent.");
- // --- Step 2: Extract message_id from response to pin it ---
- // Simple parse: find "message_id": in the JSON response
- int idIndex = response.indexOf("\"message_id\":");
- if (idIndex != -1) {
- int idStart = idIndex + 13; // length of "message_id":
- int idEnd = response.indexOf(',', idStart);
- if (idEnd == -1) idEnd = response.indexOf('}', idStart);
- String messageId = response.substring(idStart, idEnd);
- messageId.trim();
- // --- Step 3: Pin the message so it triggers a loud banner ---
- String pinUrl = "https://api.telegram.org/bot" + BOT_TOKEN +
- "/pinChatMessage"
- "?chat_id=" + CHAT_ID +
- "&message_id=" + messageId +
- "&disable_notification=false"; // Loud pin notification
- http.begin(pinUrl);
- int pinCode = http.GET();
- http.end();
- if (pinCode == 200) {
- Serial.println("[Telegram] Message pinned (loud banner triggered).");
- } else {
- Serial.println("[Telegram] Pin failed. HTTP: " + String(pinCode));
- }
- }
- return true;
- }
- // -------------------------------------------------------
- // Build and dispatch the fever alert
- // -------------------------------------------------------
- void sendFeverAlert(double celsius, bool isRepeat) {
- unsigned long minutesInFever = inFeverEpisode
- ? (millis() - lastAlertTime + alertIntervalMs) / 60000UL
- : 0;
- String repeatNote = isRepeat
- ? "⏱️ Fever ongoing for at least <b>" + String(ALERT_INTERVAL_MINUTES) + " more minutes</b>.\n"
- : "";
- String msg = "🚨 <b>FEVER ALERT" + String(isRepeat ? " (ONGOING)" : "") + "!</b>\n\n"
- "🌡️ Temperature: <b>" + String(celsius, 1) + " °C</b>\n" +
- repeatNote +
- "⚠️ Please check on the child <b>immediately!</b>\n\n"
- "📍 ESP32 Fever Monitor";
- sendTelegramUrgentMessage(msg, celsius);
- lastAlertTime = millis();
- }
- // -------------------------------------------------------
- // Average Thermistor Reading
- // -------------------------------------------------------
- double readAverageCelsius() {
- double sum = 0.0;
- for (int i = 0; i < NUM_SAMPLES; i++) {
- sum += thermistor->readCelsius();
- delay(2);
- }
- return sum / NUM_SAMPLES;
- }
- // -------------------------------------------------------
- // Setup
- // -------------------------------------------------------
- void setup() {
- Serial.begin(115200);
- delay(1000);
- Serial.println("=== Child Fever Monitor ===");
- Serial.println("Alert interval: every " + String(ALERT_INTERVAL_MINUTES) + " min while fever > " + String(FEVER_THRESHOLD) + "°C");
- Serial.println("---------------------------");
- thermistor = new NTC_Thermistor_ESP32(
- SENSOR_PIN,
- REFERENCE_RESISTANCE,
- NOMINAL_RESISTANCE,
- NOMINAL_TEMPERATURE,
- B_VALUE,
- ESP32_ADC_VREF_MV,
- ESP32_ANALOG_RESOLUTION
- );
- connectWiFi();
- }
- // -------------------------------------------------------
- // Main Loop
- // -------------------------------------------------------
- void loop() {
- // Reconnect WiFi if dropped
- if (WiFi.status() != WL_CONNECTED) {
- Serial.println("WiFi lost, reconnecting...");
- connectWiFi();
- }
- // Read temperature
- const double celsius = readAverageCelsius();
- const double kelvin = celsius + 273.15;
- const double fahrenheit = (celsius * 9.0 / 5.0) + 32.0;
- // Serial output
- Serial.print("Temp: ");
- Serial.print(celsius, 2);
- Serial.print(" °C | ");
- Serial.print(kelvin, 2);
- Serial.print(" K | ");
- Serial.print(fahrenheit, 2);
- Serial.print(" °F");
- // --- Fever Detection Logic ---
- if (celsius >= FEVER_THRESHOLD) {
- unsigned long now = millis();
- bool timeToAlert = (lastAlertTime == 0) || (now - lastAlertTime >= alertIntervalMs);
- if (timeToAlert) {
- Serial.println(" 🚨 FEVER! Sending urgent alert...");
- sendFeverAlert(celsius, inFeverEpisode); // isRepeat=true if already in episode
- inFeverEpisode = true;
- } else {
- // Show countdown to next alert
- unsigned long secondsLeft = (alertIntervalMs - (now - lastAlertTime)) / 1000UL;
- Serial.print(" 🔴 Fever persists. Next alert in: ");
- Serial.print(secondsLeft);
- Serial.print("s");
- }
- } else if (celsius < FEVER_RESET_THRESHOLD && inFeverEpisode) {
- // Fever broke — send recovery notification and reset
- Serial.print(" ✅ Fever cleared!");
- inFeverEpisode = false;
- lastAlertTime = 0;
- String recoveryMsg = "✅ <b>Fever Cleared</b>\n\n"
- "Temperature is now <b>" + String(celsius, 1) + " °C</b>\n"
- "Back in the normal range. 😊\n\n"
- "📍 ESP32 Fever Monitor";
- sendTelegramUrgentMessage(recoveryMsg, celsius);
- } else {
- Serial.print(" ✅ Normal.");
- }
- Serial.println();
- delay(500);
- }
Advertisement
Add Comment
Please, Sign In to add comment