#include <DS3232RTC.h> //http://github.com/JChristensen/DS3232RTC
#include <Streaming.h> //http://arduiniana.org/libraries/streaming/
#include <Time.h>      //http://playground.arduino.cc/Code/Time
#include <Wire.h>      //http://arduino.cc/en/Reference/Wire

const byte ChronoDot = 0x68;
const byte Pakete = 7;
int Sekunde,Minute,Stunde,Tag,Wochentag,Monat,Jahr;
/*
UNO  SDA an A4  SCL an A5
MEGA SDA an D20 SCL an D21

Uhr eistellen mit \Wortuhr IX\DS3232.ino
Beispiel 21. Sept. 2014 16 Uhr 06 15 Sek.:
JJ M DD HH M SS bzw. JJ MM DD HH MM SS
14,9,21,16,6,15 in Monitor eingeben und senden 
*/
int SH_CP1 = 4;  // SH_CP Takt 
int ST_CP1 = 3;  // ST_CP Speicher
int DS_CP1 = 2;  // DS Daten

int SH_CP2 = 7;  // SH_CP Takt 
int ST_CP2 = 6;  // ST_CP Speicher
int DS_CP2 = 5;  // DS Daten

int DEUTSCH=13;  // HIGH = Deutsch  
int SVENSKA=12;  // HIGH = Schwedisch
int DS;          // 0=Deutsch, 1=Schwedisch

int TASTE_T=8;   // Zeit einstellen an/aus
int TASTE_H=9;   // Stunden einstellen
int TASTE_M=10;  // Minuten einstellen

int UHR=11;    //Text "UHR" bzw. "3"

int ModusZeit;     //0=Normalbetrie, 1=Zeit einstellen, 2=Testlauf ohne Uhr

int BITMUSTER[17];
int WERT1;
int WERT2;

int MINUTE_D[12][4]=
{
    /*
    ES IST=4 FUENF=1 ZEHN=2 VIERTEL=8 DREI=32
    ZWANZIG=16 VOR=64 HALB=128 NACH=256    
    */
    {4,  0,  0,  0},    //Volle Stunde
    {4,  1,256,  0},    //ES_IST FUENF NACH
    {4,  2,256,  0},    //ES_IST ZEHN NACH
    {4,  8,256,  0},    //ES_IST VIERTEL NACH
    {4, 16,256,  0},    //ES_IST ZWANZIG NACH
    {4,  1, 64,128},    //ES_IST FUENF VOR HALB
    {4,128,  0,  0},    //ES_IST HALB
    {4,  1,256,128},    //ES_IST FUENF NACH HALB
    {4, 16, 64,  0},    //ES_IST ZWANZIG VOR
    {4, 32,  8,  0},    //ES_IST DREI VIERTEL
    {4,  2, 64,  0},    //ES_IST ZEHN VOR
    {4,  1, 64,  0}     //ES_IST FUENF VOR
};

int MINUTE_S[12][4]=
{
    /*
    DET AER=4 FEM=2 TIO=16 KVART=32 TJUGO=8 
    HALV=256 OEVER=64 I=128 KLOCKAN=1
    */
    {1,  0,  0,  0},    //Volle Stunde
    {4,  2, 64,  0},    //DET AER FEM OEVER       ES_IST FUENF NACH
    {4, 16, 64,  0},    //DET AER TIO OEVER       ES_IST ZEHN NACH
    {4, 32, 64,  0},    //DET AER KVART OEVER     ES_IST VIERTEL NACH
    {4,  8, 64,  0},    //DET AER TJUGO OEVER     ES_IST ZWANZIG NACH
    {4,  2,128,256},    //DET AER FEM I HALV      ES_IST FUENF VOR HALB
    {4,256,  0,  0},    //DET AER HALV            ES_IST HALB
    {4,  2, 64,256},    //DET AER FEM OEVER HALV  ES_IST FUENF NACH HALB
    {4,  8,128,  0},    //DET AER TJUGO I         ES_IST ZWANZIG VOR
    {4, 32,128,  0},    //DET AER KVART I         ES_IST DREI VIERTEL
    {4, 16,128,  0},    //DET AER TIO I           ES_IST ZEHN VOR
    {4,  2,128,  0}     //DET AER FEM I           ES_IST FUENF VOR
};

int STUNDE_D[13][2]=
{
    /*
    S=1 EIN=2 EL=4 F=8 UENF=16 ZWEI=32 DREI=64 SECHS=128
    SIEBEN=256 VIER=512 ACHT=1024 ZEH=4096 N=8192
    EUN=16384 ZWOELF=32768    
    */
    {    0,    0},    //Dummy   
    {    2,    1},    //EINS
    {    0,   32},    //ZWEI
    {    0,   64},    //DREI  
    {    0,  512},    //VIER
    {    8,   16},    //F_UENF
    {    0,  128},    //SECHS
    {    0,  256},    //SIEBEN
    {    0, 1024},    //ACHT
    { 8192,16384},    //N_EUN
    { 4096, 8192},    //Z_EHN
    {    4,    8},    //EL_F
    {    0,32768}     //ZWOELF    
};    

