#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
OneWire oneWireMain(4);
OneWire oneWireFreezer(5);
DallasTemperature sensorMain(&oneWireMain);
DallasTemperature sensorFreezer(&oneWireFreezer);
const int btnModeMainPin = 13;
const int btnModeFreezPin = 27;
const int btnIceMainPin = 18;
const int btnIceFreezPin = 19;
const int pinBuzzer = 23;
// Змінні стану
int stateMain = 0; // 0 = -30C, 1 = 0C, 2 = +10C
int stateFreez = 0; // 0 = -50C, 1 = -70C
bool iceMainActive = false;
bool iceFreezActive = false;
float targetMain = -30.0;
float targetFreez = -50.0;
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("System Loading..");
sensorMain.begin();
sensorFreezer.begin();
pinMode(btnModeMainPin, INPUT_PULLUP);
pinMode(btnModeFreezPin, INPUT_PULLUP);
pinMode(btnIceMainPin, INPUT_PULLUP);
pinMode(btnIceFreezPin, INPUT_PULLUP);
pinMode(pinBuzzer, OUTPUT);
delay(1000);
lcd.clear();
}
void loop() {
// --- 1. КНОПКИ РЕЖИМІВ ---
if (digitalRead(btnModeMainPin) == LOW) {
while (digitalRead(btnModeMainPin) == LOW); // антидребезг
stateMain++;
if (stateMain > 2) stateMain = 0;
if (stateMain == 0) targetMain = -30.0;
else if (stateMain == 1) targetMain = 0.0;
else targetMain = 10.0;
tone(pinBuzzer, 2000, 50);
}
if (digitalRead(btnModeFreezPin) == LOW) {
while (digitalRead(btnModeFreezPin) == LOW);
stateFreez++;
if (stateFreez > 1) stateFreez = 0;
if (stateFreez == 0) targetFreez = -50.0;
else targetFreez = -70.0;
tone(pinBuzzer, 2000, 50);
}
// --- 2. КНОПКИ ЛЬОДУ ---
if (digitalRead(btnIceMainPin) == LOW) {
while (digitalRead(btnIceMainPin) == LOW);
iceMainActive = !iceMainActive;
tone(pinBuzzer, 500, 100);
}
if (digitalRead(btnIceFreezPin) == LOW) {
while (digitalRead(btnIceFreezPin) == LOW);
iceFreezActive = !iceFreezActive;
tone(pinBuzzer, 500, 100);
}
// --- 3. ОТРИМАННЯ ТЕМПЕРАТУРИ ---
sensorMain.requestTemperatures();
sensorFreezer.requestTemperatures();
float currMain = sensorMain.getTempCByIndex(0);
float currFreez = sensorFreezer.getTempCByIndex(0);
// --- 4. ПЕРЕВІРКА ПОХИБКИ ---
bool alarmTempMain = false;
bool alarmTempFreez = false;
float limitMain = (targetMain == 0) ? 1.0 : abs(targetMain * 0.05);
float limitFreez = abs(targetFreez * 0.05);
if (abs(currMain - targetMain) > limitMain) alarmTempMain = true;
if (abs(currFreez - targetFreez) > limitFreez) alarmTempFreez = true;
// --- 5. ВІДОБРАЖЕННЯ ТА ТРИВОГА ---
// Пріоритет 1: ЛІД
if (iceMainActive || iceFreezActive) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("!!! WARNING !!!");
lcd.setCursor(0, 1);
if (iceMainActive && iceFreezActive) lcd.print("ICE: BOTH CAMS!");
else if (iceMainActive) lcd.print("ICE: MAIN CAM!");
else lcd.print("ICE: FREEZER!");
tone(pinBuzzer, 1000);
delay(300);
noTone(pinBuzzer);
delay(100);
return;
}
// Пріоритет 2: ТЕМПЕРАТУРА
if (alarmTempMain || alarmTempFreez) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("!!! TEMP ALARM !!!");
lcd.setCursor(0, 1);
if (alarmTempMain && alarmTempFreez) {
lcd.print("MAIN & FREEZ ERR");
}
else if (alarmTempMain) {
lcd.print("MAIN: ");
lcd.print(currMain, 1);
}
else {
lcd.print("FREEZ: ");
lcd.print(currFreez, 1);
}
tone(pinBuzzer, 400);
delay(500);
noTone(pinBuzzer);
return;
}
// Пріоритет 3: НОРМАЛЬНА РОБОТА
noTone(pinBuzzer);
lcd.setCursor(0, 0);
lcd.print("M:");
lcd.print(currMain, 1);
lcd.print(" /Set:");
lcd.print((int)targetMain);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("F:");
lcd.print(currFreez, 1);
lcd.print(" /Set:");
lcd.print((int)targetFreez);
lcd.print(" ");
delay(200);
}