#include <EEPROM.h>                 //Bibliothek zum Speichern, auch wenn Spannung verloren geht
#include <EtherCard.h>              //Bibliothek für das Internet-Shield
#include <ModbusIP_ENC28J60.h>      //Bibliothek für das Internet-Shield und die Kommunikation zu SPS
#include <Modbus.h>                 //Bibliothek für die Kommunikation zur SPS

#define EESIZE 1024;              //Größe vom EEPROM-Speicher

const int SENSOR_IREG1 = 100;      //Modbus Register Datenpunkt 1
const int SENSOR_IREG2 = 101;      //Modbus Register Datenpunkt 2
const int SENSOR_IREG3 = 102;      //Modbus Register Datenpunkt 3
const int SENSOR_IREG4 = 103;      //Modbus Register Datenpunkt 4
const int SENSOR_IREG5 = 104;      //Modbus Register Datenpunkt 5
const int SENSOR_IREG6 = 105;      //Modbus Register Datenpunkt 6
ModbusIP mb;                       //ModbusIP Objekt 

const int TASTER = 6;              //Pin für den Taster
int tasterStatus = 0;              //Variable für den Taster Status
const int LED = 3;                 //Pin für LED

//Referenzsensor
const int REFERENZSENSOR = A0;      //Pin des Auto Referenzsensors
int bitwertNTC_1 = 0;               //Variable für Bitwerte des analogen Eingangs
double Untc_1 = 0;                  //Variable Spannung über NTC-Sensor
double Uwiderstand_1 = 0;           //Variable Spannung über Referenzwiderstand;
double strom_1 = 0;                 //Variable Strom durch Sensor
double ntcwiderstand_1 = 0;         //Variable Widerstand vom NTC
const double WIDERSTAND_1 = 1950;   //Wert des Referenzwiderstandes
double temperatur_1 = 0.0;          //Variable Temperatur vom NTC

//Prüfsensor
const int PRUEFSENSOR = A2;          //Pin des Auto Prüfsensors
int bitwertNTC_2 = 0;               //Variable für Bitwerte des analogen Eingangs
double Untc_2 = 0;                  //Variable Spannung über NTC-Sensor
double Uwiderstand_2 = 0;           //Variable Spannung über Referenzwiderstand;
double strom_2 = 0;                 //Variable Strom durch Sensor
double ntcwiderstand_2 = 0;         //Variable Widerstand vom NTC
const double WIDERSTAND_2 = 1970;   //Wert des Referenzwiderstandes
double temperatur_2 = 0.0;          //Variable Temperatur vom NTC

int funktion_Sensor = 0;            //Variable für ordnungsgemäße Funktion des Prüfsensors
int id = 0;                         //Variable für id vom Prüfsensor

long ts;                          //Zeitvariable  

void setup() 
{
    Serial.begin(9600);             //Ausgabe-Fenster starten
    
    pinMode(TASTER, INPUT);                     //Taster-Pin als Eingang definieren
    tasterStatus = digitalRead(TASTER);         //Lesen des Taster Status
    pinMode(LED, OUTPUT);                       //LED-Pin als Ausgang definieren
    digitalWrite(LED, LOW);                     //LED Ausgangszustand auf AUS
    
    byte mac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };     //MAC-Adresse Arduino
    byte ip[] = { 172, 30, 50, 23 };                   //IP-Adresse Arduino - AN NETZWERK ANPASSEN !!!!
    
    mb.config(mac, ip);                 //Modbus Konfiguration mit MAC und IP
    mb.addIreg(SENSOR_IREG1);           //Datebpunkt 1 dem Modbus hinzufügen
    mb.addIreg(SENSOR_IREG2);           //Datebpunkt 2 dem Modbus hinzufügen
    mb.addIreg(SENSOR_IREG3);           //Datebpunkt 3 dem Modbus hinzufügen
    mb.addIreg(SENSOR_IREG4);           //Datebpunkt 4 dem Modbus hinzufügen
    mb.addIreg(SENSOR_IREG5);           //Datebpunkt 5 dem Modbus hinzufügen
    mb.addIreg(SENSOR_IREG6);           //Datebpunkt 6 dem Modbus hinzufügen
    
    ts = millis();                //Zeit bis Programmstart ermitteln
}

