/*
   Arduino code for Individual control over each pin
   Support for 40+ 74HC595 8 bit shift registers
   http://bildr.org/2011/02/74hc595/
*/

#define DATA_PIN  8  // Pin connected to DS of 74HC595
#define LATCH_PIN 4  // Pin connected to STCP of 74HC595
#define CLOCK_PIN 3 // Pin connected to SHCP of 74HC595

//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 4;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 3;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 2;
#define max_ser_char 20
 //////////////////////////////////////
///  Timer Handling--Global-----------
  bool DiagRuntime=true;
  bool RunTimeError=false;
  bool ton10000=0;  //10 sekunden Blinker
  bool ton5000=0;   //sekunden Blinker 1s
  bool ton1000=0;   //sekunden Blinker 1s
  bool ton100=0;    //sekunden Blinker 1/100s
  bool ton50=0;    //sekunden Blinker 1/10s
  bool fton10000=0;  //Flanke fuer Blinker
  bool fton5000=0;  //Flanke fuer Blinker
  bool fton1000=0;  //Flanke fuer Blinker
  bool fton100=0;   //Flanke fuer Blinker
  bool fton50=0;   //Flanke fuer Blinker
  unsigned long prev10000Millis = 0;        // Zaehler feur blinken 
  unsigned long prev5000Millis = 0;        // Zaehler feur blinken 
  unsigned long prev1000Millis = 0;        // Zaehler feur blinken 
  unsigned long prev100Millis = 0;         // Zaehler feur blinken 
  unsigned long prev50Millis = 0;         // Zaehler feur blinken 
  unsigned long UptimeSec = 0;        // Zaehler für Uhr
  unsigned int MillisOverrun =0;
  unsigned int WatchMoreThen50Millis =0;
  unsigned int WatchMoreThen100Millis =0;
  unsigned int LoopTime =0;
  unsigned long currentMillis = millis();
  String GS_StartTime = "";
  bool   GB_StartTime=false;
  unsigned long GI_TimeToStart=0;

int Timer(bool Begin);       //Zeitensteuerung
//---END Timer-------------------------------------------------------------------

void setup() {
//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
Serial.begin(9600);
Serial.println("Bring up Monitor");
}




void loop()
{ 
  Timer(true);
  static uint16_t bitToSet=0;
  static uint32_t max_loop=0;
  while (Serial.available() > 0)
  {
    static char read_ser[max_ser_char];
    static unsigned int char_count = 0;
    char in_char = Serial.read();
    if ( in_char != '\n' && (char_count < max_ser_char - 1) )
    {
      read_ser[char_count] = in_char;
      char_count++;
    }
    else
    {
      read_ser[char_count] = '\0';
      int bit_write = atoi(read_ser);
      bitToSet = bit_write <<8;      //nur zum Test nur die letzten 3 LEDs aktive
     // bitToSet=bit_write&0b11100000;   //nur zum Test nur die letzten 3 LEDs aktive
      //Serial.println(bitToSet,DEC);
      char_count = 0;   //Zaehler abnullen
      //registerWrite(bitToSet);
    }  
  }
  if(ton50)
  {   
    bitWrite(bitToSet, 0, HIGH);
  }
  else
  {
    bitWrite(bitToSet, 0, LOW);
  }
  if(ton100)
  {   
    bitWrite(bitToSet, 1, HIGH);
  }
  else
  {
    bitWrite(bitToSet, 1, LOW);
  }  
  if(ton1000)
  {   
    bitWrite(bitToSet, 2, HIGH);
  }
  else
  {
    bitWrite(bitToSet, 2, LOW);
  }  
  if(ton5000)
  {   
    bitWrite(bitToSet, 3, HIGH);
  }
  else
  {
    bitWrite(bitToSet, 3, LOW);
  }
  if(fton10000)
  {   
    bitWrite(bitToSet, 4, HIGH);
    //if(LoopTime>max_loop)
    //  max_loop=LoopTime;
    //Serial.print("max_loop: ");
    //Serial.println(max_loop,DEC);
  }
  else
  {
    bitWrite(bitToSet, 4, LOW);
  }
  registerWrite(bitToSet);
  Timer(false);
}

void registerWrite(uint16_t send_byte) 
{
  uint16_t send_byte_old;
  if(send_byte_old!=send_byte)
  {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, send_byte>>8);
    shiftOut(dataPin, clockPin, MSBFIRST, send_byte);
    digitalWrite(latchPin, HIGH);
    send_byte_old=send_byte;
   // Serial.println(send_byte, DEC);
  }
}

//////////////////////////////////////
///  Timer Handling-------------
//////////////////////////////////////
////////////////////////////////////////////
int Timer(bool Begin) {
    if(Begin){
      currentMillis = millis();
    
      if(currentMillis < prev50Millis){
        prev10000Millis = 0; prev5000Millis = 0; prev1000Millis = 0; prev100Millis = 0; prev50Millis = 0; MillisOverrun ++;// Zaehler Nullen da milis ueberlauf 
      }
      UptimeSec = (MillisOverrun * 4294967) + (currentMillis / 1000);
      if((currentMillis >= prev50Millis + 50) /* &! (fton100 || fton1000 || fton5000 || fton10000)*/){
          prev50Millis = currentMillis;
          if(ton50==0){
             ton50=1;fton50=1;
          }else{ton50=0;fton50=1;}
      }
      else if((currentMillis >= prev100Millis + 100)/* &! (fton50 || fton1000 || fton5000 || fton10000)*/) {
          prev100Millis = currentMillis;
          if(ton100==0){
             ton100=1;fton100=1;
          }else{ton100=0;fton100=1;}
      }
      else if((currentMillis >= prev1000Millis + 1000)/* &! (fton50 || fton100 || fton5000 || fton10000)*/) {
          prev1000Millis = currentMillis;
              if(ton1000==0){ton1000=1;fton1000=1;
              }else{ ton1000=0;fton1000=1;}
      }       
      else if((currentMillis >= prev5000Millis + 5000)/* &! (fton50 || fton100 || fton1000 || fton10000)*/) {
          prev5000Millis = currentMillis;
              if(ton5000==0){ton5000=1;fton5000=1;
              }else{ ton5000=0;fton5000=1;}
      }       
      else if((currentMillis >= prev10000Millis + 10000)/* &! (fton50 || fton100 || fton1000 || fton5000)*/) {
          prev10000Millis = currentMillis;
              if(ton10000==0){ton10000=1;fton10000=1;
              }else{ ton10000=0;fton10000=1;}
      }
      return 0;
    }
    else{
        if(DiagRuntime){
            if(millis()>currentMillis +50)
                WatchMoreThen50Millis ++;
            if(millis()>currentMillis +100)
                WatchMoreThen100Millis ++;
            LoopTime=millis()- currentMillis;
        }
        fton10000=0; fton5000=0; fton1000=0; fton100=0; fton50=0;      
        if(millis()> currentMillis +100)
          return -1;
        else
          return 0;
    }
}
///////////////////////////////////////////////////
/// --END--- Timer Handling-------------
///////////////////////////////////////////////////7
///////////-----Zeit----------------
74HC595
74HC595