/*******************************************************************************************
 *******************************************************************************************
 **                                www.bastelgarage.ch                                    **
 ** Der Onlineshop mit Videoanleitungen und kompletten Bausätzen für Anfänger und Profis! **
 *******************************************************************************************
 *******************************************************************************************
 ** In diesem Beispiel zeigen wir dir wie du ein LCD Display mit dem ESP8266              **
 ** Mikrocontroller ansteuern kannst. für die Ansteuerung nutzen wir ein I2C Adapter der  **
 ** auf das Display montiert wird. Somit kann das Display über die I2c Adresse 0x27       **
 ** angesprochen werden. Da wir in diesem Beispiel ein 5V Display einsetzen und der       **
 ** ESP8266 auf 3.3V läuft ist noch ein Logic Level Converter notwendig der die           **
 ** 3.3V auf 5V konvertiert. Der SI7021 ist ein Luftfeuchtigkeitssensor der die Relative  **
 ** Luftfeuchtigkeit und Temperatur misst. Da es sich beim SI7021 um ein 3.3V Sensor      **
 ** handelt muss er auf der 3.3V Seite des Logic Level Converter angeschlossen werden.    **
 ** in diesem Beispiel wollen wir lernen wie man Benutzerdefinierte Symbole auf dem       **
 ** Display darstellen kann. Wir wollen auch die Luftfeuchtigkeit und Temperatur aus dem  **
 ** Si7021 auslesen und auf dem Display darstellen.                                       **
 **                                                                                       **
 ** Autor: Philippe Keller                                                                **
 ** Datum: August 2016                                                                    **
 ** Version: 1.0                                                                          **
 * *****************************************************************************************
*/

/************************( Importieren der genutzten Bibliotheken )************************/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SI7021.h>

/********************( Definieren der Globale Variablen und Konstanten)********************/
float t;                                      // Variable zum speichern der Temperatur
float h;                                      // Variable zum speichern der Luftfeuchtigkeit

long SensorenLetzteAktualisierung;            // Hilfsvariable für Zeitmessung
int SensorenSampelTime = 1000;                // Zeit in ms für Aktualisierung der
                                              // Sensordaten und Display

/********************************( Definieren der Objekte )********************************/
// Einstellen der I2C Adresse des Displays auf 0x27 für
// Character Display mit zwei Linien und 16 Zeichen (PCF8574T I2C Adapter)

// LiquidCrystal_I2C lcd(0x3F, 16, 2); //I2c Adapter mit PCF8574AT(ohne Brücken auf 0,A1,A2)
LiquidCrystal_I2C lcd(0x27, 16, 2); //I2c Adapter mit PCF8574T(ohne Brücken auf 0,A1,A2)

SI7021 SI7021_Sensor;                                // Si7021 Initialisieren 

/******************************( Definieren der LCD Symbolen )*****************************/
byte thermometer[8] = //Icon für Thermometer
{
  B00100,
  B01010,
  B01010,
  B01110,
  B01110,
  B11111,
  B11111,
  B01110
};

byte tropfen[8] = //Icon für Wassertropf
{
  B00100,
  B00100,
  B01010,
  B01010,
  B10001,
  B10001,
  B10001,
  B01110,
};



void setup() {
  Wire.begin(D2, D1);         // Festlegen der I2c Pins und initialisieren (4,5 oder D2,D1)
  lcd.begin();                // LCD Initialisieren
  lcd.backlight();            // LCD Hintergrundbeleuchtung ein
  lcd.clear();                // LCD Anzeige Löschen

  lcd.setCursor(0, 0);           // Cursor auf das erste Zeichen auf der ersten Zeile setzen.
  lcd.print("Bastelgarage.ch");  // Text schreiben maximal 16 Zeichen lang
  delay(3000);                   // Wartezeit in ms (3 Sekunden warten)


  lcd.createChar(1, thermometer); //BenutzerdefiniertesThermometersymbol auf LCD Speichern
  lcd.createChar(2, tropfen);     //BenutzerdefiniertesWassertropfensymbol auf LCD Speichern
}


/***********************(Funktion um Daten auf das LCD zu Schreiben)***********************/
void lcdSchreiben() {

  // Zuerst wird der Cursor auf dem LCD Display da gesetzt wo etwas geschrieben werden soll.
  // Dazu wird der Befehl lcd.SetCursor(0,0) genutzt.
  // lcd.SetCursor(X,Y)
  // Bei X wird die Position in der Zeile gewählt in unserem Beispiel mit 0 ist es die erste Position
  // ganz der Zeile also das erste Zeichen.
  // Bei Y wird die Zeile angewählt. in unserem Beispiel ist es eine 0 also die erste Zeile.

  lcd.setCursor(0, 0);           // Cursor auf das erste Zeichen auf der ersten Zeile setzen.
  lcd.print("Bastelgarage.ch");  // Text schreiben maximal 16 Zeichen lang

  lcd.setCursor(0, 1);           // Cursor auf die zweite Zeile setzen
  lcd.write(1);                  // BenutzerdefiniertesThermometersymbol auf LCD schreiben
  lcd.setCursor(2, 1);
  lcd.print(t, 1);               // Temperatur aus Variable t auf LCD schreiben
                                 // mit einer nachkomastelle
  lcd.print((char)223);          // Gradzeichen auf LCD schreiben 
  lcd.print("C");
  lcd.setCursor(10, 1);
  lcd.write(2);                  // BenutzerdefiniertesWassertropfensymbol auf LCD schreiben
  lcd.setCursor(12, 1);
  lcd.print(h, 0);               // Relative Luftfeuchtigkeit aus Variabel h auf LCD schreiben
  lcd.print("%");

}

/***********************(Hauptprogramm)***********************/
void loop() {

// Mit der Funktion millis() wird die vergangene Zeit in ms zurückgegeben. Wir vergleichen diesen
// Wert mit der letzten Sensor Aktualisierung ist mehr Zeit vergangen als in der Variable 
// ensorenSampelTime steht wird die if abzweigung ausgeführt und sonst nicht. Wir könnten das auch
// mit einer delay() Funktion lösen jedoch möchten wir das der Mikrocontroller nicht einfach
// stehen bleibt, sondern weiter arbeiten kann.

  if (millis() - SensorenLetzteAktualisierung > SensorenSampelTime) {

    t = SI7021_Sensor.getCelsiusHundredths() / 100.0; // Temperatur aus SI7021 auslesen 
                                                      // und in Variable t speichern
                                                      
    h = SI7021_Sensor.getHumidityPercent();           // Luftfeuchtigkeit aus Si7021 auslesen
                                                      // und in Variable h speichern
    SensorenLetzteAktualisierung = millis();                                              
    lcdSchreiben();                                   // Funktion zum schreiben vom LCD Aufrufen
  }
}
