
// =============================================================================================================================
/* 
 Title ..: DCF with 1284P - 328P
 Author .: Ed Nieuwenhuys Oct 2016
*/
// ===============================================================================================================================
 
//--------------------------------------------
// ARDUINO Definition of installed modules
//--------------------------------------------
#include <Wire.h>
#include "DCF77.h"
#include "TimeLib.h"
#include <RTClib.h>
 
//--------------------------------------------
// PIN Assigments
//-------------------------------------------- 
#if defined(__AVR_ATmega328P__) 
// Digital hardware constants ATMEGA 328 ----
enum DigitalPinAssignments {
 
  DCF_PIN     =  2,               // DCFPulse on interrupt  pin
  DCF_LED_Pin  = 9,           // define pin voor AM PM Led
  secondsPin   = 13};
                                  // Analogue hardware constants ----
enum AnaloguePinAssignments {
 SDA_pin       = 4,               // SDA pin
 SCL_pin       = 5};              // SCL pin
# endif
 
//--------------------------------------------//-------------------------------------------- 
#if defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284__)
                                  // Digital hardware constants ATMEGA 1284P ----
enum DigitalPinAssignments {
 
  DCF_PIN      = 2,                  // DCFPulse on interrupt  pin
  DCF_LED_Pin  = 10,            // define pin voor AM PM Led
  secondsPin   = 29};
                                  // Analogue hardware constants ----
enum AnaloguePinAssignments {
 SDA_pin       = 17,               // SDA pin
 SCL_pin       = 16};              // SCL pin
 # endif 
 
//--------------------------------------------
// CLOCK
//--------------------------------------------                                 
static unsigned long msTick;   // the number of millisecond ticks since we last incremented the second counter
byte Isecond, Iminute, Ihour, Iday, Imonth, Iyear; 
byte SecPulse           = 0;      // give a pulse to the Isecond led
String SerialString;
//--------------------------------------------
// DS3231 CLOCK MODULE
//--------------------------------------------
 
RTC_DS3231 RTC;    //RTC_DS1307 RTC;  
DateTime Inow;
 
//--------------------------------------------
// DCF-2 DCF77 MODULE
//--------------------------------------------
byte DCF_signal = 0;              // is a proper time received?
#if defined(__AVR_ATmega328P__) 
#define DCF_INTERRUPT 0           // DCF Interrupt number associated with DCF_PIN
#endif
#if defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284__)
#define DCF_INTERRUPT 2           // DCF Interrupt number associated with DCF_PIN
#endif
time_t tijd;
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT,LOW);
                                  // End Definitions  ---------------------------------------------------------
                               
//--------------------------------------------
// ARDUINO Loop
//--------------------------------------------
void loop(void)
{
 SerialCheck();
 DCF77Check();
 EverySecondCheck();
}  
//--------------------------------------------
// ARDUINO Setup
//--------------------------------------------
void setup()
{                                              // initialise the hardware // initialize the appropriate pins as outputs:
 
 pinMode(DCF_LED_Pin,  OUTPUT);
 pinMode(secondsPin,   OUTPUT );
 pinMode(DCF_PIN,      INPUT_PULLUP);
 Serial.begin(9600);                          // setup the serial port to 9600 baud 
 DCF.Start();                                 // start the DCF-module
 Wire.begin();                                // start the wire communication I2C
 RTC.begin();                                 // start the RTC-module
 DateTime now = RTC.now();                    // Get the time from the RTC
 DateTime compiled = DateTime(__DATE__, __TIME__);
 if (now.unixtime() < compiled.unixtime()) 
 {
  Serial.println("RTC is older than compile time! Updating");      // following line sets the RTC to the date & time this sketch was compiled
  RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); 
 } 
 GetTijd(0);                                                       // Get the time and print it to serial
}
// --------------------------- END SETUP                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
 
//--------------------------------------------
// CLOCK Update routine done every second
//--------------------------------------------
void EverySecondCheck(void)
{
  if ( millis() - msTick >50)   digitalWrite(secondsPin,LOW);       // Turn OFF the second on pin 13
  if ( millis() - msTick >999)                              // Flash the onboard Pin 13 Led so we know something is happening
  {    
   msTick = millis();                                             // second++; 
   digitalWrite(secondsPin,HIGH);                   // turn ON the second on pin 13
   ++SecPulse;                                                      // second routine in function DimLeds
   GetTijd(0);                                                      // synchronize time with RTC clock 
 //  Print_tijd();
  }
 }
 
