// Version vom 19.09.2020 um 12:00
// PWM Port 11+12 auf 31300Hz eingestellt
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h> // LCD Display
// -------------LCD Display Acresse 0x3F oder 0x27----------------
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

int messwert1 = 0;
int messwert1_2 = 0;
int messwert2 = 0;
int messwert2_2 = 0;
const unsigned long Timer2 = (60000UL * 60); // Alle 60 Min. Lüftertausch
unsigned long VorherMilles2 = 0;
byte wechsel2 = 0;
byte luefteralarm = 0;
byte sensortausch = 1;// Wenn die Sensoren vertauscht sind dann "1" eintragen
// -------PWM Ausgabepins für Mega festlegen--------------------
const int PWM_PIN1 = 11;  // PWM Ausgabepin festlegen
const int PWM_PIN2 = 12;  // PWM Ausgabepin festlegen
const byte PWMmin = 30; // Minimaler PWM Wert für die Lüfter Motoren

const int delayTimeM1 = 2000; // Alle 2 Sekunden Temperatur-Auswertung
unsigned long VorherMillesM1 = 0;

const unsigned long Baud_Rate = 9600;
const unsigned char One_Wire_Bus = 2; // Sensoren auf Pin
OneWire oneWire(One_Wire_Bus);
DallasTemperature sensoren (&oneWire);

int Anzahl_Sensoren = 0;
int is = 0; // Zaehler fuer die Sensoren
int ia = 0; // Zaehler fuer die Adressstellen 0-7
int Sensor = 0;
DeviceAddress tempDeviceAddress; // Fuer die Adressausgabe
int numberOfDevices; // Fuer die Adressausgabe

