#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
/*// Pindefinitionen für das Display
const int RS= 8;
const int EN= 9;
const int DB7= 7;
const int DB6= 6;
const int DB5= 5;
const int DB4= 4;
const int LED= 10;
*/
// Pin für die Temperatursensoren
const int One_Wire_Bus = 4;
// Variablen für Auswertung der Tasten
const int AnalogPin=13;
const int dec=-1;
const int inc=1;
const int Tasterrechts= inc;
const int Tasteroben= 1;
const int Tasterunten= 2;
const int Tasterlinks= dec;
const int Tasterselect= 4;
const int KeinTaster= 5;
// --Displayzustände--
// Definition der Zustände
const byte Z_Statusanzeige = 0;
const byte Z_SetPoolSoll = 1;
const byte Z_SetHystereseEin = 2;
const byte Z_SetHystereseAus = 3;
// Zustandsvaiable
byte Display = Z_Statusanzeige;
// --Betriebszustände--
// Definition der Zustände
const byte Z_Aus=0;
const byte Z_Umwaelzen=1;
const byte Z_Solarbetrieb=2;
// Zustandsvaiablen
byte PumpeVentil=Z_Aus; //PumpeVentilAlt=Z_Aus;
// Werte für bestimmte Zeichen im Display
const unsigned char Pfeillinks=127,Pfeilrechts=126,CharGrad=223;
// --Variablen für die Temperaturen--
// Sensortemperaturen
float PoolIst=0, SolarIst=0;
// SOLL, SOLLMAX und SOLLMIN-Werte für die Pooltemperatur
float PoolSoll=29.5, PoolSollMax=32 , PoolSollMin=20;
// Ein- bzw. Ausschalthysterese für Solarbetrieb
int HystereseEin=6, HystereseEinMin=0, HystereseEinMax=9;
int HystereseAus=2, HystereseAusMin=0, HystereseAusMax=8;
// Einige Merker
bool zustandwechsel=false, wertwechsel=false, TempAenderung=false;
// --Variablen für die Timer--
const byte stop=0, start=1, laeuft=2;
// Displaytimer
const int DisplayTimeoutZeit = 5 *1000; // nach X Sekunden (*Millisekunden) ohne Tastendruck soll das Display wieder auf Statusanzeige schalten
bool DisplayTimeout=false;
byte DisplayTimer=stop;
// Solarsteuerung
const int SolarEinWartezeit= 10000, SolarAusWartezeit= 10000; // X Minuten*Millisekunden
bool SolarEinTimeout=false, SolarAusTimeout=false;
byte SolarEinTimer=stop, SolarAusTimer=stop;
// Ablesung Temperaturwerte
unsigned long letzteAblesung= 0, AbleseFrequenz=3*1000;
// Erzeugen der Objekte für Display und Temperatursensoren
LiquidCrystal_I2C lcd(0x27, 16, 2);
OneWire oneWire(One_Wire_Bus);
DallasTemperature sensors(&oneWire);
void SolarbetriebEin (void){
PumpeVentil=Z_Solarbetrieb;
}
void SolarbetriebAus (void){
PumpeVentil=Z_Aus;
}
void UpdateTimer (void){
TimerDisplay();
TimerSolarEin();
TimerSolarAus();
}
// Prüft ob min<=wert>=max
bool imBereich(float wert, float min, float max){
if((wert-min)*(wert-max) <= 0) return true;
return false;
}
void TimerSolarEin(){
static unsigned long startmillis= 0;
if (SolarEinTimer==start){ //
startmillis=millis();
SolarEinTimer=laeuft;
SolarEinTimeout=false;
Serial.print("SolarEinTimer gestartet " );
Serial.println(SolarEinTimer);
}
if (SolarEinTimer==laeuft){
if ((millis()-startmillis) > SolarEinWartezeit){
SolarEinTimeout=true;
Serial.print("SolarEinTimer abgelaufen " );
Serial.println(SolarEinTimer, SolarEinTimeout);
}
}
}
void TimerSolarAus(){
static unsigned long startmillis= 0;
if (SolarAusTimer==start){ //
startmillis=millis();
SolarAusTimer=laeuft;
SolarAusTimeout=false;
Serial.print("SolarAusTimer gestartet " );
Serial.println(SolarAusTimer);
}
if (SolarAusTimer==laeuft){
if ((millis()-startmillis) > SolarAusWartezeit){
SolarAusTimeout=true;
Serial.print("SolarAusTimer abgelaufen " );
Serial.println(SolarAusTimer, SolarAusTimeout);
}
}
}
void TimerDisplay (){
static unsigned long startmillis= 0;
if (DisplayTimer==start){
Serial.println("Starte Displaytimer");
startmillis=millis();
DisplayTimer=laeuft;
}
if (DisplayTimer==laeuft){
if (millis()-startmillis > DisplayTimeoutZeit){
DisplayTimeout=true;
DisplayTimer=stop;
}
}
}
void HoleTemperaturen()
{
static unsigned long letzteAblesung=0;
static float PoolIstAlt=0, SolarIstAlt=0;
static bool firstrun=true;
TempAenderung=false;
if ((millis() - letzteAblesung > AbleseFrequenz)||firstrun)
{
firstrun=false;
sensors.requestTemperatures();
letzteAblesung = millis();
PoolIstAlt=PoolIst;
SolarIstAlt=SolarIst;
PoolIst=(float)(round(sensors.getTempCByIndex(0)*10))/10; // Runden der Temperaturen auf
SolarIst=(float)(round(sensors.getTempCByIndex(1)*10))/10; // eine Nachkommastelle
/*Serial.print("Pool: ");
Serial.print(PoolIst);
Serial.print(" Solar: ");
Serial.println(SolarIst);*/
if(PoolIst!=PoolIstAlt||SolarIst!=SolarIstAlt){
TempAenderung=true;
Serial.println("Tempänderung!!");
}
}
}
int Holetaster()
{
short Taster=KeinTaster, Analogwert = 0;
static short Tastermerker=KeinTaster;
Analogwert = analogRead(AnalogPin); // Auslesen der Taster am Analogen Pin A0.
if (Analogwert > 1000) Taster=Tastermerker=KeinTaster; //Auswerten des gedrückten Tasters
else if (Analogwert < 50) Taster= Tasterrechts;
else if (Analogwert < 300) Taster= Tasteroben;
else if (Analogwert < 500) Taster= Tasterunten;
else if (Analogwert < 700) Taster= Tasterlinks;
else if (Analogwert < 900) Taster= Tasterselect;
else Taster= KeinTaster; // Default = kein Taster gedrückt.
if (Taster!=KeinTaster&&Tastermerker==KeinTaster)//Entprellen des Tasters, gedrückte Taster erst nach loslassen
{
Tastermerker=Taster;
return Taster;
}
return KeinTaster; // Ausgabe wenn kein Taster gedrückt wurde.
}
void SteuerungDisplay(int Taster){
if (DisplayTimeout){
Statusanzeige();
DisplayTimeout=false;
}
if (TempAenderung&&Display==Z_Statusanzeige){
Statusanzeige();
}
if (Taster==Tasterselect)
{
zustandwechsel=true;
DisplayTimer=start;
TimerDisplay();
switch(Display){
case Z_Statusanzeige: SetPoolSoll(NULL); break;
case Z_SetPoolSoll: SetHystereseEin(NULL); break;
case Z_SetHystereseEin: SetHystereseAus(NULL); break;
case Z_SetHystereseAus: Statusanzeige(); break;
//case Z_Statusanzeige: Z_SetPoolSoll(); break;
}
}
if (Taster==Tasterlinks||Taster==Tasterrechts){
wertwechsel=true;
DisplayTimer=start;
TimerDisplay();
switch(Display){
case Z_Statusanzeige: break;
case Z_SetPoolSoll: SetPoolSoll(Taster); break;
case Z_SetHystereseEin: SetHystereseEin(Taster); break;
case Z_SetHystereseAus: SetHystereseAus(Taster); break;
//case Z_Statusanzeige: Z_SetPoolSoll(); break;
}
}
}
void SteuerungPumpeVentil(){
//Serial.println("SteuerungPumpeVentil");
if (PoolIst>=PoolSoll){//gewünschte Temperatur erreicht
Serial.println("PoolSoll OK, alles aus!");
SolarEinTimer=stop; // alle Timer stoppen
SolarAusTimer=stop;
SolarEinTimeout=false;
SolarAusTimeout=false;
if (PumpeVentil=Z_Solarbetrieb){
SolarbetriebAus();
//Umwaelzen();????
}
return;
}
switch (PumpeVentil){
case Z_Aus:
case Z_Umwaelzen:{
if (SolarEinTimer==stop &&((SolarIst-PoolIst)>=HystereseEin)){
//PumpeVentilAlt=PumpeVentil; //Speichern des Zustands
SolarEinTimer=start;
Serial.println("Starte SolarEinTimer" );
TimerSolarEin();
break;
}
if ((SolarEinTimer==laeuft)&&((SolarIst-PoolIst) < HystereseEin)){
SolarEinTimer=stop;
Serial.println("Stoppe SolarEinTimer" );
//PumpeVentil=PumpeVentilAlt; //Wiederherstellen des vorherigen Zustands Z_Aus oder Z_Umwaelzen
break;
}
if (SolarEinTimeout){
Serial.println("Solarbetrieb Ein!" );
SolarEinTimer=stop;
SolarEinTimeout=false;
SolarbetriebEin();
break;
}
break;
}
case Z_Solarbetrieb: {
if (SolarAusTimer==stop&&((SolarIst-PoolIst)<=HystereseAus)){
SolarAusTimer=start;
Serial.println("Starte SolarAusTimer" );
TimerSolarAus();
break;
}
if (SolarAusTimer==laeuft&&((SolarIst-PoolIst) > HystereseAus)){
SolarAusTimer=stop;
Serial.println("Stoppe SolarAusTimer" );
break;
}
if (SolarAusTimeout){
Serial.println("Solarbetrieb Aus!" );
SolarAusTimer=stop;
SolarAusTimeout=false;
SolarbetriebAus();
break;
}
break;
}
}
}
void Statusanzeige()
{
char strPoolIst[7],strSolarIst[7],Zeile2[16];
dtostrf(PoolIst, 4, 1,strPoolIst); // Umwandeln der Temperaturen von floats in strings
dtostrf(SolarIst, 4, 1,strSolarIst); // zu Anzeige nur einer Nachkommastelle
//sprintf(Zeile2,"%s%cC %s%cC",strPoolIst,CharGrad,strSolarIst,CharGrad);
//sprintf(Zeile2,"%s*C %s*C",strPoolIst,strSolarIst);
lcd.setCursor(0,0);
lcd.print(F(" Pool Solar "));
lcd.setCursor(0,1);
lcd.print(strPoolIst);
lcd.write(CharGrad);
lcd.print("C ");
lcd.print(strSolarIst);
lcd.write(CharGrad);
lcd.print("C");
//lcd.print(Zeile2);
Serial.println(F("Display=Statusanzeige"));
Display=Z_Statusanzeige;
}
void SetPoolSoll(int incdec)
{
//char strPoolSoll[7],Zeile2[16];
char strPoolSoll[7],Zeile2[17];
//Wert nur verändern, wenn Min-und Max Grenzen eingehalten werden
if (imBereich(PoolSoll+incdec*0.5,PoolSollMin,PoolSollMax))
PoolSoll+=incdec*0.5;
dtostrf(PoolSoll, 4, 1,strPoolSoll);
if (zustandwechsel){
lcd.setCursor(0,0);
lcd.print(" Pool SOLL: ");
}
if (zustandwechsel||wertwechsel){
lcd.setCursor(0,1);
sprintf(Zeile2,"-%c %s%cC %c+",Pfeillinks,strPoolSoll,CharGrad,Pfeilrechts);
lcd.print(Zeile2);
zustandwechsel=false;
wertwechsel=false;
}
Display=Z_SetPoolSoll;
}
void SetHystereseEin(int incdec)
{
if (imBereich(HystereseEin+incdec,HystereseEinMin,HystereseEinMax))
HystereseEin+=incdec;
if (zustandwechsel){
lcd.setCursor(0,0);
lcd.print(" EIN Hysterese: ");
}
if (zustandwechsel||wertwechsel){
char Zeile2[16];
lcd.setCursor(0,1);
sprintf(Zeile2,"-%c %d%cC %c+",Pfeillinks,HystereseEin,CharGrad,Pfeilrechts);
lcd.print(Zeile2);
zustandwechsel=false;
wertwechsel=false;
}
Display=Z_SetHystereseEin;
}
void SetHystereseAus(int incdec)
{
if (imBereich(HystereseAus+incdec,HystereseAusMin,HystereseAusMax))
HystereseAus+=incdec;
if (zustandwechsel){
lcd.setCursor(0,0);
lcd.print(" AUS Hysterese: ");
}
if (zustandwechsel||wertwechsel){
char Zeile2[16];
lcd.setCursor(0,1);
sprintf(Zeile2,"-%c %d%cC %c+",Pfeillinks,HystereseAus,CharGrad,Pfeilrechts);
lcd.print(Zeile2);
zustandwechsel=false;
wertwechsel=false;
}
Display=Z_SetHystereseAus;
}
void setup()
{
Serial.begin(115200); //seriellen Monitor aktivieren
Serial.println(F("Start..."));
//pinMode(10, OUTPUT);
//digitalWrite(10, HIGH); // Beleuchtung für das LCD einschalten
//lcd.begin(16, 2); // Starten der Programmbibliothek für das Display
analogReadResolution(10);
lcd.init(); //Im Setup wird der LCD gestartet
lcd.backlight(); //Hintergrundbeleuchtung einschalten (lcd.noBacklight(); schaltet die Beleuchtung aus).
sensors.begin(); // Starten der Programmbibliothek für das Temperatursensoren
sensors.setWaitForConversion(false); //Ablesung der Sensoren asynchron
}
void loop()
{
int Taster;
HoleTemperaturen();
Taster = Holetaster(); // Abfrage der Taster
SteuerungDisplay(Taster);
SteuerungPumpeVentil();
UpdateTimer();
}