#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
#include "DHTesp.h"
#include "RTClib.h"
// ---------------- Wi-Fi ----------------
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASS = "";
const char* GPT_KEY = "b453666eb3d04c1fa7c608375d88f7fc";
// ---------------- Об'єкти ----------------
DHTesp dht;
RTC_DS1307 rtc;
Servo valve;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// ---------------- Піни ----------------
#define DHT_PIN 15
#define PHOTO_A 12
#define PHOTO_D 13
#define SERVO_PIN 18
// ---------------- Константи ----------------
const float GAMMA = 0.7;
const float RL10 = 50;
// ---------------- Глобальні змінні ----------------
String gptReply = "Очікування даних...";
unsigned long lastUpdate = 0;
bool valveOpen = false;
// ---------------- Підключення до Wi-Fi ----------------
void connectWiFi() {
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.print("Підключення до Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("\n✅ Wi-Fi підключено!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
// ---------------- GPT ----------------
String callGPT(String prompt) {
HTTPClient http;
http.begin("https://artificialintelligence.openai.azure.com/openai/deployments/test/chat/completions?api-version=2023-05-15");
http.addHeader("Content-Type", "application/json");
http.addHeader("api-key", GPT_KEY);
DynamicJsonDocument doc(1024);
doc["model"] = "gpt-3.5-turbo";
JsonArray messages = doc.createNestedArray("messages");
JsonObject sys = messages.createNestedObject();
sys["role"] = "system";
sys["content"] = "You are a smart farming assistant. Give short recommendations.";
JsonObject user = messages.createNestedObject();
user["role"] = "user";
user["content"] = prompt;
String body;
serializeJson(doc, body);
int code = http.POST(body);
String result = "";
if (code == 200) {
String response = http.getString();
DynamicJsonDocument resp(4096);
DeserializationError err = deserializeJson(resp, response);
if (!err) {
result = resp["choices"][0]["message"]["content"].as<String>();
} else {
result = "Помилка розбору JSON";
}
} else {
result = "Помилка GPT-запиту (" + String(code) + ")";
}
http.end();
return result;
}
// ---------------- Серво ----------------
void toggleValve() {
for (int i = 0; i <= 180; i += 3) {
valve.write(i);
delay(5);
}
for (int i = 180; i >= 0; i -= 3) {
valve.write(i);
delay(5);
}
}
// ---------------- Основна логіка ----------------
void setup() {
Serial.begin(115200);
pinMode(PHOTO_A, INPUT);
pinMode(PHOTO_D, INPUT);
valve.attach(SERVO_PIN);
dht.setup(DHT_PIN, DHTesp::DHT22);
rtc.begin();
lcd.init();
lcd.backlight();
connectWiFi();
Serial.println("🌿 Система запущена");
}
void loop() {
unsigned long now = millis();
if (now - lastUpdate >= 10000) { // кожні 10 секунд
lastUpdate = now;
// --- Зчитування датчиків ---
TempAndHumidity env = dht.getTempAndHumidity();
int analogVal = analogRead(PHOTO_A);
float voltage = analogVal / 4096.0 * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
float lux = pow(RL10 * 1000 * pow(10, GAMMA) / resistance, 1 / GAMMA);
String lightState = digitalRead(PHOTO_D) == 0 ? "Яскраво" : "Темно";
// --- Формування рядка ---
String sensorData =
"Температура: " + String(env.temperature, 1) + "°C\n" +
"Вологість: " + String(env.humidity, 1) + "%\n" +
"Освітленість: " + lightState + " (" + String((int)lux) + " люкс)";
// --- Вивід показників ---
Serial.println("\n--- Показники ---");
Serial.println(sensorData);
// --- GPT запит ---
gptReply = callGPT(sensorData);
Serial.println("\n💬 Відповідь GPT:");
Serial.println(gptReply);
Serial.println("--------------------------");
// --- Оновлення LCD ---
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(String(env.temperature, 0) + "C " + String(env.humidity, 0) + "%");
lcd.setCursor(0, 1);
lcd.print(lightState);
}
}