void loop() 
{
   mb.task();         //Modbus starten, jedoch nur einmal ausführen!!!

   if (millis() > ts + 500)        //beginnt alle halbe Sekunde mit dieser Schleife
   {
      tasterStatus = digitalRead(TASTER);           //Taster Status lesen

      //Auswerten Referenzsensor
      bitwertNTC_1 = analogRead(REFERENZSENSOR);                  //Analog-Pin Referenzsensor auslesen
      Untc_1 = (double)bitwertNTC_1 * 0.00487;                    //Umwandlung Bitwerte von A0 in Spannung über Referenz-NTC
      Uwiderstand_1 = 5 - Untc_1;                                 //Berechnung Spannung über Referenzwiderstand
      strom_1 = Uwiderstand_1 / WIDERSTAND_1 * 1000;              //Berechnung Strom durch Referenz-NTC
      ntcwiderstand_1 = (Untc_1 / strom_1)*1000;                  //Berechnung Widerstand vom Referenz-NTC
      temperatur_1 = (-0.0125 * ntcwiderstand_1) + 37,3;          //Umrechnung WIderstand Referenz-NTC in Temperatur                              

      //Auswerten Prüfsensor
      bitwertNTC_2 = analogRead(PRUEFSENSOR);                      //Analog-Pin Prüfsensor auslesen
      Untc_2 = (double)bitwertNTC_2 * 0.00487;                    //Umwandlung Bitwerte von A2 in Spannung über Prüf-NTC
      Uwiderstand_2 = 5 - Untc_2;                                 //Berechnung Spannung über Referenzwiderstand
      strom_2 = Uwiderstand_2 / WIDERSTAND_2 * 1000;              //Berechnung Strom durch Prüf-NTC
      ntcwiderstand_2 = (Untc_2 / strom_2)*1000;                  //Berechnung Widerstand vom Prüf-NTC
      temperatur_2 = (-0.0125 * ntcwiderstand_2) + 37,3;          //Umrechnung WIderstand Prüf-NTC in Temperatur                              

      int temperatur_1_int = temperatur_1 * 100;            //Umwandlung vom double in ein int
      int temperatur_2_int = temperatur_2 * 100;            //Umwandlung vom double in ein int
      mb.Ireg(SENSOR_IREG5, temperatur_1_int);              //Datenpunkt 5 zum kontinuierlichen senden in Modbus schreiben
      mb.Ireg(SENSOR_IREG6, temperatur_2_int);              //Datenpunkt 6 zum kontinuierlichen senden in Modbus schreiben
    
      ts = millis();
      if(tasterStatus == HIGH)
      {
          digitalWrite(LED, HIGH);                  //LED anschalten
          
          if(temperatur_2 <= temperatur_1 + 0.5 && temperatur_2 >= temperatur_1 - 0.5)          //Überprüfen, ob Prüfsensor 
          {                                                                                     //im Toleranzbereich vom 
              funktion_Sensor = 1;          //Prüfsensor ist i.O.                               //Referenzsensor ist
          }
          else
          {
              funktion_Sensor = 0;          //Prüfsensor ist n.i.O.
          }
          
          id = EEPROM.read(0);              //id vom letzen Sensor ermitteln
          id = id + 1;                      //id um eins addieren
          EEPROM.write(0, id);              //neue id in EEPROM-Speicher schreiben
          
          mb.Ireg(SENSOR_IREG1, id);                    //Datenpunkt 1 in Modbus schreiben 
          mb.Ireg(SENSOR_IREG2, temperatur_1_int);      //Datenpunkt 2 in Modbus schreiben 
          mb.Ireg(SENSOR_IREG3, temperatur_2_int);      //Datenpunkt 3 in Modbus schreiben 
          mb.Ireg(SENSOR_IREG4, funktion_Sensor);       //Datenpunkt 3 in Modbus schreiben 
          delay(2000);                                  //wartet 2 Sekunden
          digitalWrite(LED, LOW);                       //LED ausschalten
      }      
   }
}
