/*
ARDUINO NANO ATMEGA328 AVR 5V 16 MHz z wywietlaczem LCD 1602 2x16 i HD44780.
Sterowanie grzaniem dwch piecy.
Pomiar temperatury na 2 czujnikach DS18B20.
Wywietlenie T1 i T2 oraz temperatury zadanej, programowanie temperatury zadanej
, delty grzania pieca oraz korekty ( Offset2 ) czujnika temperatury pieca 2.
Zastosowano filtr bdnych odczytw temperatury,
Autor Andrzej Coojew.
*/
#include <avr/wdt.h>
#include <OneWire.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS_1 2 //nr PIN = D2 dla sensora T1
#define ONE_WIRE_BUS_2 3 //nr PIN = D3 dla sensora T2
OneWire oneWire_1(ONE_WIRE_BUS_1);
OneWire oneWire_2(ONE_WIRE_BUS_2);
DallasTemperature sensor_1(&oneWire_1);
DallasTemperature sensor_2(&oneWire_2);
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7); // 0x27 is the I2C bus address
float T1 ;
float T2 ;
byte Tu ;
float Tx ;
float TxOld;
byte Taryfa2;
byte G1 = LOW;
byte G2 = LOW;
byte SW1 = HIGH;
byte SW2 = HIGH;
byte S1 = HIGH;
byte S2 = HIGH;
byte TempError1 = LOW;
byte TempError2 = LOW;
float delta = 3.0; // zajmuje 4 bajty
float deltaOld;
float Offset2 = 0.0;
float Offset2Old;
byte K = 0;
byte K2 = 0;
short i;
unsigned long start;
unsigned long koniec;
byte W1 = LOW;
byte W2 = LOW;
void setup()
{
cli(); //wyczenie WDT
wdt_reset(); // wyzerowanie licznika WDT
WDTCSR |= (1 << WDCE) | (1 << WDE); // inicjacja setup'u WDT
WDTCSR = (0 << WDIE) | (1 << WDE) | (1 << WDP3) | (0 << WDP2) | (0 << WDP1) | (1 << WDP0); //zaprogramowanie WDT na reset i czas 8 s.
sei(); // wczenie WDT
// activate LCD module
lcd.begin (16, 2); // for 16 x 2 LCD module
lcd.setBacklightPin(3, POSITIVE);
lcd.backlight(); // zaczenie podwietlenia
sensor_1.begin();
sensor_2.begin();
pinMode(A2, INPUT); // Taryfa2
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
pinMode(9, OUTPUT);
pinMode(A3, OUTPUT); // buzzer
digitalWrite(9, LOW);
pinMode(10, OUTPUT);
digitalWrite(10, LOW);
pinMode(11, OUTPUT);
digitalWrite(11, HIGH);
pinMode(12, OUTPUT);
digitalWrite(12, HIGH);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Tu = EEPROM.read(0);
EEPROM.get(9, Tx);
if (Tu < 20 || Tu > 60)
{
Tu = 30;
Tx = 25;
EEPROM.write(0, Tu);
EEPROM.put(1, delta); // zapisuje zmienn uamkow "delta"
EEPROM.put(5, Offset2); // zapisuje zmienn uamkow "Offset2"
EEPROM.put(9, Tx);
}
else
{
EEPROM.get(1, delta);
EEPROM.get(5, Offset2);
EEPROM.get(9, Tx);
}
lcd.clear();
lcd.print("STEROWNIK PIECOW");
lcd.setCursor (2, 1);
lcd.print("by A.Colojew");
delay(4000);
wdt_reset();
lcd.clear();
if (digitalRead(7) == HIGH)
{
lcd.print("Piec nr 1 i nr 2");
lcd.setCursor (4, 1);
lcd.print("WYLACZONY");
S1 = HIGH;
S2 = HIGH;
}
else
{
if (digitalRead(8) == LOW)
{
lcd.clear();
lcd.print("Piec nr 1 i nr 2");
lcd.setCursor (4, 1);
lcd.print("WLACZONY");
S1 = LOW;
S2 = LOW;
}
else
{
lcd.clear();
lcd.print(" Piec nr 1");
lcd.setCursor (4, 1);
lcd.print("WLACZONY");
S1 = LOW;
S2 = HIGH;
}
}
delay(4000);
wdt_reset();
CzytT1T2();
LCDprint(); // wywietlenie T1, T2 i Tu
Taryfa2 = digitalRead(A2); // czyta stan taryfy 2
}
void loop()
{
wdt_reset();
CzytT1T2(); //czyta T1 i T2. Kontrola zakuce, zaokrglenie (zajmuje ok. 1 s.)
if (S2 == HIGH && TempError1 == LOW && TempError2 == LOW) //wyczony 2 piec i nie ma ErrorTemp
{
lcd.setCursor (8, 0);
}
else
{
lcd.setCursor (3, 0); // set cursor to 3,0 //wywietlenie T1, T2
if (TempError2 == HIGH)
{
lcd.print(int(T2));
}
else
{
lcd.print(T2, 1); //
}
lcd.setCursor (12, 0); // set cursor to 12,0 //
}
if (TempError1 == HIGH)
{
lcd.print(int(T1));
}
else
{
lcd.print(T1, 1); //
}
if ( G1 == LOW && G2 == LOW) // czy piece nie grzej ?
{
digitalWrite(9, HIGH); // zmniejszenie owietlenia LCD.
}
else
{
digitalWrite(9, LOW); // zwikszenie owietlenia LCD gdy ktry piec grzeje.
}
if (W1 == HIGH || W2 == HIGH)
{
digitalWrite(A3, HIGH); // wczenie beep
lcd.setCursor (0, 1); // set cursor to 0,1
lcd.print("Blad temperatury ");
}
for (i = 0; i < 350; i++) // czeka 3.5 s.
{
SW1 = digitalRead(7); // czyta stan zezwolenie grzania 1 pieca
SW2 = digitalRead(8); // czyta stan zezwolenie grzania 2 pieca
if (digitalRead (4) == HIGH && S1 == SW1 && S2 == SW2 && Taryfa2 == digitalRead(A2))
{
delay(10);
}
else // przerywa czekanie
{
break;
}
wdt_reset();
}
if (W1 == HIGH || W2 == HIGH)
{
digitalWrite(A3, LOW); // wyczwnie beep
lcd.setCursor (0, 1); // set cursor to 0,1 //
lcd.print(" T zadana = "); //
lcd.print(Tu); //
lcd.print(" C"); //
}
for (i = 0; i < 500; i++) // czeka 5 s.
{
SW1 = digitalRead(7); // czyta stan zezwolenie grzania 1 pieca
SW2 = digitalRead(8); // czyta stan zezwolenie grzania 2 pieca
if (digitalRead (4) == HIGH && S1 == SW1 && S2 == SW2 && Taryfa2 == digitalRead(A2))
{
delay(10);
}
else // przerywa czekanie
{
if (Taryfa2 == digitalRead(A2))
{
W1 = LOW;
W2 = LOW;
}
Taryfa2 = digitalRead(A2); // czyta stan taryfy 2
break;
}
wdt_reset();
}
if ( S1 != SW1 ) // zmiana stanu wcznika 1 pieca
{
digitalWrite(9, LOW);
lcd.clear();
if ( SW1 == HIGH )
{
S1 = HIGH;
lcd.print( " Wylaczono");
lcd.setCursor (0, 1);
lcd.print("piec nr 1 i nr 2");
}
else
{
S1 = LOW;
lcd.print( " Wlaczono");
if ( SW2 == HIGH)
{
lcd.setCursor (3, 1);
lcd.print( "piec nr 1");
}
else
{
lcd.setCursor (0, 1);
lcd.print("piec nr 1 i nr 2");
}
}
delay(4000);
wdt_reset();
LCDprint(); // wywietlenie T1, T2 i Tu
}
if ( S2 != SW2 ) // zmiana stanu wcznika 2 pieca
{
digitalWrite(9, LOW);
lcd.clear();
if ( SW2 == HIGH )
{
S2 = HIGH;
lcd.print( " Wylaczono");
lcd.setCursor (3, 1);
lcd.print("piec nr 2");
wdt_reset();
delay(3000);
lcd.clear();
lcd.print(" ZAMKNIJ");
lcd.setCursor (1, 1);
lcd.print("zawor pieca 2");
for (i = 0; i < 6 ; i++)
{
lcd.noDisplay();
delay(300);
lcd.display();
delay(700);
wdt_reset();
}
}
else
{
S2 = LOW;
if ( SW1 == LOW )
{
lcd.print( " Wlaczono");
lcd.setCursor (3, 1);
lcd.print( "piec nr 2");
wdt_reset();
delay(3000);
lcd.clear();
lcd.print(" OTWORZ");
lcd.setCursor (1, 1);
lcd.print("zawor pieca 2");
for (i = 0; i < 6 ; i++)
{
lcd.noDisplay();
delay(300);
lcd.display();
delay(700);
wdt_reset();
}
}
else
{
lcd.print(" Blokada");
lcd.setCursor (2, 1);
lcd.print( "pieca nr 2");
wdt_reset();
delay(4000);
}
}
LCDprint(); // wywietlenie T1, T2 i Tu
}
if (digitalRead(4) == LOW) // czy nacinieto "SET"
{ // nacisnieto "SET"
digitalWrite(9, LOW);
lcd.clear(); //wywietlenie
lcd.setCursor (0, 0); // set cursor to 0,0 //"Ustaw tem. pieca"
lcd.print("Ustaw tem. pieca");
lcd.setCursor (5, 1);
lcd.print("T = ");
lcd.print(Tu);
lcd.print(" C");
PullSW3(); // czeka na puszczenie "SET"
start = millis(); // zaadowanie licznika czasu
while (digitalRead(4) == HIGH) //wykonuj dopuki nie nacinito "SET"
{
if (digitalRead(5) == LOW) // czy nacinieto "-"
{
start = millis();
Tu = Tu - 1;
Tu = constrain (Tu, 20 , 60 ); // ograniczenie Tmin do 20 C
lcd.setCursor (9, 1);
lcd.print(Tu);
delay (300);
}
if (digitalRead(6) == LOW) // czy nacinieto "+"
{
start = millis();
Tu = Tu + 1;
Tu = constrain (Tu, 20 , 60 ); // ograniczenie Tmax do 60 C
lcd.setCursor (9, 1);
lcd.print(Tu);
delay (300);
}
koniec = millis();
if (koniec - start >= 30000 ) // jeeli nic si nie dziao przez 30 s. to RETURN.
{
LCDprint();
return;
}
wdt_reset();
}
EEPROM.update (0, Tu); // zapis do EEPROMU ustawionej tem. Tu (update: jeeli nie zmany - nie zapisuje)
lcd.clear(); // wywietlenie "Ustaw delty pieca"
lcd.setCursor (0, 0); // set cursor to 0,0
lcd.print("Ustaw del. pieca");
lcd.setCursor (2, 1);
lcd.print("delta = ");
lcd.print(delta, 1);
lcd.print(" C");
PullSW3(); // czeka na puszczenie "SET"
deltaOld = delta;
start = millis();
while (digitalRead(4) == HIGH) //wykonuj dopuki nie nacinito "SET"
{
if (digitalRead(5) == LOW) // czy nacinieto "-"
{
start = millis();
delta = delta - 0.1;
delta = constrain (delta, 0.3 , 5 ); // ograniczenie delty do 0.3 C
lcd.setCursor (10, 1);
lcd.print(delta, 1);
lcd.print(" C ");
delay (300);
}
if (digitalRead(6) == LOW) // czy nacinieto "+"
{
start = millis();
delta = delta + 0.1;
delta = constrain (delta, 0.3 , 5 ); // ograniczenie delty do 5 C
lcd.setCursor (10, 1);
lcd.print(delta, 1);
lcd.print(" C ");
delay (300);
}
koniec = millis();
if (koniec - start >= 30000 )
{
LCDprint();
return;
}
wdt_reset();
}
if (deltaOld != delta )
{
EEPROM.put(1, delta); // zapis do EEPROMU ustawionej delty .
}
lcd.clear(); // wywietlenie "Ustaw Offset pieca 2"
lcd.setCursor (0, 0); // set cursor to 0,0
lcd.print("Offset pieca 2:");
lcd.setCursor (1, 1);
lcd.print("offset = ");
lcd.print(Offset2, 1);
lcd.print(" C");
PullSW3(); // czeka na puszczenie "SET"
Offset2Old = Offset2;
start = millis();
while (digitalRead(4) == HIGH) //wykonuj dopuki nie nacinito "SET"
{
if (digitalRead(5) == LOW) // czy nacinieto "-"
{
start = millis();
Offset2 = Offset2 - 0.1;
Offset2 = constrain (Offset2, -3 , 3 ); // ograniczenie Offset2 do -3 C
lcd.setCursor (10, 1);
lcd.print(Offset2, 1);
lcd.print(" C ");
delay (300);
}
if (digitalRead(6) == LOW) // czy nacinieto "+"
{
start = millis();
Offset2 = Offset2 + 0.1;
Offset2 = constrain (Offset2, -3 , 3 ); // ograniczenie Offset2 do 3 C
lcd.setCursor (10, 1);
lcd.print(Offset2, 1);
lcd.print(" C ");
delay (300);
}
koniec = millis();
if (koniec - start >= 30000 )
{
LCDprint();
return;
}
wdt_reset();
}
if (Offset2 != Offset2Old)
{
EEPROM.put(5, Offset2); // zapis do EEPROMU ustawiony Offset2 .
}
//////////////////////////////////////////////////////////////////////////////////////////
lcd.clear(); // wywietlenie "Ustaw Tx"
lcd.setCursor (2, 0); // set cursor to 2,0
lcd.print("Tx pieca 1 :");
lcd.setCursor (2, 1);
lcd.print("Tx = ");
lcd.print(Tx, 1);
lcd.print(" C ");
PullSW3(); // czeka na puszczenie "SET"
TxOld = Tx;
start = millis();
while (digitalRead(4) == HIGH) //wykonuj dopuki nie nacinito "SET"
{
if (digitalRead(5) == LOW) // czy nacinieto "-"
{
start = millis();
Tx = Tx - 0.2;
Tx = constrain (Tx, 3 , 30 ); // ograniczenie Tx do 3 C
lcd.setCursor (7, 1);
lcd.print(Tx, 1);
lcd.print(" C ");
delay (300);
}
if (digitalRead(6) == LOW) // czy nacinieto "+"
{
start = millis();
Tx = Tx + 0.2;
Tx = constrain (Tx, 3 , 30 ); // ograniczenie Tx do 30 C
lcd.setCursor (7, 1);
lcd.print(Tx, 1);
lcd.print(" C ");
delay (300);
}
koniec = millis();
if (koniec - start >= 30000 )
{
LCDprint();
return;
}
wdt_reset();
}
if (Tx != TxOld)
{
EEPROM.put(9, Tx); // zapis do EEPROMU ustawiony Tx .
}
LCDprint(); // wywietlenie T1, T2 i Tu
PullSW3(); // czeka na puszczenie "SET"
//////////////////////////////////////////////////////////////////////////////////////////
}
if (SW1 == HIGH) // czy brak zezwolenia na grzanie 1 pieca
{
G1 = LOW;
G2 = LOW;
digitalWrite(10, LOW);
digitalWrite(11, HIGH);
digitalWrite(12, HIGH);
digitalWrite(13, LOW);
K = 0;
K2 = 0;
return;
}
if (SW2 == HIGH) // czy brak zezwolenia na grzanie 2 pieca
{
G2 = LOW;
digitalWrite(12, HIGH);
digitalWrite(13, LOW);
digitalWrite(10, LOW);
if (TempError1 == HIGH)
{ // wyczenie 1 pieca.
G1 = LOW;
digitalWrite(11, HIGH);
K = 0;
return;
}
if (G1 == HIGH) // 1 piec grzeje.
{
if (T1 >= Tu)
{ // nagrza si 1 piec.
K = K + 1;
if ( K >= 3 )
{ // wyczenie 1 pieca.
G1 = LOW;
digitalWrite(11, HIGH);
K = 0;
}
return;
}
K = 0;
return;
}
if (Taryfa2 == LOW)
{ // WSTAWKA !!!!!!
if (T1 <= Tu - Tx) // czy nadmierne schodzenie pieca?
{
G1 = HIGH;
digitalWrite(11, LOW); // wczenie 1 pieca.
K = 0;
}
// koniec wstawki
return;
}
if (T1 <= Tu - delta) // czy chce grza 1 piec ?
{
K = K + 1;
if ( K >= 4 )
{
G1 = HIGH;
digitalWrite(11, LOW); // wczenie 1 pieca.
K = 0;
}
return;
}
K = 0;
return;
}
// oba piece mog grza.
if (G1 == HIGH) // grzeje 1 piec.
{
if (TempError1 == HIGH)
{ // wyczenie 1 pieca.
G1 = LOW;
digitalWrite(11, HIGH);
K = 0;
}
else
{
if (T2 <= Tu - delta && Taryfa2 == HIGH) // czy jest 2 taryfa i 2 piec chce grza ?
{
digitalWrite(13, HIGH);
}
else
{
digitalWrite(13, LOW);
}
if (T1 < Tu) // czy nie nagrza si 1 piec ?
{
K = 0;
return;
}
K = K + 1;
if (K < 3 )
{
return;
}
G1 = LOW; // wyczenie 1 pieca.
digitalWrite(11, HIGH);
K = 0;
}
if (T2 <= Tu - delta ) // 2 piec chce grza ?
{
if (TempError2 == LOW)
{
digitalWrite(12, LOW); // wczenie 2 pieca.
digitalWrite(13, LOW);
G2 = HIGH; // wczenie flagi "2 piec grzeje".
}
}
return;
}
if (G2 == HIGH) // czy grzeje 2 piec ?
{
if (TempError2 == HIGH)
{
G2 = LOW; // wyczenie 2 pieca.
digitalWrite(12, HIGH);
K = 0;
}
if (T1 <= Tu - delta && Taryfa2 == HIGH) // czy jest 2 taryfa i 1 piec chce grza ?
{
digitalWrite(10, HIGH);
}
else
{
digitalWrite(10, LOW);
}
if (T2 < Tu) // czy 2 piec nienagrzany ?
{
K = 0;
return;
}
K = K + 1;
if (K < 3 )
{
return;
}
G2 = LOW; // wyczenie 2 pieca.
digitalWrite(12, HIGH);
K = 0;
if (T1 <= Tu - delta && Taryfa2 == HIGH) // czy jest 2 taryfa i 1 piec chce grza ?
{
if (TempError1 == LOW)
{
digitalWrite(11, LOW); // wczenie 1 pieca.
digitalWrite(10, LOW);
G1 = HIGH; // wczenie flagi "1 piec grzeje".
}
}
return;
}
if (Taryfa2 == LOW) // czy nie ma 2 taryfy ?
{
// WSTAWKA !!!!!!
if (TempError1 == LOW )
{
if (T1 <= Tu - Tx) // czy nadmierne schodzenie pieca?
{
G1 = HIGH;
digitalWrite(11, LOW); // wczenie 1 pieca.
K = 0;
}
} // koniec wstawki
digitalWrite(10, LOW);
digitalWrite(13, LOW);
return;
}
if (TempError1 == LOW)
{
if (T1 <= Tu - delta) // czy chce grza 1 piec ?
{
K = K + 1;
if ( K >= 4 )
{
G1 = HIGH;
digitalWrite(11, LOW); // wczenie 1 pieca.
digitalWrite(10, LOW);
K = 0;
}
return;
}
}
K = 0;
digitalWrite(10, LOW);
if ( TempError2 == LOW)
{
if (T2 <= Tu - delta) // czy chce grza 2 piec ?
{
K2 = K2 + 1;
if ( K2 >= 4 )
{
digitalWrite(12, LOW); // wczenie 2 pieca.
digitalWrite(13, LOW);
G2 = HIGH; // wczenie flagi "2 piec grzeje".
K2 = 0;
}
return;
}
}
K2 = 0;
digitalWrite(13, LOW);
}
// KONIEC programu LOOP.
// PROCEDURY.
void PullSW3() // Czeka na puszczenie "SET"
{
while (digitalRead(4) == LOW)
{
delay(50);
wdt_reset();
}
delay(50);
}
void LCDprint()
{
lcd.clear();
if (S2 == HIGH && TempError1 == LOW && TempError2 == LOW) //wyczony 2 piec i nie ma TempError
{
lcd.setCursor (3, 0); // wywietlenie T1, Tu
lcd.print("T1 = ");
lcd.print(T1, 1);
lcd.print(" C");
}
else
{
lcd.setCursor (0, 0); // set cursor to 0,0 //wywietlenie T1, T2, Tu
lcd.print("T2="); //
if (TempError2 == HIGH)
{
lcd.print(int(T2));
}
else
{
lcd.print(T2, 1);
}
lcd.print(" T1=");
if (TempError1 == HIGH)
{
lcd.print(int(T1));
}
else
{
lcd.print(T1, 1);
}
} //
lcd.setCursor (1, 1); // set cursor to 0,1 //
lcd.print("T zadana = "); //
lcd.print(Tu); //
lcd.print(" C"); //
}
float CzytT1T2()
{
float T11 = 0;
float T21 = 0;
for (i = 0 ; i < 7 ; i++) // oblicza redni z 7 pomiarw
{
sensor_1.setWaitForConversion(false); // makes it async
sensor_2.setWaitForConversion(false); // makes it async
sensor_1.requestTemperatures();
sensor_2.requestTemperatures();
delay(150);
T11 = T11 + sensor_1.getTempCByIndex(0);
T21 = T21 + sensor_2.getTempCByIndex(0);
}
wdt_reset();
T11 = T11 / 7;
T21 = T21 / 7;
if (T11 < 10 || T11 > 65)
{
G1 = LOW; // wyczenie 1 pieca.
digitalWrite(11, HIGH);
digitalWrite(10, LOW);
if (TempError1 == LOW)
{
TempError1 = HIGH;
W1 = HIGH;
lcd.setCursor (0, 0); // set cursor to 0,0 // wywietlenie T1, T2, Tu
lcd.print("T2="); //
lcd.print(T21, 1); //
lcd.setCursor(7, 0);
lcd.print(" T1="); //
lcd.print(int(T11)); //
}
}
else
{
if (TempError1 == HIGH)
{
TempError1 = LOW;
W1 = LOW;
T1 = T11;
LCDprint();
}
}
if (T21 < 10 || T21 > 65)
{
G2 = LOW; // wyczenie 2 pieca.
digitalWrite(12, HIGH);
digitalWrite(13, LOW);
if (TempError2 == LOW)
{
TempError2 = HIGH;
W2 = HIGH;
lcd.setCursor (0, 0); // set cursor to 0,0 //wywietlenie T1, T2, Tu
lcd.print("T2="); //
lcd.print(int (T21)); //
lcd.setCursor(7, 0);
lcd.print(" T1="); //
lcd.print(T11, 1); //
}
}
else
{
if (TempError2 == HIGH)
{
TempError2 = LOW;
W2 = LOW;
T2 = T21;
LCDprint();
}
}
T11 = T11 * 10; // zaokrglenie Temp. do jednego miejsca po przecinku.
T1 = int( T11 );
if (T11 - T1 > 0.5)
{
T1 = T1 + 1;
}
T1 = T1 / 10;
T21 = T21 * 10;
T2 = int( T21 );
if (T21 - T2 > 0.5)
{
T2 = T2 + 1;
}
T2 = T2 / 10 + Offset2 + 0.2; // korekta o offset oraz uchyb.
return (T1, T2);
}
Comments
Please log in or sign up to comment.