2023-08-25 13:45:14 +02:00
// First we include the libraries
# include <OneWire.h>
# include <DallasTemperature.h>
# include <Controllino.h>
# include <SPI.h>
# include <Ethernet.h>
2023-08-29 10:03:58 +02:00
# include <EEPROM.h>
2023-08-25 13:45:14 +02:00
/********************************************************************/
// Data wire is plugged into pin 2 on the Arduino
2023-08-28 23:15:14 +02:00
# define ONE_WIRE_BUS 2
# define TEMPERATURE_PRECISION 11
2023-08-25 13:45:14 +02:00
/********************************************************************/
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire ( ONE_WIRE_BUS ) ;
/********************************************************************/
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors ( & oneWire ) ;
/********************************************************************/
2023-08-28 23:15:14 +02:00
DeviceAddress adT1 = { 0x28 , 0xF8 , 0xE2 , 0x80 , 0xE3 , 0xE1 , 0x3C , 0xC2 } ;
DeviceAddress adT2 = { 0x28 , 0x89 , 0x9F , 0x80 , 0xE3 , 0xE1 , 0x3C , 0xEC } ;
DeviceAddress adKW = { 0x28 , 0x3B , 0x58 , 0x80 , 0xE3 , 0xE1 , 0x3C , 0xF6 } ;
float TT1_Sp = 30.0 ;
float TT2_Sp = 30.0 ;
float TKW_Sp = 0.0 ;
float Hyst_Sp = 0.5 ;
2023-08-29 10:03:58 +02:00
// Hilfswerte für EEPROM schreiben
float H_TT1_Sp ;
float H_TT2_Sp ;
float H_TKW_Sp ;
float H_Hyst_Sp ;
2023-08-28 23:15:14 +02:00
float TT1_AV ;
float TT2_AV ;
float TKW_AV ;
byte Act_T1 ;
byte Act_T2 ;
byte Act_KW ;
byte State_Bypass = 0 ;
unsigned long previousMillisBypass = 0 ;
byte State_T1 = 0 ;
unsigned long previousMillisT1 = 0 ;
byte State_T2 = 0 ;
unsigned long previousMillisT2 = 0 ;
// Variables for Webserver
2023-08-25 13:45:14 +02:00
byte mac [ ] = { 0x90 , 0xA2 , 0xDA , 0x00 , 0x09 , 0x70 } ;
2023-08-30 15:40:59 +02:00
IPAddress ip ( 192 , 168 , 8 , 57 ) ;
2023-08-25 13:45:14 +02:00
EthernetServer server ( 80 ) ;
2023-08-28 23:15:14 +02:00
String readString ;
int b_str ;
int e_str ;
String t1_str ;
String t2_str ;
float t1_float ;
float t2_float ;
void setup ( void )
{
Serial . begin ( 9600 ) ;
sensors . begin ( ) ;
pinMode ( 22 , OUTPUT ) ;
pinMode ( 23 , OUTPUT ) ;
pinMode ( 24 , OUTPUT ) ;
pinMode ( 30 , OUTPUT ) ;
pinMode ( 31 , OUTPUT ) ;
// set the resolution per device
sensors . setResolution ( adT1 , TEMPERATURE_PRECISION ) ;
sensors . setResolution ( adT2 , TEMPERATURE_PRECISION ) ;
sensors . setResolution ( adKW , TEMPERATURE_PRECISION ) ;
2023-08-25 13:45:14 +02:00
2023-08-28 23:15:14 +02:00
// Ethernet Verbindung und Server starten
2023-08-25 13:45:14 +02:00
Ethernet . begin ( mac , ip ) ;
server . begin ( ) ;
2023-08-28 23:15:14 +02:00
Serial . print ( " Server gestartet. IP: " ) ;
// IP des Arduino-Servers ausgeben
Serial . println ( Ethernet . localIP ( ) ) ;
2023-08-29 10:03:58 +02:00
// Get Setpoints from EEPROM
EEPROM . get ( 0 , TT1_Sp ) ;
EEPROM . get ( 4 , TT2_Sp ) ;
EEPROM . get ( 8 , TKW_Sp ) ;
EEPROM . get ( 12 , Hyst_Sp ) ;
H_TT1_Sp = TT1_Sp ;
H_TT2_Sp = TT2_Sp ;
H_TKW_Sp = TKW_Sp ;
H_Hyst_Sp = Hyst_Sp ;
2023-08-25 13:45:14 +02:00
}
2023-08-28 23:15:14 +02:00
void loop ( void )
{
// Versorge Zeit
unsigned long currentMillis = millis ( ) ;
2023-08-29 10:03:58 +02:00
2023-08-28 23:15:14 +02:00
// Hole Temperaturen
sensors . requestTemperatures ( ) ;
TT1_AV = sensors . getTempC ( adT1 ) ;
//TT1_AV = sensors.getTempCByIndex(0);
TT2_AV = sensors . getTempC ( adT2 ) ;
//TT2_AV = sensors.getTempCByIndex(1);
TKW_AV = sensors . getTempC ( adKW ) ;
//TKW_AV = sensors.getTempCByIndex(2);
// Vergleiche Aktualtemperaturen mit Setpoint
// Tank 1
if ( TT1_AV > = TT1_Sp + Hyst_Sp ) {
Act_T1 = 1 ;
}
if ( TT1_AV < = TT1_Sp ) {
Act_T1 = 0 ;
}
if ( TT2_AV > = TT2_Sp + Hyst_Sp ) {
Act_T2 = 1 ;
}
if ( TT2_AV < = TT2_Sp ) {
Act_T2 = 0 ;
}
if ( TKW_AV > = TKW_Sp + Hyst_Sp ) {
Act_KW = 1 ;
}
if ( TKW_AV < = TKW_Sp ) {
Act_KW = 0 ;
}
// Bypass Ventil schließen, wenn T1 oder T2 offen, delay 2s
if ( ( Act_T1 = = 1 | | Act_T2 = = 1 ) & & State_Bypass = = 0 ) {
State_Bypass = 1 ;
previousMillisBypass = currentMillis ;
}
if ( currentMillis - previousMillisBypass > = 2000 & & State_Bypass = = 1 ) {
digitalWrite ( 22 , HIGH ) ;
}
if ( Act_T1 = = 0 & & Act_T2 = = 0 ) {
digitalWrite ( 22 , LOW ) ;
State_Bypass = 0 ;
}
// Kühlung Tank 1, Ausschaltverzögerung 2s
if ( Act_T1 = = 1 ) {
digitalWrite ( 23 , HIGH ) ;
State_T1 = 1 ;
}
if ( Act_T1 = = 0 & & State_T1 = = 1 ) {
previousMillisT1 = currentMillis ;
State_T1 = 0 ;
}
if ( Act_T1 = = 0 & & State_T1 = = 0 & & currentMillis - previousMillisT1 > = 2000 ) {
previousMillisT1 = currentMillis ;
digitalWrite ( 23 , LOW ) ;
}
// Kühlung Tank 2, Ausschaltverzögerung 2s
if ( Act_T2 = = 1 ) {
digitalWrite ( 24 , HIGH ) ;
State_T2 = 1 ;
}
if ( Act_T2 = = 0 & & State_T2 = = 1 ) {
previousMillisT2 = currentMillis ;
State_T2 = 0 ;
}
if ( Act_T2 = = 0 & & State_T2 = = 0 & & currentMillis - previousMillisT2 > = 2000 ) {
previousMillisT2 = currentMillis ;
digitalWrite ( 24 , LOW ) ;
}
webserver ( ) ;
2023-08-25 13:45:14 +02:00
}
2023-08-28 23:15:14 +02:00
void webserver ( ) {
// server.available() schaut, ob ein Client verfügbar ist und Daten
// an den Server schicken möchte. Gibt dann eine Client-Objekt zurück,
// sonst false
EthernetClient client = server . available ( ) ;
2023-08-25 13:45:14 +02:00
// Wenn es einen Client gibt, dann...
if ( client ) {
Serial . println ( " Neuer Client " ) ;
// Jetzt solange Zeichen lesen, bis eine leere Zeile empfangen wurde
// HTTP Requests enden immer mit einer leeren Zeile
boolean currentLineIsBlank = true ;
// Solange Client verbunden
while ( client . connected ( ) ) {
// client.available() gibt die Anzahl der Zeichen zurück, die zum Lesen
// verfügbar sind
if ( client . available ( ) ) {
2023-08-28 23:15:14 +02:00
2023-08-25 13:45:14 +02:00
// Ein Zeichen lesen und am seriellen Monitor ausgeben
char c = client . read ( ) ;
2023-08-28 23:15:14 +02:00
if ( readString . length ( ) < 100 ) {
//store characters to string
readString + = c ;
//Serial.print(c);
}
2023-08-25 13:45:14 +02:00
// In currentLineIsBlank merken wir uns, ob diese Zeile bisher leer war.
// Wenn die Zeile leer ist und ein Zeilenwechsel (das \n) kommt,
// dann ist die Anfrage zu Ende und wir können antworten
if ( c = = ' \n ' & & currentLineIsBlank ) {
2023-08-28 23:15:14 +02:00
Serial . println ( readString ) ;
2023-08-29 10:03:58 +02:00
Serial . println ( TT1_Sp ) ;
Serial . println ( TT2_Sp ) ;
Serial . println ( TKW_Sp ) ;
Serial . println ( Hyst_Sp ) ;
2023-08-28 23:15:14 +02:00
// Wertänderung T 1
b_str = readString . indexOf ( " T1_Sp= " ) ;
e_str = readString . indexOf ( " HTTP/ " ) ;
t1_str = " " ;
if ( b_str ! = - 1 ) {
b_str = b_str + 6 ;
for ( int i = b_str ; i < e_str ; i + + ) {
t1_str + = readString . charAt ( i ) ;
t1_float = t1_str . toFloat ( ) ;
if ( t1_float ! = 0 ) {
TT1_Sp = t1_float ;
}
}
}
2023-08-29 10:03:58 +02:00
// Wertänderung T 2
2023-08-28 23:15:14 +02:00
b_str = readString . indexOf ( " T2_Sp= " ) ;
e_str = readString . indexOf ( " HTTP/ " ) ;
t2_str = " " ;
if ( b_str ! = - 1 ) {
b_str = b_str + 6 ;
for ( int i = b_str ; i < e_str ; i + + ) {
t2_str + = readString . charAt ( i ) ;
t2_float = t2_str . toFloat ( ) ;
if ( t2_float ! = 0 ) {
TT2_Sp = t2_float ;
}
}
}
2023-08-29 10:03:58 +02:00
// Wertänderung EEPROM schreiben
b_str = readString . indexOf ( " EEPROM= " ) ;
if ( b_str ! = - 1 ) {
EEPROM . get ( 0 , H_TT1_Sp ) ;
EEPROM . get ( 4 , H_TT2_Sp ) ;
EEPROM . get ( 8 , H_TKW_Sp ) ;
EEPROM . get ( 12 , H_Hyst_Sp ) ;
if ( H_TT1_Sp ! = TT1_Sp ) {
EEPROM . put ( 0 , TT1_Sp ) ;
}
if ( H_TT2_Sp ! = TT2_Sp ) {
EEPROM . put ( 4 , TT2_Sp ) ;
}
if ( H_TKW_Sp ! = TKW_Sp ) {
EEPROM . put ( 8 , TT1_Sp ) ;
}
if ( H_Hyst_Sp ! = Hyst_Sp ) {
EEPROM . put ( 12 , Hyst_Sp ) ;
}
}
2023-08-28 23:15:14 +02:00
// HTTP Header 200 an den Browser schicken
client . println ( " HTTP/1.1 200 OK " ) ;
2023-08-25 13:45:14 +02:00
client . println ( " Content-Type: text/html " ) ;
client . println ( " Connection: close " ) ; // Verbindung wird nach Antwort beendet
2023-08-28 23:15:14 +02:00
client . println ( " Refresh: 60 " ) ; // Seite alle 60 Sekunden neu abfragen
2023-08-25 13:45:14 +02:00
client . println ( ) ;
// Ab hier berginnt der HTML-Code, der an den Browser geschickt wird
client . println ( " <!DOCTYPE HTML> " ) ;
client . println ( " <html> " ) ;
2023-08-28 23:15:14 +02:00
client . println ( " <head><title>Temperatursteuerung</title></head> " ) ;
client . println ( " <body><h3>Temperatursteuerung</h3> " ) ;
2023-09-04 12:43:47 +02:00
client . println ( " <svg width= \" 45 \" height= \" 52 \" > " ) ;
2023-08-28 23:15:14 +02:00
client . println ( " <path " ) ;
client . println ( " style= \" fill:#000000;stroke-width:0.0282222 \" " ) ;
client . println ( " d= \" m 19.642666,46.637223 v -2.441222 h 2.441222 2.441223 v 2.441222 2.441222 H 22.083888 19.642666 Z M 14.722747,44.17734 c -0.01043,-0.01043 -0.01897,-1.115402 -0.01897,-2.455489 V 39.285334 H 12.248444 9.793111 V 36.83 34.374667 H 7.351889 4.910667 V 29.464 24.553334 H 2.455334 0 V 19.642667 14.732 H 2.455334 4.910667 V 12.290778 9.8495558 H 7.366 9.821334 V 12.290778 14.732 H 7.366 4.910667 v 4.910667 4.910667 H 7.351889 9.793111 V 22.098 19.642667 h 2.455177 2.455178 l 0.0072,-2.448278 0.0072,-2.448278 2.462388,-0.0072 2.462389,-0.0072 v 4.910822 4.910822 h 2.441222 2.441223 v 2.441067 2.441067 l 2.462388,0.0072 2.462391,0.0072 0.007,2.462389 0.007,2.462389 h 2.44107 2.44106 V 29.464 24.553334 h -4.89651 -4.896554 V 19.642667 14.732 h 2.455333 2.455331 v 2.455334 2.455333 h 2.45534 2.45533 V 22.098 24.553334 h 2.45533 2.45534 V 19.642667 14.732 h -2.45534 -2.45533 V 12.276667 9.8213338 h -4.91082 -4.910826 l 0.0072,-2.448278 0.0072,-2.448278 4.903616,-0.0071 4.90361,-0.0071 v 2.455413 2.455413 h 2.45533 2.45533 v 2.4553332 2.455333 h 2.45534 2.45533 v 4.910667 4.910667 h -2.45523 -2.45526 l -0.007,4.903611 -0.007,4.903611 -2.46238,0.0072 -2.46239,0.0072 v 2.455178 2.455178 h -2.44114 -2.44107 l -0.007,2.448278 -0.007,2.448277 h -2.45553 -2.455333 l -0.0071,-4.903611 -0.0071,-4.903611 H 22.08398 19.642917 l -0.0071,4.903611 -0.0071,4.903611 -2.443419,0.0072 c -1.343881,0.004 -2.451956,-0.0013 -2.462389,-0.01176 z m -0.01207,-12.265062 0.0072,-2.462389 2.462388,-0.0072 2.462389,-0.0072 V 26.994401 24.553334 H 14.717889 9.793111 V 29.464 34.374667 h 2.455178 2.455179 z M 12.283722,9.8283908 9.821334,9.8209908 V 7.3658118 4.9106338 H 14.732 19.642666 V 2.4553334 0 h 2.441222 2.441223 v 2.4553334 2.4553334 h -2.441223 -2.441222 v 2.469444 2.469445 l -2.448278,-0.0069 c -1.346552,-0.0038 -3.556352,-0.01021 -4.910666,-0.01427 z \" " ) ;
client . println ( " id= \" path903 \" /> " ) ;
client . println ( " </svg> " ) ;
client . print ( " <table> " ) ;
client . print ( " <tr> " ) ;
client . print ( " <th> </th> " ) ;
client . print ( " <th> Istwert </th> " ) ;
client . print ( " <th> Sollwert </th> " ) ;
client . print ( " </tr> " ) ;
client . print ( " <tr> " ) ;
client . print ( " <td>Tank 1</td> " ) ;
if ( State_T1 = = 1 ) {
client . print ( " <td bgcolor=#00FF00> " ) ; client . print ( TT1_AV ) ; client . print ( " °C</td> " ) ;
}
else {
client . print ( " <td> " ) ; client . print ( TT1_AV ) ; client . print ( " °C</td> " ) ;
}
client . print ( " <td> " ) ; client . print ( TT1_Sp ) ; client . print ( " °C</td> " ) ;
client . print ( " <td> " ) ;
client . print ( " <form action= \" / \" method= \" get \" > " ) ;
client . print ( " <label for= \" fname \" >Setpoint</label> " ) ;
client . print ( " <input type= \" text \" id= \" T1_Sp \" name= \" T1_Sp \" > " ) ;
client . print ( " <input type= \" submit \" value= \" Submit \" > " ) ;
client . print ( " </form> " ) ;
client . print ( " </td> " ) ;
client . print ( " </tr> " ) ;
client . print ( " <tr> " ) ;
client . print ( " <td>Tank 2</td> " ) ;
if ( State_T2 = = 1 ) {
client . print ( " <td bgcolor=#00FF00> " ) ; client . print ( TT2_AV ) ; client . print ( " °C</td> " ) ;
}
else {
client . print ( " <td> " ) ; client . print ( TT2_AV ) ; client . print ( " °C</td> " ) ;
}
client . print ( " <td> " ) ; client . print ( TT2_Sp ) ; client . print ( " °C</td> " ) ;
client . print ( " <td> " ) ;
client . print ( " <form action= \" / \" method= \" get \" > " ) ;
client . print ( " <label for= \" fname \" >Setpoint</label> " ) ;
client . print ( " <input type= \" text \" id= \" T2_Sp \" name= \" T2_Sp \" > " ) ;
client . print ( " <input type= \" submit \" value= \" Submit \" > " ) ;
client . print ( " </form> " ) ;
client . print ( " </td> " ) ;
client . print ( " </tr> " ) ;
2023-08-29 10:03:58 +02:00
client . print ( " <tr> " ) ;
2023-08-28 23:15:14 +02:00
client . print ( " <td>Bypass</td> " ) ;
if ( State_Bypass = = 0 ) {
client . print ( " <td bgcolor=#00FF00></td> " ) ;
}
else {
client . print ( " <td></td> " ) ;
}
client . print ( " <td></td> " ) ;
client . print ( " <td></td> " ) ;
client . print ( " </tr> " ) ;
2023-08-29 10:03:58 +02:00
client . print ( " <tr> " ) ;
2023-09-04 12:43:47 +02:00
client . print ( " <td colspan= \" 4 \" >EEPROM " ) ;
client . print ( " T1 " ) ; client . print ( H_TT1_Sp ) ; client . print ( " °C " ) ;
client . print ( " T2 " ) ; client . print ( H_TT2_Sp ) ; client . print ( " °C " ) ;
client . print ( " KW " ) ; client . print ( H_TKW_Sp ) ; client . print ( " °C " ) ;
client . print ( " Hyst " ) ; client . print ( H_Hyst_Sp ) ; client . print ( " °C " ) ;
client . print ( " </td><td> " ) ;
2023-08-29 10:03:58 +02:00
client . print ( " <form action= \" / \" method= \" get \" > " ) ;
client . print ( " <input id= \" EEPROM \" name= \" EEPROM \" type= \" submit \" value= \" Submit \" > " ) ;
client . print ( " </form> " ) ;
client . print ( " </td> " ) ;
client . print ( " </tr> " ) ;
2023-08-28 23:15:14 +02:00
client . print ( " </table> " ) ;
client . println ( " </body></html> " ) ;
2023-08-25 13:45:14 +02:00
break ;
}
if ( c = = ' \n ' ) {
// Zeilenwechsel, also currentLineIsBlack erstmal auf True setzen
currentLineIsBlank = true ;
}
else if ( c ! = ' \r ' ) {
// Zeile enthält Zeichen, also currentLineIsBlack auf False setzen
currentLineIsBlank = false ;
}
}
}
// Kleine Pause
delay ( 1 ) ;
// Verbindung schliessen
client . stop ( ) ;
2023-08-28 23:15:14 +02:00
//clearing string for next read
readString = " " ;
2023-08-25 13:45:14 +02:00
Serial . println ( " Verbindung mit Client beendet. " ) ;
Serial . println ( " " ) ;
}
}