//--------------------------------------------
// CLOCK check for DCF input
//--------------------------------------------
void DCF77Check(void)
{
  time_t DCFtime = DCF.getTime();                  // Check if new DCF77 time is available
  if (DCFtime!=0)
   {
    Serial.print(F("Time is updated ----->  "));
    DCF_signal++;
    setTime(DCFtime); 
    RTC.adjust(DCFtime);
    digitalClockDisplay(); 
   } 
  digitalWrite(DCF_LED_Pin,1-digitalRead(DCF_PIN));                // write inverted DCF pulse to LED on board
} 
 
//--------------------------------------------
// CLOCK check for serial input
//--------------------------------------------
void SerialCheck(void)
{
 while (Serial.available())
  {
   delay(3);  
   char c = Serial.read();
   if (c>31 && c<128) SerialString += c;            // allow input from Space - Del
  }
 if (SerialString.length()>0)     ReworkInputString(SerialString);  // Rework ReworkInputString();
 SerialString = "";
}
 
//--------------------------------------------
// DS3231 Get time from DS3231
//--------------------------------------------
void GetTijd(byte printit)
{
 Inow =    RTC.now();
 Ihour =   Inow.hour();
 Iminute = Inow.minute();
 Isecond = Inow.second();
// if (Ihour > 24) { Ihour = random(12)+1; Iminute = random(60)+1; Isecond = 30;}  // set a time if time module is absent or defect
 if (printit)  Print_RTC_tijd(); 
}
 
//--------------------------------------------
// DS3231 utility function prints time to serial
//--------------------------------------------
void Print_RTC_tijd(void)
{
 if (Inow.hour() < 10) Serial.print(F("0"));
 Serial.print(Inow.hour(), DEC);
 Serial.print(F(":"));
 if (Inow.minute() < 10) Serial.print(F("0"));
 Serial.print(Inow.minute(), DEC);
 Serial.print(F(":"));
 if (Inow.second() < 10) Serial.print(F("0"));
 Serial.print(Inow.second(), DEC);
 Serial.print(F("  "));
 Serial.print(Inow.day(), DEC);
 Serial.print(F("/"));
 Serial.print(Inow.month(), DEC);
 Serial.print(F("/"));
 Serial.println(Inow.year(), DEC); 
}
 
//--------------------------------------------
// CLOCK utility function prints time to serial
//--------------------------------------------
void Print_tijd(void)
{
 if (Ihour < 10) Serial.print(F("0"));
 Serial.print(Ihour);
 Serial.print(F(":"));
 if (Iminute < 10) Serial.print(F("0"));
 Serial.print(Iminute);
 Serial.print(F(":"));
 if (Isecond < 10) Serial.print(F("0"));
 Serial.println(Isecond);
}
 
//--------------------------------------------
// DCF77 utility function prints DCF time
//--------------------------------------------
void digitalClockDisplay()
{
//  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(F(" "));
  Serial.print(day());
  Serial.print(F(" "));
  Serial.print(month());
  Serial.print(F(" "));
  Serial.print(year()); 
  Serial.println(); 
}
//--------------------------------------------
// DCF77 utility function prints preceding colon and leading 0
//--------------------------------------------
void printDigits(int digits)
{
  Serial.print(F(":"));
  if(digits < 10)
    Serial.print(F("0"));
  Serial.print(digits);
}
 
//--------------------------------------------
// DS3231 Set time in module and print it
//--------------------------------------------
void SetRTCTime(void)
{ 
 RTC.adjust(DateTime(Inow.year(), Inow.month(), Inow.day(), Ihour, Iminute, Isecond));
 GetTijd(0);                               // synchronize time with RTC clock
 Print_tijd();
}
 
//--------------------------------------------
//  CLOCK Input from  Serial
//--------------------------------------------
void ReworkInputString(String InputString)
{
 String temp;
 float ff;
 Serial.println(InputString);
 
if (InputString.length() > 3 && InputString.length() <7 )
 {
  temp = InputString.substring(0,2);   
  Ihour = temp.toInt(); 
  if (InputString.length() > 3) { temp = InputString.substring(2,4); Iminute = temp.toInt(); }
  if (InputString.length() > 5) { temp = InputString.substring(4,6); Isecond = temp.toInt(); }
  SetRTCTime();
 }
 InputString = "";
 temp = "";
}
 
//*****************


 