void setup() {
  sensoren.begin();
  Serial.begin(9600);
  lcd.begin(20, 4);
  lcd.backlight();
  lcd.clear();
  lcd.setCursor (0, 0);
  lcd.print (F("Luefter"));
  lcd.setCursor (9, 0);
  lcd.print (F("Temp."));
  lcd.setCursor (16, 0);
  lcd.print (F("PWM"));
  lcd.setCursor (0, 1);
  lcd.print (F("-------------------"));
  lcd.setCursor (0, 2);
  lcd.print (F("CPU"));
  lcd.setCursor (0, 3);
  lcd.print (F("Raum"));
  // ----------PWM Tackt beim MEGA Pin 11 & 12 auf 31300Hz ändern---------------
  TCCR1B = TCCR1B & 0b11111000 | 0x01;

  // ----------Input und Output Pin bestimmen---------------------------
  pinMode(PWM_PIN1, OUTPUT);
  pinMode(PWM_PIN2, OUTPUT);

  // Anzahl der Sesoren ermitteln
  Anzahl_Sensoren = sensoren.getDeviceCount();

  // Ermitteln der Sensor-Adressen
  for (is = 0; is < Anzahl_Sensoren; is++)
  {
    if (sensoren.getAddress(tempDeviceAddress, is))
    {
      Serial.println ();
      printAddress(tempDeviceAddress);
    }
  }
  // Kein blockierendes Warten auf die Messung!!
  // Spart 740ms Loop Zeit bei der Messung
  sensoren.setWaitForConversion(false);
}
//---------------------------------------------------------------------------
// Ausgabe der Sensor-Adressen
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t ia = 0; ia < 8; ia++)
  {
    if (deviceAddress[ia] < 16)
    {
      Serial.print("0"); //ist die Hex Adresse kleiner 16 dann erste Stelle eine "0"
    }
    Serial.print(deviceAddress[ia], HEX);
  }
}
//---------------------------------------------------------------------------
void loop() {
  //------------------------------Temperatur Auslesen--------------------------
  if (millis() - VorherMillesM1 >= delayTimeM1)
  {
    VorherMillesM1 = millis();

    //Temperaturen Aulesen
    if (Sensor == 0) //Bei jedem ersten Durchgang Temperaturen holen
    {
      sensoren.requestTemperatures();
    }
    // Hier werden die Temperaturen aufs Display gebracht
    if (Sensor < Anzahl_Sensoren)
    {
      Sensor ++;
      float temperatur = sensoren.getTempCByIndex(Sensor - 1);
      // -----------Messfehler überbrücken--------------------------------
      // ----Sensor1------
      if ((temperatur < 0) && (Sensor == 1))
      {
        temperatur = 40;
      }
      // ----Sensor2------
      if ((temperatur < 0) && (Sensor == 2))
      {
        temperatur = 30;
      }
      //------------------------------------------------------------------
      // ---------------Lüfter Überwachung -------------------------------
      if ((temperatur > 50) && (Sensor == 1))
      {
        luefteralarm = 1; // Zweiten Lüfter zur CPU Lüftung zuschalten
      }
      if ((temperatur < 40) && (Sensor == 1))
      {
        luefteralarm = 0;
      }
      // --Sensorwerte ins Display in messwert1 oder messwert2 übergeben--
      //-------Wenn sensoren nicht vertauscht sind------------------------
      if (sensortausch == 0)
      {
        if (Sensor == 1)
        {
          messwert1 = temperatur;
          lcd.setCursor (9, 2);
          lcd.print (F("      "));
          lcd.setCursor (9, 2);
          lcd.print (temperatur);
        }
        if (Sensor == 2)
        {
          messwert2 = temperatur;
          lcd.setCursor (9, 3);
          lcd.print (F("      "));
          lcd.setCursor (9, 3);
          lcd.print (temperatur);
        }
        if (Sensor == Anzahl_Sensoren)
        {
          Sensor = 0;
        }
      }
      //------------------------------------------------------------------
      //----------Wenn Sensoren vertauscht sind---------------------------
      if (sensortausch == 1)
      {
        if (Sensor == 1)
        {
          messwert2 = temperatur;
          lcd.setCursor (9, 3);
          lcd.print (F("      "));
          lcd.setCursor (9, 3);
          lcd.print (temperatur);
        }
        if (Sensor == 2)
        {
          messwert1 = temperatur;
          lcd.setCursor (9, 2);
          lcd.print (F("      "));
          lcd.setCursor (9, 2);
          lcd.print (temperatur);
        }
        if (Sensor == Anzahl_Sensoren)
        {
          Sensor = 0;
        }
      }
      //-------------------Sensortausch Ende------------------------------
    }
    //---------------------------------------------------------------------------
       // Temperaturwerte 25-100 Grad, in PWM Wert "PWMmin"-255 umwandeln
    messwert1_2 = map(messwert1, 25, 100, (PWMmin-1), 255);
    messwert2_2 = map(messwert2, 25, 100, (PWMmin-1), 255);
    //Wenn PWM Drehzahl Lüfter 1 kleiner 30 dann unsicherer Lauf, also Lüfter aus
    if (messwert1_2 < PWMmin) 
    {
      messwert1_2 = 0;
    }
    if (messwert1_2 > 255)
    {
      messwert1_2 = 255;
    }
    //Wenn PWM Drehzahl Lüfter 2 kleiner 30 dann unsicherer Lauf, also Lüfter aus
    if (messwert2_2 < PWMmin)
    {
      messwert2_2 = 0;
    }
    if (messwert2_2 > 255)
    {
      messwert2_2 = 255;
    }
    if (wechsel2 == 0) // Lüfterwechsel 1 & 2 wenn Zeit gekommen ist
    {
      lcd.setCursor (5, 2);
      lcd.print (F("1"));
      lcd.setCursor (5, 3);
      lcd.print (F("2"));
      analogWrite (PWM_PIN1, messwert1_2); // Analogwert Ausgabe an PWM Pin.9
      analogWrite (PWM_PIN2, messwert2_2); // Analogwert Ausgabe an PWM Pin.10
      if (luefteralarm == 1)
      {
        analogWrite (PWM_PIN2, messwert1_2); // Analogwert Ausgabe an PWM Pin.9
      }
    }
    if (wechsel2 == 1) // Lüfterwechsel 1 & 2 wenn Zeit gekommen ist
    {
      lcd.setCursor (5, 2);
      lcd.print (F("2"));
      lcd.setCursor (5, 3);
      lcd.print (F("1"));
      analogWrite (PWM_PIN1, messwert2_2); // Analogwert Ausgabe an PWM Pin.9
      analogWrite (PWM_PIN2, messwert1_2); // Analogwert Ausgabe an PWM Pin.10
      if (luefteralarm == 1)
      {
        analogWrite (PWM_PIN1, messwert1_2); // Analogwert Ausgabe an PWM Pin.9
      }
    }
    lcd.setCursor (16, 2);
    lcd.print (F("    "));
    lcd.setCursor (16, 2);
    lcd.print (messwert1_2);

    if (luefteralarm == 1)
    {
      lcd.setCursor (16, 3);
      lcd.print (F("    "));
      lcd.setCursor (16, 3);
      lcd.print (messwert1_2);
    }
    else
    {
      lcd.setCursor (16, 3);
      lcd.print (F("    "));
      lcd.setCursor (16, 3);
      lcd.print (messwert2_2);
    }
  }
  //----Zeitsteuerung für Lüfterwechsel------
  if (millis() - VorherMilles2 >= Timer2)
  {
    VorherMilles2 = millis();
    wechsel2 = !wechsel2;
  }
  //-----------------------------------------
}