#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
// Definicje LDC dla I2C
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
// Definicje pinów dla czujników DS18B20
#define ONE_WIRE_BUS1 22
#define ONE_WIRE_BUS2 23
#define ONE_WIRE_BUS3 24
#define ONE_WIRE_BUS4 25
// Inicjalizacja obiektów OneWire dla każdego czujnika
OneWire oneWire1(ONE_WIRE_BUS1);
OneWire oneWire2(ONE_WIRE_BUS2);
OneWire oneWire3(ONE_WIRE_BUS3);
OneWire oneWire4(ONE_WIRE_BUS4);
// Inicjalizacja obiektów DallasTemperature dla każdego czujnika
DallasTemperature sensors1(&oneWire1);
DallasTemperature sensors2(&oneWire2);
DallasTemperature sensors3(&oneWire3);
DallasTemperature sensors4(&oneWire4);
// Definicje dla przekaźników
#define RELAY1 26
#define RELAY2 27
#define RELAY3 28
#define RELAY4 29
// Ustawienia progów temperatury dla każdego obiegu (początkowo)
float tempSetpoint1 = 22.0;
float tempSetpoint2 = 22.0;
float tempSetpoint3 = 22.0;
float tempSetpoint4 = 22.0;
// Histereza dla każdego obwodu
float hysteresisLow1 = 20.0;
float hysteresisHigh1 = 20.5;
float hysteresisLow2 = 21.0;
float hysteresisHigh2 = 21.5;
float hysteresisLow3 = 20.0;
float hysteresisHigh3 = 20.5;
float hysteresisLow4 = 21.5;
float hysteresisHigh4 = 22.5;
// Stan przekaźników (pamięć poprzedniego stanu)
bool relayState1 = false;
bool relayState2 = false;
bool relayState3 = false;
bool relayState4 = false;
// Stany temperatury do wyświetlenia inicjalizacja
String tmp1 = "none";
String tmp2 = "none";
String tmp3 = "none";
String tmp4 = "none";
void setup() {
// test LCD
lcd.init();
lcd.backlight();
lcd.setCursor(3, 0);
lcd.print("Hello, world!");
// Inicjalizacja czujników
sensors1.begin();
sensors2.begin();
sensors3.begin();
sensors4.begin();
// Inicjalizacja przekaźników jako wyjścia
pinMode(RELAY1, OUTPUT);
pinMode(RELAY2, OUTPUT);
pinMode(RELAY3, OUTPUT);
pinMode(RELAY4, OUTPUT);
// Domyślne wyłączenie przekaźników
digitalWrite(RELAY1, LOW);
digitalWrite(RELAY2, LOW);
digitalWrite(RELAY3, LOW);
digitalWrite(RELAY4, LOW);
// Ustawienia początkowe dla Serial (opcjonalnie)
Serial.begin(9600);
}
void loop() {
// Aktualizacja temperatury z każdego czujnika
sensors1.requestTemperatures();
sensors2.requestTemperatures();
sensors3.requestTemperatures();
sensors4.requestTemperatures();
float temp1 = sensors1.getTempCByIndex(0);
float temp2 = sensors2.getTempCByIndex(0);
float temp3 = sensors3.getTempCByIndex(0);
float temp4 = sensors4.getTempCByIndex(0);
// Wyświetlanie temperatur (opcjonalnie)
Serial.print("Temperatura 1: ");
Serial.println(temp1);
Serial.print("Temperatura 2: ");
Serial.println(temp2);
Serial.print("Temperatura 3: ");
Serial.println(temp3);
Serial.print("Temperatura 4: ");
Serial.println(temp4);
// Wyświetlanie temperatur na LCD
lcd.clear();
int high = 16;
int low = 11;
int digit = 0;
int first = 0;
tmp1 = prtLcd(temp1, 0, digit, first, low, high, hysteresisLow1, hysteresisHigh1);
tmp2 = prtLcd(temp2, 1, digit, first, low, high, hysteresisLow2, hysteresisHigh2);
tmp3 = prtLcd(temp3, 2, digit, first, low, high, hysteresisLow3, hysteresisHigh3);
tmp4 = prtLcd(temp4, 3, digit, first, low, high, hysteresisLow4, hysteresisHigh4);
// Sterowanie przekaźnikami na podstawie temperatury z indywidualną histerezą
relayState1 = controlRelayWithHysteresis(RELAY1, temp1, relayState1, hysteresisLow1, hysteresisHigh1);
relayState2 = controlRelayWithHysteresis(RELAY2, temp2, relayState2, hysteresisLow2, hysteresisHigh2);
relayState3 = controlRelayWithHysteresis(RELAY3, temp3, relayState3, hysteresisLow3, hysteresisHigh3);
relayState4 = controlRelayWithHysteresis(RELAY4, temp4, relayState4, hysteresisLow4, hysteresisHigh4);
// Opóźnienie na potrzeby stabilności odczytów
delay(10000);
}
// Funkcja sterująca przekaźnikiem na podstawie indywidualnej histerezy
bool controlRelayWithHysteresis(int relayPin, float currentTemp, bool currentRelayState, float hysteresisLow, float hysteresisHigh) {
if (currentTemp < hysteresisLow && !currentRelayState) {
digitalWrite(relayPin, HIGH); // Włącz grzanie
return true;
} else if (currentTemp > hysteresisHigh && currentRelayState) {
digitalWrite(relayPin, LOW); // Wyłącz grzanie
return false;
}
return currentRelayState; // Zwróć aktualny stan, jeśli nic się nie zmieniło
}
// Funkcja wyświetlania temperatur na LCD
String prtLcd (float temp, int row, int dig, int k0, int k1, int k2, float hl, float hh ){
lcd.setCursor(k0, row);
lcd.print("T");
lcd.print(row+1);
lcd.print(": ");
lcd.print(temp);
lcd.setCursor(k1, row);
lcd.print("L:");
lcd.print(hl, dig);
lcd.setCursor(k2, row);
lcd.print("H:");
lcd.print(hh, dig);
}