safwan092

Untitled

Feb 19th, 2026 (edited)
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.02 KB | None | 0 0
  1. /*
  2. NTC Thermistor for ESP32 - Child Fever Monitor
  3. With WiFi, Telegram Bot alerts (loud/urgent) every X minutes while fever persists
  4.  
  5. Alert behavior: Sends urgent loud Telegram notification every ALERT_INTERVAL_MINUTES
  6. while temperature stays above 38°C
  7. */
  8.  
  9. #include <Thermistor.h>
  10. #include <NTC_Thermistor.h>
  11. #include <WiFi.h>
  12. #include <HTTPClient.h>
  13. #include <UrlEncode.h> // Install "URLEncode" by Masood Farquhar from Library Manager
  14.  
  15. // ============================================================
  16. // CONFIGURE THESE BEFORE UPLOADING
  17. // ============================================================
  18.  
  19. // WiFi credentials
  20. const char* WIFI_SSID = "BS Home1";
  21. const char* WIFI_PASSWORD = "0554418546";
  22.  
  23. // Telegram Bot - get token from @BotFather, Chat ID from @userinfobot
  24. const String BOT_TOKEN = "8214034828:AAFgHIVpbouWFLBrkr4wVHQSZJFZK9y0NB0"; // e.g. "123456789:ABCDefgh..."
  25. const String CHAT_ID = "985890015"; // e.g. "987654321"
  26.  
  27. // How often to re-send the alert while fever persists (in minutes)
  28. #define ALERT_INTERVAL_MINUTES 5
  29.  
  30. // ============================================================
  31. // THERMISTOR CONFIG
  32. // ============================================================
  33. #define SENSOR_PIN D1
  34. #define REFERENCE_RESISTANCE 100000
  35. #define NOMINAL_RESISTANCE 100000
  36. #define NOMINAL_TEMPERATURE 25
  37. #define B_VALUE 3380
  38. #define ESP32_ANALOG_RESOLUTION 4095
  39. #define ESP32_ADC_VREF_MV 3300
  40. #define NUM_SAMPLES 100
  41.  
  42. // ============================================================
  43. // FEVER THRESHOLDS
  44. // ============================================================
  45. #define FEVER_THRESHOLD 33.0 // Alert above this (°C)
  46. #define FEVER_RESET_THRESHOLD 32.5 // Re-arm alert below this (°C)
  47.  
  48. // ============================================================
  49.  
  50. Thermistor* thermistor;
  51.  
  52. unsigned long lastAlertTime = 0; // Timestamp of last alert sent
  53. bool inFeverEpisode = false; // True while child is in fever
  54. unsigned long alertIntervalMs = (unsigned long)ALERT_INTERVAL_MINUTES * 60UL * 1000UL;
  55.  
  56. // -------------------------------------------------------
  57. // WiFi Connection
  58. // -------------------------------------------------------
  59. void connectWiFi() {
  60. Serial.print("Connecting to WiFi: ");
  61. Serial.println(WIFI_SSID);
  62. WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  63.  
  64. int attempts = 0;
  65. while (WiFi.status() != WL_CONNECTED && attempts < 30) {
  66. delay(500);
  67. Serial.print(".");
  68. attempts++;
  69. }
  70.  
  71. if (WiFi.status() == WL_CONNECTED) {
  72. Serial.println("\nWiFi connected! IP: " + WiFi.localIP().toString());
  73. } else {
  74. Serial.println("\nWiFi connection FAILED. Will retry later.");
  75. }
  76. }
  77.  
  78. // -------------------------------------------------------
  79. // Send Urgent Telegram Message
  80. // notification_sound = 1 → loud/default sound
  81. // protect_content = false so user can forward/screenshot
  82. //
  83. // Telegram's "critical" loud alert is achieved by using
  84. // sendMessage with disable_notification=false (default) AND
  85. // sending a second "pinned" copy so it banner-alerts even
  86. // when phone is on silent (via pinChatMessage).
  87. // -------------------------------------------------------
  88. bool sendTelegramUrgentMessage(String message, double tempValue) {
  89. if (WiFi.status() != WL_CONNECTED) {
  90. Serial.println("[Telegram] Not connected to WiFi, skipping.");
  91. return false;
  92. }
  93.  
  94. HTTPClient http;
  95.  
  96. // --- Step 1: Send the message ---
  97. String url = "https://api.telegram.org/bot" + BOT_TOKEN +
  98. "/sendMessage"
  99. "?chat_id=" + CHAT_ID +
  100. "&text=" + urlEncode(message) +
  101. "&parse_mode=HTML"
  102. "&disable_notification=false"; // Ensures sound/vibration
  103.  
  104. http.begin(url);
  105. int httpCode = http.GET();
  106. String response = http.getString();
  107. http.end();
  108.  
  109. if (httpCode != 200) {
  110. Serial.println("[Telegram] Message failed. HTTP: " + String(httpCode));
  111. Serial.println("[Telegram] Response: " + response);
  112. return false;
  113. }
  114.  
  115. Serial.println("[Telegram] Urgent message sent.");
  116.  
  117. // --- Step 2: Extract message_id from response to pin it ---
  118. // Simple parse: find "message_id": in the JSON response
  119. int idIndex = response.indexOf("\"message_id\":");
  120. if (idIndex != -1) {
  121. int idStart = idIndex + 13; // length of "message_id":
  122. int idEnd = response.indexOf(',', idStart);
  123. if (idEnd == -1) idEnd = response.indexOf('}', idStart);
  124. String messageId = response.substring(idStart, idEnd);
  125. messageId.trim();
  126.  
  127. // --- Step 3: Pin the message so it triggers a loud banner ---
  128. String pinUrl = "https://api.telegram.org/bot" + BOT_TOKEN +
  129. "/pinChatMessage"
  130. "?chat_id=" + CHAT_ID +
  131. "&message_id=" + messageId +
  132. "&disable_notification=false"; // Loud pin notification
  133.  
  134. http.begin(pinUrl);
  135. int pinCode = http.GET();
  136. http.end();
  137.  
  138. if (pinCode == 200) {
  139. Serial.println("[Telegram] Message pinned (loud banner triggered).");
  140. } else {
  141. Serial.println("[Telegram] Pin failed. HTTP: " + String(pinCode));
  142. }
  143. }
  144.  
  145. return true;
  146. }
  147.  
  148. // -------------------------------------------------------
  149. // Build and dispatch the fever alert
  150. // -------------------------------------------------------
  151. void sendFeverAlert(double celsius, bool isRepeat) {
  152. unsigned long minutesInFever = inFeverEpisode
  153. ? (millis() - lastAlertTime + alertIntervalMs) / 60000UL
  154. : 0;
  155.  
  156. String repeatNote = isRepeat
  157. ? "⏱️ Fever ongoing for at least <b>" + String(ALERT_INTERVAL_MINUTES) + " more minutes</b>.\n"
  158. : "";
  159.  
  160. String msg = "🚨 <b>FEVER ALERT" + String(isRepeat ? " (ONGOING)" : "") + "!</b>\n\n"
  161. "🌡️ Temperature: <b>" + String(celsius, 1) + " °C</b>\n" +
  162. repeatNote +
  163. "⚠️ Please check on the child <b>immediately!</b>\n\n"
  164. "📍 ESP32 Fever Monitor";
  165.  
  166. sendTelegramUrgentMessage(msg, celsius);
  167. lastAlertTime = millis();
  168. }
  169.  
  170. // -------------------------------------------------------
  171. // Average Thermistor Reading
  172. // -------------------------------------------------------
  173. double readAverageCelsius() {
  174. double sum = 0.0;
  175. for (int i = 0; i < NUM_SAMPLES; i++) {
  176. sum += thermistor->readCelsius();
  177. delay(2);
  178. }
  179. return sum / NUM_SAMPLES;
  180. }
  181.  
  182. // -------------------------------------------------------
  183. // Setup
  184. // -------------------------------------------------------
  185. void setup() {
  186. Serial.begin(115200);
  187. delay(1000);
  188.  
  189. Serial.println("=== Child Fever Monitor ===");
  190. Serial.println("Alert interval: every " + String(ALERT_INTERVAL_MINUTES) + " min while fever > " + String(FEVER_THRESHOLD) + "°C");
  191. Serial.println("---------------------------");
  192.  
  193. thermistor = new NTC_Thermistor_ESP32(
  194. SENSOR_PIN,
  195. REFERENCE_RESISTANCE,
  196. NOMINAL_RESISTANCE,
  197. NOMINAL_TEMPERATURE,
  198. B_VALUE,
  199. ESP32_ADC_VREF_MV,
  200. ESP32_ANALOG_RESOLUTION
  201. );
  202.  
  203. connectWiFi();
  204. }
  205.  
  206. // -------------------------------------------------------
  207. // Main Loop
  208. // -------------------------------------------------------
  209. void loop() {
  210. // Reconnect WiFi if dropped
  211. if (WiFi.status() != WL_CONNECTED) {
  212. Serial.println("WiFi lost, reconnecting...");
  213. connectWiFi();
  214. }
  215.  
  216. // Read temperature
  217. const double celsius = readAverageCelsius();
  218. const double kelvin = celsius + 273.15;
  219. const double fahrenheit = (celsius * 9.0 / 5.0) + 32.0;
  220.  
  221. // Serial output
  222. Serial.print("Temp: ");
  223. Serial.print(celsius, 2);
  224. Serial.print(" °C | ");
  225. Serial.print(kelvin, 2);
  226. Serial.print(" K | ");
  227. Serial.print(fahrenheit, 2);
  228. Serial.print(" °F");
  229.  
  230. // --- Fever Detection Logic ---
  231. if (celsius >= FEVER_THRESHOLD) {
  232. unsigned long now = millis();
  233. bool timeToAlert = (lastAlertTime == 0) || (now - lastAlertTime >= alertIntervalMs);
  234.  
  235. if (timeToAlert) {
  236. Serial.println(" 🚨 FEVER! Sending urgent alert...");
  237. sendFeverAlert(celsius, inFeverEpisode); // isRepeat=true if already in episode
  238. inFeverEpisode = true;
  239. } else {
  240. // Show countdown to next alert
  241. unsigned long secondsLeft = (alertIntervalMs - (now - lastAlertTime)) / 1000UL;
  242. Serial.print(" 🔴 Fever persists. Next alert in: ");
  243. Serial.print(secondsLeft);
  244. Serial.print("s");
  245. }
  246.  
  247. } else if (celsius < FEVER_RESET_THRESHOLD && inFeverEpisode) {
  248. // Fever broke — send recovery notification and reset
  249. Serial.print(" ✅ Fever cleared!");
  250. inFeverEpisode = false;
  251. lastAlertTime = 0;
  252.  
  253. String recoveryMsg = "✅ <b>Fever Cleared</b>\n\n"
  254. "Temperature is now <b>" + String(celsius, 1) + " °C</b>\n"
  255. "Back in the normal range. 😊\n\n"
  256. "📍 ESP32 Fever Monitor";
  257. sendTelegramUrgentMessage(recoveryMsg, celsius);
  258.  
  259. } else {
  260. Serial.print(" ✅ Normal.");
  261. }
  262.  
  263. Serial.println();
  264. delay(500);
  265. }
Advertisement
Add Comment
Please, Sign In to add comment