#include <LiquidCrystal_I2C.h>
#include <DHT.h>
// Komponent pinlari
#define ENCODER_CLK 2
#define ENCODER_DT 3
#define ENCODER_SW 4
#define DHT_PIN 7
#define RELAY_HEATER 6
#define RELAY_FAN 5
// LCD va DHT sozlamalari
LiquidCrystal_I2C lcd(0x27, 16, 2);
DHT dht(DHT_PIN, DHT22);
// Global o‘zgaruvchilar
float targetTemp = 37.5;
int timerMinutes = 60;
float currentTemp;
float currentHumidity;
int menuIndex = 0;
bool inSubMenu = false;
void setup() {
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
pinMode(RELAY_HEATER, OUTPUT);
pinMode(RELAY_FAN, OUTPUT);
lcd.init();
lcd.backlight();
dht.begin();
// Dastlabki logo
lcd.setCursor(4, 0);
lcd.print("INKUBATOR");
lcd.setCursor(2, 1);
lcd.print("KY-040 BILAN");
delay(3000);
lcd.clear();
// Asosiy ekran
displayMainScreen();
}
void loop() {
// Harorat va namlikni yangilash
currentTemp = dht.readTemperature();
currentHumidity = dht.readHumidity();
// Haroratni boshqarish
controlTemperature();
// SW tugmasi bosilganda menyuga kirish
if (digitalRead(ENCODER_SW) == LOW) {
delay(200); // Debouncing
inSubMenu = !inSubMenu;
if (inSubMenu) {
displayMenu();
} else {
displayMainScreen();
}
}
// Menyu ichida harakatlanish
if (inSubMenu) {
handleMenu();
}
}
void displayMainScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Harorat: ");
lcd.print(currentTemp);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("Namlik: ");
lcd.print(currentHumidity);
lcd.print("%");
}
void displayMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Harorat sozla");
lcd.setCursor(0, 1);
lcd.print("Taymer sozla");
}
void handleMenu() {
static int lastEncoderState = digitalRead(ENCODER_CLK);
int encoderState = digitalRead(ENCODER_CLK);
if (encoderState != lastEncoderState) {
if (digitalRead(ENCODER_DT) != encoderState) {
menuIndex++;
} else {
menuIndex--;
}
menuIndex = constrain(menuIndex, 1, 3);
lcd.clear();
if (menuIndex == 1) {
lcd.setCursor(0, 0);
lcd.print("> Harorat sozla");
lcd.setCursor(0, 1);
lcd.print(" Taymer sozla");
} else if (menuIndex == 2) {
lcd.setCursor(0, 0);
lcd.print(" Harorat sozla");
lcd.setCursor(0, 1);
lcd.print("> Taymer sozla");
} else if (menuIndex == 3) {
lcd.setCursor(0, 0);
lcd.print(" Ortga qaytish");
}
}
lastEncoderState = encoderState;
// SW tugmasi bosilganda menyu ichiga kirish
if (digitalRead(ENCODER_SW) == LOW) {
delay(200); // Debouncing
if (menuIndex == 0) {
adjustTemperature();
} else if (menuIndex == 1) {
adjustTimer();
} else if (menuIndex == 2) {
inSubMenu = false;
displayMainScreen();
}
}
}
void adjustTemperature() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Harorat sozlash:");
lcd.setCursor(0, 1);
lcd.print(targetTemp);
lcd.print((char)223);
lcd.print("C");
while (digitalRead(ENCODER_SW) != LOW) {
int encoderState = digitalRead(ENCODER_CLK);
static int lastEncoderState = encoderState;
if (encoderState != lastEncoderState) {
if (digitalRead(ENCODER_DT) != encoderState) {
targetTemp += 0.5;
} else {
targetTemp -= 0.5;
}
targetTemp = constrain(targetTemp, 30.0, 40.0);
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(targetTemp);
lcd.print((char)223);
lcd.print("C");
}
lastEncoderState = encoderState;
}
delay(200); // Debouncing
}
void adjustTimer() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Taymer sozlash:");
lcd.setCursor(0, 1);
lcd.print(timerMinutes);
lcd.print(" min");
while (digitalRead(ENCODER_SW) != LOW) {
int encoderState = digitalRead(ENCODER_CLK);
static int lastEncoderState = encoderState;
if (encoderState != lastEncoderState) {
if (digitalRead(ENCODER_DT) != encoderState) {
timerMinutes++;
} else {
timerMinutes--;
}
timerMinutes = constrain(timerMinutes, 0, 1440);
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(timerMinutes);
lcd.print(" min");
}
lastEncoderState = encoderState;
}
delay(200); // Debouncing
}
void controlTemperature() {
if (currentTemp < targetTemp) {
digitalWrite(RELAY_HEATER, HIGH);
digitalWrite(RELAY_FAN, LOW);
} else {
digitalWrite(RELAY_HEATER, LOW);
digitalWrite(RELAY_FAN, HIGH);
}
}