#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// Keypad setup
const byte KEYPAD_ROWS = 4;
const byte KEYPAD_COLS = 4;
byte rowPins[KEYPAD_ROWS] = {5, 4, 3, 2};
byte colPins[KEYPAD_COLS] = {A3, A2, A1, A0};
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
// 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 hysteresis = 0.25;
float hysteresisHigh1 = 20.0;
float hysteresisLow1 = hysteresisHigh1 - hysteresis;
float hysteresisHigh2 = 22.5;
float hysteresisLow2 = hysteresisHigh2 - hysteresis;
float hysteresisHigh3 = 22.5;
float hysteresisLow3 = hysteresisHigh3 - hysteresis;
float hysteresisHigh4 = 22.5;
float hysteresisLow4 = hysteresisHigh4 - hysteresis;
// 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";
// Aktywacja nadawania temperatur
int activTemp = 1;
char key;
void setup() {
// test LCD
lcd.init();
lcd.backlight();
lcd.setCursor(3, 1);
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);
Serial.println(key);
Serial.println(hysteresisLow1);
Serial.println(hysteresisHigh1);
// Wyświetlanie temperatur na LCD
lcd.clear();
int high = 13;
int digit = 2;
int first = 0;
tmp1 = prtLcd(temp1, 0, digit, first, high, hysteresisHigh1);
tmp2 = prtLcd(temp2, 1, digit, first, high, hysteresisHigh2);
tmp3 = prtLcd(temp3, 2, digit, first, high, hysteresisHigh3);
tmp4 = prtLcd(temp4, 3, digit, first, high, 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(5000);
// funkcja zmiany nastaw
lcd.clear();
key = keypad.getKey();
if (key == '#'){
// Menu A B C D return button
menu(key);
// wybór sekcji histerezy rerurn low high
if (key == 'A'){
lcd.clear();
lcd.setCursor(3, 1);
lcd.print("Hello, world!");
}
// nastawa return new low/high
// hysteresisLow1 = setSection(hysteresisLow1, key);
delay(1000);
}
}
// 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, float hh ){
lcd.setCursor(k0, row);
lcd.print("T");
lcd.print(row+1);
lcd.print(": ");
lcd.print(temp);
lcd.setCursor(k1, row);
lcd.print("H:");
lcd.print(hh, dig);
}
// Funkcja zmiany histerezy
/*
float setSection (float tempSet, char button){
while (button != '0') {
lcd.clear();
lcd.print("Wybierz sekcje:");
lcd.setCursor(0, 1);
lcd.print("A > T1 B > T2");
lcd.setCursor(0, 2);
lcd.print("C > T3 D > T4");
lcd.setCursor(0, 3);
lcd.print("EXIT >> 0");
delay(2000);
button = keypad.getKey();
if (button == 'A'){
lcd.clear();
lcd.println("Sukces");
lcd.println("Sekcja 1");
delay(1000);
while (button != 'D') {
lcd.clear();
lcd.print("Aktualna Temp");
lcd.setCursor(0, 1);
lcd.print(tempSet);
lcd.setCursor(0, 2);
lcd.print("A + 0,25 B - 0,25");
lcd.setCursor(0, 3);
lcd.print("EXIT >> D");
if (button == 'A'){
tempSet = tempSet + 0.25;
}
if (button == 'B'){
tempSet = tempSet - 0.25;
button = '2';
}
else{
button = keypad.getKey();
}
delay(1000);
}
button = '1';
return tempSet;
delay(1000);
}
}
}
*/
/*
while (key != '0') {
key = keypad.getKey();
if (key == 'A'){
lcd.clear();
lcd.print("Sukces");
float nthh = thh + 1;
float nthl = thl + 1;
lcd.setCursor(1, 1);
lcd.print(nthh);
lcd.setCursor(1, 2);
lcd.print(nthl);
return thh = nthh;
return thl = nthl;
delay(1000);
key = '0';
}
}
}
*/
//MENU
char menu (char sect){
while (sect != 'A' && sect != 'B' && sect != 'C' && sect != 'D' && sect != '0'){
lcd.clear();
lcd.print("Wybierz sekcje:");
lcd.setCursor(0, 1);
lcd.print("A > T1 B > T2");
lcd.setCursor(0, 2);
lcd.print("C > T3 D > T4");
lcd.setCursor(0, 3);
lcd.print("EXIT >> 0");
delay(2000);
sect = keypad.getKey();
if (sect == 'A' && sect == 'B' && sect == 'C' && sect == 'D' && sect == '0'){
lcd.clear();
lcd.print(sect);
delay(1000);
}
}
delay(1000);
return sect;
}
/*
WYBÓR SEKCJI
if (button == 'A'){
lcd.clear();
lcd.print("Sukces");
lcd.print("wybrano Sekcje ");
lcd.println(button);
delay(1000);
*/
/*
//ZMIANA NASTAWY
float newTemp (float tempSet, char button){
while (button != 'D') {
lcd.clear();
lcd.print("Aktualna Temp");
lcd.setCursor(0, 1);
lcd.print(tempSet);
lcd.setCursor(0, 2);
lcd.print("A + 0,25 B - 0,25");
lcd.setCursor(0, 3);
lcd.print("EXIT >> D");
if (button == 'A'){
tempSet = tempSet + 0.25;
}
if (button == 'B'){
tempSet = tempSet - 0.25;
button = '2';
}
else{
button = keypad.getKey();
delay(1000);
}
}
}
*/