int STUNDE_S[13][2]=
{
    /*
    ET=1 T=2 VA=4 TRE=8 FEM=16 SEX=32 NIO=64 SJU=128
    FYRA=256 ATTA=512 TIO=1024 TOLV=2048 ELVA=4096
    1=8192 2=16384 4=32768
    */
    {    0,    0},    //Dummy   
    {    1,    2},    //ET_T       EIN UHR
    {    2,    4},    //T_VA       ZWEI UHR
    {    0,    8},    //TRE        DREI UHR    
    {    0,  256},    //FYRA       VIER UHR
    {    0,   16},    //FEM        F_UENF UHR
    {    0,   32},    //SEX        SECHS UHR
    {    0,  128},    //SJU        SIEBEN UHR
    {    0,  512},    //ATTA       ACHT UHR
    {    0,   64},    //NIO        N_EUN UHR
    {    0, 1024},    //TIO        Z_EHN UHR
    {    0, 4096},    //ELVA       EL_F UHR
    {    0, 2048}     //TOLV       ZWOELF UHR      
};

int M,H,W,X,Y,Z;
int ZT,ZH,ZM;
int MinuteMERK,StundeMERK;
//++++++++++++++++++++++++++++++++++++++++++++++++
void setup() 
{
    Serial.begin(9600);
    Wire.begin();    
    pinMode(SH_CP1, OUTPUT);
    pinMode(ST_CP1, OUTPUT);
    pinMode(DS_CP1, OUTPUT);
    pinMode(SH_CP2, OUTPUT);
    pinMode(ST_CP2, OUTPUT);
    pinMode(DS_CP2, OUTPUT);    
    RESET_PINS1();           // Alle Pins auf LOW setzten
    RESET_PINS2();
    pinMode(DEUTSCH,INPUT);
    pinMode(SVENSKA,INPUT);
    pinMode(TASTE_T,INPUT);digitalWrite(TASTE_T,HIGH);
    pinMode(TASTE_H,INPUT);digitalWrite(TASTE_H,HIGH);
    pinMode(TASTE_M,INPUT);digitalWrite(TASTE_M,HIGH);
    pinMode(UHR,OUTPUT);
    WERT1=0;LED_SHOW1();
    WERT2=0;LED_SHOW2();
    digitalWrite(ST_CP1, HIGH); // ST_CP 
    digitalWrite(ST_CP2, HIGH); // ST_CP
    if(digitalRead(DEUTSCH)==HIGH){DS=0;}
    if(digitalRead(SVENSKA)==HIGH){DS=1;}
    digitalWrite(UHR,LOW);
    ModusZeit=0;    
}
//++++++++++++++++++++++++++++++++++++++++++++++++
void loop()
{
    if(ModusZeit==0)
    {
        Wire.beginTransmission(ChronoDot);
        Wire.write((byte)0x00);
        Wire.endTransmission();
        Wire.requestFrom(ChronoDot,Pakete);
        Sekunde=BCD_DEC(Wire.read()&0x7f);
        Minute=BCD_DEC(Wire.read());
        Stunde=BCD_DEC(Wire.read()&0x3f);
        //ANZEIGE_RTC();
        if(Stunde==0){Stunde=12;}
        M=Minute/5;
        H=Stunde;
        if(H==0){H=12;}
        if(M>=5){H++;}
        if(H>12){H=H-12;}
        //Serial.print(Minute);Serial.print(":");Serial.print(M);Serial.print("  ");
        //Serial.print(Stunde);Serial.print(".");Serial.println(H);                
        WERT2=0;
        for(Y=0;Y<2;Y++)
        {
            if(DS==0){WERT2=WERT2+STUNDE_D[H][Y];}
            if(DS==1){WERT2=WERT2+STUNDE_S[H][Y];}
            //Serial.println(WERT2);
        }
        LED_SHOW2();
        WERT1=0;
        digitalWrite(UHR,LOW);
        for(Y=0;Y<4;Y++)
        {
            if(DS==0){WERT1=WERT1+MINUTE_D[M][Y];}
            if(DS==1){WERT1=WERT1+MINUTE_S[M][Y];}
        }
        if(Minute<5)
        {
            if(DS==0){digitalWrite(UHR,HIGH);}    //UHR
            if(DS==1){WERT1=1;}                   //KLOCKAN
                    
        }                
        LED_SHOW1();
        //EIN UHR
        if(DS==0)
        {
            if(M==0)
            {
                if(H==1)
                {
                    WERT1=4;LED_SHOW1(); //ES IST
                    WERT2=2;LED_SHOW2(); //EIN
                }
            }
        }
        digitalWrite(ST_CP1, HIGH); // ST_CP
        digitalWrite(ST_CP2, HIGH); // ST_CP
        delay(5);
    }
    if(ModusZeit==1)
    {
        
    }
    TASTEN();
    delay(500);    
}
//++++++++++++++++++++++++++++++++++++++++++++++++
void TASTEN()
{
    ZT=digitalRead(TASTE_T);
    if(ZT==LOW)
    {
        delay(700);
        ZT=digitalRead(TASTE_T);    
        if(ZT==LOW){ModusZeit++;}
        if(ModusZeit==1)
        {
            if(DS==1){digitalWrite(UHR,HIGH);}
            MinuteMERK=M;
            StundeMERK=Stunde;
            if(MinuteMERK>=5){StundeMERK++;}
            if(StundeMERK>12){StundeMERK=StundeMERK-13;}
            WERT1=0;WERT2=0;
            for(Y=0;Y<2;Y++)
            {
                if(DS==0){WERT2=WERT2+STUNDE_D[StundeMERK][Y];}
                if(DS==1){WERT2=WERT2+STUNDE_S[StundeMERK][Y];}
            }            
            for(Y=1;Y<4;Y++)
            {
                if(DS==0){WERT1=WERT1+MINUTE_D[MinuteMERK][Y];}
                if(DS==1){WERT1=WERT1+MINUTE_S[MinuteMERK][Y];}
            }
            LED_SHOW1();LED_SHOW2();
            digitalWrite(ST_CP1, HIGH); // ST_CP
            digitalWrite(ST_CP2, HIGH); // ST_CP
            delay(5);            
        }

        if(ModusZeit==2)
        {
            if(MinuteMERK>4){StundeMERK--;}
            /*
            Serial.print("MM ");Serial.print(MinuteMERK);
            Serial.print("  SM ");Serial.print(StundeMERK);
            Serial.print("  H ");Serial.println(H);
            Serial.print("MIN ");Serial.print(MinuteMERK*5);
            Serial.print(" STD ");Serial.println(StundeMERK); 
            Serial.println(" Fertig");
            */
            // /*
            static time_t tLast;
            time_t t;
            tmElements_t tm;
            tm.Hour=StundeMERK;
            tm.Minute=MinuteMERK*5;
            t=makeTime(tm);
            RTC.set(t);
            setTime(t);
            // */
            if(DS==1){digitalWrite(UHR,LOW);}    
            ModusZeit=0;
        }
    }
    if(ModusZeit==1)
    {
        ZH=digitalRead(TASTE_H);
        if(ZH==LOW)
        {
            delay(700);
            ZH=digitalRead(TASTE_H);
            if(ZH==LOW)
            {
                StundeMERK++;
                if(StundeMERK>12){StundeMERK=1;}
                WERT2=0;
                for(Y=0;Y<2;Y++)
                {
                    if(DS==0){WERT2=WERT2+STUNDE_D[StundeMERK][Y];}
                    if(DS==1){WERT2=WERT2+STUNDE_S[StundeMERK][Y];}
                }                            
            }
            LED_SHOW2();
            digitalWrite(ST_CP2, HIGH); // ST_CP
        }
        ZM=digitalRead(TASTE_M);
        if(ZM==LOW)
        {
            delay(700);
            ZM=digitalRead(TASTE_M);
            if(ZM==LOW)
            {
                MinuteMERK++;
                if(MinuteMERK>11){MinuteMERK=0;}
                WERT1=0;
                for(Y=1;Y<4;Y++)
                {
                    if(DS==0){WERT1=WERT1+MINUTE_D[MinuteMERK][Y];}
                    if(DS==1){WERT1=WERT1+MINUTE_S[MinuteMERK][Y];}
                }                
            }
            LED_SHOW1();
            digitalWrite(ST_CP1, HIGH); // ST_CP            
        }
        /*
        Serial.print("MM ");Serial.print(MinuteMERK);
        Serial.print("  SM ");Serial.print(StundeMERK);
        Serial.print("  H ");Serial.println(H);
        */        
    }
}
//++++++++++++++++++++++++++++++++++++++++++++++++
byte BCD_DEC(byte num)
{
    return((num/16*10)+(num % 16));
}
//++++++++++++++++++++++++++++++++++++++++++++++++
void ANZEIGE_RTC()
{
    Serial.print(Stunde);
    printDigits(Minute);
    printDigits(Sekunde);
    Serial.println(" ");
}
//++++++++++++++++++++++++++++++++++++++++++++++++
void printDigits(int digits)
{
    Serial.print(":");
    if(digits<10) Serial.print('0');
    Serial.print(digits);
}
//++++++++++++++++++++++++++++++++++++++++++++++++
void RESET_PINS1()
{
    digitalWrite(SH_CP1, LOW);
    digitalWrite(ST_CP1, LOW);
    digitalWrite(DS_CP1, LOW);
}
//++++++++++++++++++++++++++++++++++++++++++++++++
void RESET_PINS2()
{
    digitalWrite(SH_CP2, LOW);delay(1);
    digitalWrite(ST_CP2, LOW);delay(1);
    digitalWrite(DS_CP2, LOW);delay(1);   
}
//++++++++++++++++++++++++++++++++++++++++++++++++
void LED_SHOW1()
{
    BITMUSTER[0]=WERT1/256;WERT1=WERT1-(BITMUSTER[0]*256);
    BITMUSTER[1]=WERT1/128;WERT1=WERT1-(BITMUSTER[1]*128);
    BITMUSTER[2]=WERT1/64;WERT1=WERT1-(BITMUSTER[2]*64);
    BITMUSTER[3]=WERT1/32;WERT1=WERT1-(BITMUSTER[3]*32);
    BITMUSTER[4]=WERT1/16;WERT1=WERT1-(BITMUSTER[4]*16);
    BITMUSTER[5]=WERT1/8;WERT1=WERT1-(BITMUSTER[5]*8);
    BITMUSTER[6]=WERT1/4;WERT1=WERT1-(BITMUSTER[6]*4);
    BITMUSTER[7]=WERT1/2;WERT1=WERT1-(BITMUSTER[7]*2);
    BITMUSTER[8]=WERT1/1;WERT1=WERT1-(BITMUSTER[8]*1);
    SETZE_PINS1();
    //digitalWrite(ST_CP1, HIGH); // ST_CP 
}
//++++++++++++++++++++++++++++++++++++++++++++++++
void LED_SHOW2()
{
    BITMUSTER[0]=WERT2/65536;WERT2=WERT2-(BITMUSTER[0]*65536);
    BITMUSTER[1]=WERT2/32768;WERT2=WERT2-(BITMUSTER[1]*32768);
    BITMUSTER[2]=WERT2/16384;WERT2=WERT2-(BITMUSTER[2]*16384);
    BITMUSTER[3]=WERT2/8192;WERT2=WERT2-(BITMUSTER[3]*8192);
    BITMUSTER[4]=WERT2/4096;WERT2=WERT2-(BITMUSTER[4]*4096);
    BITMUSTER[5]=WERT2/2048;WERT2=WERT2-(BITMUSTER[5]*2048);
    BITMUSTER[6]=WERT2/1024;WERT2=WERT2-(BITMUSTER[6]*1024);
    BITMUSTER[7]=WERT2/512;WERT2=WERT2-(BITMUSTER[7]*512);
    BITMUSTER[8]=WERT2/256;WERT2=WERT2-(BITMUSTER[8]*256);
    BITMUSTER[9]=WERT2/128;WERT2=WERT2-(BITMUSTER[9]*128);
    BITMUSTER[10]=WERT2/64;WERT2=WERT2-(BITMUSTER[10]*64);
    BITMUSTER[11]=WERT2/32;WERT2=WERT2-(BITMUSTER[11]*32);
    BITMUSTER[12]=WERT2/16;WERT2=WERT2-(BITMUSTER[12]*16);
    BITMUSTER[13]=WERT2/8;WERT2=WERT2-(BITMUSTER[13]*8);
    BITMUSTER[14]=WERT2/4;WERT2=WERT2-(BITMUSTER[14]*4);
    BITMUSTER[15]=WERT2/2;WERT2=WERT2-(BITMUSTER[15]*2);
    BITMUSTER[16]=WERT2/1;WERT2=WERT2-(BITMUSTER[16]*1);
    SETZE_PINS2();
    //digitalWrite(ST_CP2, HIGH); // ST_CP 
}
//++++++++++++++++++++++++++++++++++++++++++++++++
void SETZE_PINS1()
{
    for(X=0;X<9;X++)
    {
        RESET_PINS1();
        digitalWrite(DS_CP1, BITMUSTER[X]); 
        delay(5);
        digitalWrite(SH_CP1, HIGH); 
        delay(5);
    }
}
//++++++++++++++++++++++++++++++++++++++++++++++++
void SETZE_PINS2()
{
    for(X=0;X<17;X++)
    {
        RESET_PINS2();
        digitalWrite(DS_CP2, BITMUSTER[X]);
        delay(5);
        digitalWrite(SH_CP2, HIGH); 
        delay(5);
    }
}