#include <WiFi.h>
#include "RTClib.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
// WiFi
const char* SSID = "Wokwi-GUEST";
const char* password = "";
// OpenAI API
const char* openaiApiKey = "b453666eb3d04c1fa7c608375d88f7fc"; // свій ключ
// RTC, Sensors
RTC_DS1307 rtc;
const int POT_PIN = 35; // Потенціометр → пульс
const int NTC_PIN = 32; // Аналоговий датчик температури
// Дані
String dataValue = "Loading...";
String recommendation = "No recommendation yet";
float lastTemp = 25.0;
String history[10]; // пам’ять останніх станів
int historyIndex = 0;
unsigned long lastRequestTime = 0; // для таймера GPT
// GPT запит
void request_gpt(String prompt) {
DynamicJsonDocument jsonDocument(4096);
jsonDocument["model"] = "gpt-3.5-turbo";
JsonArray messages = jsonDocument.createNestedArray("messages");
JsonObject sys = messages.createNestedObject();
sys["role"] = "system";
sys["content"] = "You are an AI system that analyzes health data (temperature, heart rate). "
"You remember recent values. If there are sudden unrealistic jumps (e.g. -1C to 100C instantly), "
"treat them as anomalies and ignore them in your advice.";
// історія в prompt'і
String historyPrompt = "Recent data history:\n";
for (int i = 0; i < 10; i++) {
if (history[i] != "") historyPrompt += history[i] + "\n";
}
JsonObject usr = messages.createNestedObject();
usr["role"] = "user";
usr["content"] = historyPrompt + "\nCurrent data:\n" + prompt;
HTTPClient http;
String apiUrl = "https://artificialintelligence.openai.azure.com/openai/deployments/test/chat/completions?api-version=2023-05-15";
http.begin(apiUrl);
http.addHeader("Content-Type", "application/json");
http.addHeader("api-key", openaiApiKey);
String body;
serializeJson(jsonDocument, body);
int httpCode = http.POST(body);
if (httpCode == 200) {
String response = http.getString();
DynamicJsonDocument resDoc(8192);
deserializeJson(resDoc, response);
recommendation = resDoc["choices"][0]["message"]["content"].as<String>();
Serial.println("AI Recommendation: " + recommendation);
} else {
recommendation = "Failed: " + String(httpCode);
Serial.println(recommendation);
}
http.end();
}
// Temperature Sensor
float getTemperature() {
const float BETA = 3950;
int analogValue = analogRead(NTC_PIN);
float celsius = 1 / (log(1 / (4095. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
return celsius;
}
//SETUP
void setup() {
Serial.begin(115200);
pinMode(NTC_PIN, INPUT);
// RTC
Wire.begin(21, 22);
if (!rtc.begin()) Serial.println("Couldn't find RTC");
// WiFi
WiFi.begin(SSID, password);
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.println("\nConnected, IP: " + WiFi.localIP().toString());
}
// LOOP
void loop() {
// RTC
DateTime now = rtc.now();
String Time = String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second());
// Temperature with anomaly check
float temp = getTemperature();
bool anomaly = abs(temp - lastTemp) > 20.0; // якщо різниця >20C → аномалія
if (!anomaly) lastTemp = temp;
String Temp = anomaly ? "ANOMALY!" : String(temp, 1) + " C";
// Potentiometer → Heart Rate (BPM)
int potValue = analogRead(POT_PIN);
int bpm = map(potValue, 0, 4095, 60, 180); // 60–180 bpm
String HeartRate = String(bpm) + " bpm";
// Формуємо дані
dataValue = "Time: " + Time + "\n" +
"Heart Rate: " + HeartRate + "\n" +
"Temperature: " + Temp + "\n";
// Зберігаємо в історію
history[historyIndex] = dataValue;
historyIndex = (historyIndex + 1) % 10;
// Вивід у Serial
Serial.println("---- Current Data ----");
Serial.println(dataValue);
// GPT-запит раз на 30 секунд
if (millis() - lastRequestTime > 30000) {
request_gpt(dataValue);
lastRequestTime = millis();
}
delay(1000);
}