/**************************************************************************/
/*
   Bei einer Ref. Spannung von 4,096 Volt
   und einem Messteiler von 3 zu 1 ist die Rechnung
   4,096 x 4 = 16,384 / 1024 = 0,016
   Ist 0-1023 x 16 / 1000
   Höchste Messspannung ist bis 16,384 Volt beim 4 zu 1 Teiler

   Bei einer Ref. Spannung von 4,096 Volt
   und einem Messteiler von 11 zu 1 ist die Rechnung
   4,096 x 11 = 45,06 / 1024 = 0,044
   Ist 0-1023 +1 x 44 / 1000  // das +1 ist ene Messwert Korrektur
   Höchste Messspannung ist bis 45,060 Volt beim 11 zu 1 Teiler
*/
/**************************************************************************/
#include <LiquidCrystal_I2C.h> // LCD Display
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

const byte ANALOG_PIN16 = A0; // Hier wird der Name vom Messeingang 0-16 Volt festgelegt
const byte DIGI_PIN16 = 8; // Relais von 45V auf 16V umschalten, Low 45V Eingang, High 16V Eingang.
const byte ANALOG_PIN45 = A1; // Hier wird der Name vom Messeingang 0-45 Volt festgelegt
float max31 = 0;      // Der Speicher für den ausgelesenen Analogwert vom Messbuchse
float max31alt = 0;
float max32 = 0;       // Der Speicher für den ausgelesenen Max-Analogwert vom ADC
float min31 = 0;      // Der Speicher für den ausgelesenen Analogwert vom Messbuchse
float min31alt = 1023;
float min32 = 0;       // Der Speicher für den ausgelesenen Max-Analogwert vom ADC
float durchschnitt = 0;
unsigned long startzeit = 0;
unsigned long endzeit = 0;
unsigned long Sekundenablauf01 = 0; // Messung erneuern nach eine Sekunde
const unsigned long Pausezeit01 = 1000;
byte messeingang = 0;
byte messeingangalt = 0;
int eingang = 0;
//====================================================================================
void setup(void) {
  analogReference(EXTERNAL); // Externe Referenzspannung am AREF 4,096Volt
  Serial.begin(9600);

  pinMode(ANALOG_PIN16, INPUT); // Input vom Messteiler 16V
  pinMode(ANALOG_PIN45, INPUT); // Input vom Messteiler 45V
  pinMode(DIGI_PIN16, OUTPUT);  // Output vom Analogschalter 16V
  lcd.begin(20, 4);
  lcd.backlight();
  lcd.clear();
  // Display Maxwert
  lcd.setCursor (0, 0);
  lcd.print (F("Maximalwert"));
  lcd.setCursor (18, 0);
  lcd.print (F("V"));
  // Display Minwert
  lcd.setCursor (0, 1);
  lcd.print (F("Minimalwert"));
  lcd.setCursor (18, 1);
  lcd.print (F("V"));
  // Display Durchschnitts Wert
  lcd.setCursor (0, 2);
  lcd.print (F("Normalwert"));
  lcd.setCursor (18, 2);
  lcd.print (F("V"));
  lcd.setCursor (0, 3);
  lcd.print (F("Messeingang bis "));
}
//===================================================================================
//--------------------------------LOOP Start---------------------------------------------------
void loop(void) {
  //------Zeit für die Durchlaufmessung---------
  startzeit = micros();
  //---Testen welcher Eingang Spannung führt----
  testmesseingang();
  //--Nach einer Sekunde neue Messung starten---
  if (millis() - Sekundenablauf01 >= Pausezeit01) {
    displayausgabe();
  }
  //---Messung 700 x pro Sekunde----------------
  messen();
  // -----------------------------------Laufzeittest-------------------------------------------
  endzeit = micros();
  //Serial.println(endzeit - startzeit);
}
//--------------------------------LOOP Ende----------------------------------------------------
//-----------------------------Max und Minwert messen und Maxwert sichern----------------------
void messen() {
  if (messeingang == 1) {
    max31 = analogRead (ANALOG_PIN16); // Analogen Eingang A0 auslesen
  }
  if (messeingang == 2) {
    max31 = analogRead (ANALOG_PIN45); // Analogen Eingang A0 auslesen
  }
  min31 = max31;
  if (max31 >= max31alt) {
    max31alt = max31;
  }
  //-----Minimalwert sichern-----------------
  if (min31 <= min31alt) {
    min31alt = min31;
  }
}
//--------------------------------Messen Ende--------------------------------------------------
//------------------------------Messeingang bestimmen------------------------------------------
void testmesseingang() {
  if (millis() - Sekundenablauf01 >= Pausezeit01) {
    messeingang = 0;
    eingang = analogRead (ANALOG_PIN16); // Analogen Eingang A0 auslesen
    if (eingang >= 30) {  // Ist A0 größer 0,5 Volt dann als Eingang markieren
      messeingang = 1;
      messeingangalt = 1;
      lcd.setCursor (16, 3);
      lcd.print (F("  "));
      lcd.setCursor (16, 3);
      lcd.print (F("16V"));
    }
    eingang = analogRead (ANALOG_PIN45); // Analogen Eingang A1 auslesen
    if (eingang >= 11) {  // Ist A1 größer 0,5 Volt dann als Eingang markieren
      messeingang = 2;
      messeingangalt = 2;
      lcd.setCursor (16, 3);
      lcd.print (F("  "));
      lcd.setCursor (16, 3);
      lcd.print (F("45V"));
    }
    if (messeingang == 0) {
      messeingang = messeingangalt;
    }
  }
}
//--------------------------Eingangstest Ende--------------------------------------------------
//----------------------Ausgabe nach einer Sekunde aufs Display--------------------------------
void displayausgabe () {
  if (messeingang == 1) {
    max32 = ((max31alt * 16) / 1000); // 0-1023 x 0,016 für 16 Volt
    if (max32 >= 13) {
      digitalWrite(DIGI_PIN16, LOW);
    }
  }
  if (messeingang == 2) {
    max32 = (((max31alt + 1) * 44) / 1000); // 0-1023 x 0,044 für 45 Volt
    if ((max32 >=1)&&(max32<= 10)) {
      digitalWrite(DIGI_PIN16, HIGH);
    }
  }
  lcd.setCursor (13, 0);
  lcd.print (F("     "));
  lcd.setCursor (13, 0);
  lcd.print (max32);
  max31alt = 0;
  if (messeingang == 1) {
    min32 = ((min31alt * 16) / 1000); // 0-1023 x 0,016 für 16 Volt
  }
  if (messeingang == 2) {
    min32 = (((min31alt + 1) * 44) / 1000); // 0-1023 x 0,044 für 45 Volt
  }
  lcd.setCursor (13, 1);
  lcd.print (F("     "));
  lcd.setCursor (13, 1);
  lcd.print (min32);
  min31alt = 1023;
  lcd.setCursor (13, 2);
  lcd.print (F("     "));
  lcd.setCursor (13, 2);
  durchschnitt = max32 / 2;
  if ((max32 - min32) <= 1) {
    durchschnitt = max32;
  }
  lcd.print (durchschnitt);
  Sekundenablauf01 = millis();
}
//------------------------------Display Ausgane Ende-------------------------------------------