374 lines
12 KiB
C++
374 lines
12 KiB
C++
// First we include the libraries
|
|
#include <OneWire.h>
|
|
#include <DallasTemperature.h>
|
|
#include <Controllino.h>
|
|
#include <SPI.h>
|
|
#include <Ethernet.h>
|
|
#include <EEPROM.h>
|
|
|
|
|
|
/********************************************************************/
|
|
// Data wire is plugged into pin 2 on the Arduino
|
|
#define ONE_WIRE_BUS 2
|
|
#define TEMPERATURE_PRECISION 11
|
|
|
|
/********************************************************************/
|
|
// 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);
|
|
/********************************************************************/
|
|
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;
|
|
// Hilfswerte für EEPROM schreiben
|
|
float H_TT1_Sp;
|
|
float H_TT2_Sp;
|
|
float H_TKW_Sp;
|
|
float H_Hyst_Sp;
|
|
|
|
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
|
|
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x09, 0x70 };
|
|
IPAddress ip(192,168,8,57);
|
|
EthernetServer server(80);
|
|
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);
|
|
|
|
// Ethernet Verbindung und Server starten
|
|
Ethernet.begin(mac, ip);
|
|
server.begin();
|
|
Serial.print("Server gestartet. IP: ");
|
|
// IP des Arduino-Servers ausgeben
|
|
Serial.println(Ethernet.localIP());
|
|
|
|
// 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;
|
|
}
|
|
|
|
void loop(void)
|
|
{
|
|
// Versorge Zeit
|
|
unsigned long currentMillis = millis();
|
|
|
|
// 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();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
// 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()) {
|
|
|
|
// Ein Zeichen lesen und am seriellen Monitor ausgeben
|
|
char c = client.read();
|
|
if (readString.length() < 100) {
|
|
|
|
//store characters to string
|
|
readString += c;
|
|
//Serial.print(c);
|
|
}
|
|
|
|
// 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) {
|
|
Serial.println(readString);
|
|
|
|
|
|
Serial.println(TT1_Sp);
|
|
Serial.println(TT2_Sp);
|
|
Serial.println(TKW_Sp);
|
|
Serial.println(Hyst_Sp);
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
// Wertänderung T 2
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
// HTTP Header 200 an den Browser schicken
|
|
client.println("HTTP/1.1 200 OK");
|
|
client.println("Content-Type: text/html");
|
|
client.println("Connection: close"); // Verbindung wird nach Antwort beendet
|
|
client.println("Refresh: 60"); // Seite alle 60 Sekunden neu abfragen
|
|
client.println();
|
|
// Ab hier berginnt der HTML-Code, der an den Browser geschickt wird
|
|
client.println("<!DOCTYPE HTML>");
|
|
client.println("<html>");
|
|
client.println("<head><title>Temperatursteuerung</title></head>");
|
|
client.println("<body><h3>Temperatursteuerung</h3>");
|
|
|
|
client.println("<svg width=\"45\" height=\"52\">");
|
|
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>");
|
|
client.print(" <tr>");
|
|
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>");
|
|
client.print(" <tr>");
|
|
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>");
|
|
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>");
|
|
client.print("</table>");
|
|
client.println("</body></html>");
|
|
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();
|
|
//clearing string for next read
|
|
readString="";
|
|
Serial.println("Verbindung mit Client beendet.");
|
|
Serial.println("");
|
|
}
|
|
}
|