#include "Wire.h"
int impulseArray[60];
int impulseCount = 0;
int actualHours, actualMinutes, actualSecond, actualDay, actualMonth, actualYear, DayOfW;
//BEGIN RTC CODE
//rtc variables
int second, minute, hour;
int dayOfWeek, dayOfMonth, month, year;
//end rtc variables
#define DS3231_I2C_ADDRESS 0x68
byte decToBcd(byte val) {
return ( (val / 10 * 16) + (val % 10) );
}
// Convert binary coded decimal to decimal numbers
byte bcdToDec(byte val) {
return ( (val / 16 * 10) + (val % 16) );
}
// Set the time
void rtc_setTime(byte second, byte minute, byte hour, byte wday, byte mday, byte mon, byte year) {
// sets time and date data to DS3231
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set next input to start at the seconds register
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(wday)); // set day of week (1=Monday, 7=Sunday)
Wire.write(decToBcd(mday)); // set date (1 to 31)
Wire.write(decToBcd(mon)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}
void rtc_readTime() {
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set DS3231 register pointer to 00h
Wire.endTransmission();
// request seven bytes of data from DS3231 starting from register 00h
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
second = bcdToDec(Wire.read() & 0x7f);
minute = bcdToDec(Wire.read());
hour = bcdToDec(Wire.read() & 0x3f);
dayOfWeek = bcdToDec(Wire.read());
dayOfMonth = bcdToDec(Wire.read());
month = bcdToDec(Wire.read());
year = bcdToDec(Wire.read());
//leap year correction
#define LEAP_YEAR(Y) ( !(((Y))%4) && ( (((Y))%100) || !(((Y))%400) ) )
if(LEAP_YEAR(year) == 0 && dayOfMonth == 29 && month == 2){
rtc_setTime(second, minute, hour, dayOfWeek, 1, 3, year);
}
}
void rtc_init(){
Wire.begin();
}
//END RTC CODE
int dcf_out = 11;
uint32_t previous;
bool dst = false;
void setup() {
rtc_init();
pinMode(dcf_out, OUTPUT);
Serial.begin(115200);
convertDcf();
while(second != 0){
rtc_readTime();
if(second == 0){
break;
}
}
}
void loop() {
rtc_readTime();
if(millis() - previous >= 100){
convertDcf();
dcfOut();
previous = millis();
}
}
int monthVal(){
int val = 30;
if(month == 1){
val = 31;
}
if(month == 2 && !LEAP_YEAR(year)){
val = 28;
}
if(month == 2 && LEAP_YEAR(year)==1){
val = 29;
}
if(month == 3){
val = 31;
}
if(month == 4){
val = 30;
}
if(month == 5){
val = 31;
}
if(month == 6){
val = 30;
}
if(month == 7){
val = 31;
}
if(month == 8){
val = 31;
}
if(month == 9){
val = 30;
}
if(month == 10){
val = 31;
}
if(month == 11){
val = 30;
}
if(month == 12){
val = 31;
}
return val;
}
void convertDcf() {
rtc_readTime();
DayOfW = dayOfWeek-1;
if (DayOfW == 0) DayOfW = 7;
actualDay = dayOfMonth;
actualMonth = month;
actualYear = year % 100;
actualHours = hour;
actualMinutes = minute + 1;
actualSecond = second;
if (actualSecond >= 60){ actualSecond = 0;}
if (actualMinutes >= 60){ actualMinutes = 0; actualHours += 1;}
if (actualHours >= 24){ actualHours = 0; DayOfW += 1; actualDay += 1;}
if (DayOfW >= 8){ DayOfW = 1;}
if (actualDay > monthVal()){ actualDay - monthVal(); actualMonth += 1;}
if (actualMonth >= 13){ DayOfW = 1; actualYear += 1;}
if (actualYear >= 100){ actualYear = 0;}
int n, Tmp, TmpIn;
int ParityCount = 0;
//we put the first 20 bits of each minute at a logical zero value
for (n = 0; n < 20; n++) impulseArray[n] = 1;
// set DST bit
if (dst == false) {
impulseArray[18] = 2; // CET or DST OFF
} else {
impulseArray[17] = 2; // CEST or DST ON
}
//bit 20 must be 1 to indicate active time
impulseArray[20] = 2;
//calculates the bits for the minutes
TmpIn = Bin2Bcd(actualMinutes);
for (n = 21; n < 28; n++) {
Tmp = TmpIn & 1;
impulseArray[n] = Tmp + 1;
ParityCount += Tmp;
TmpIn >>= 1;
}
if ((ParityCount & 1) == 0)
impulseArray[28] = 1;
else
impulseArray[28] = 2;
//calculates bits for the hours
ParityCount = 0;
TmpIn = Bin2Bcd(actualHours);
for (n = 29; n < 35; n++) {
Tmp = TmpIn & 1;
impulseArray[n] = Tmp + 1;
ParityCount += Tmp;
TmpIn >>= 1;
}
if ((ParityCount & 1) == 0)
impulseArray[35] = 1;
else
impulseArray[35] = 2;
ParityCount = 0;
//calculate the bits for the actual Day of Month
TmpIn = Bin2Bcd(actualDay);
for (n = 36; n < 42; n++) {
Tmp = TmpIn & 1;
impulseArray[n] = Tmp + 1;
ParityCount += Tmp;
TmpIn >>= 1;
}
TmpIn = Bin2Bcd(DayOfW);
for (n = 42; n < 45; n++) {
Tmp = TmpIn & 1;
impulseArray[n] = Tmp + 1;
ParityCount += Tmp;
TmpIn >>= 1;
}
//calculates the bits for the actualMonth
TmpIn = Bin2Bcd(actualMonth);
for (n = 45; n < 50; n++) {
Tmp = TmpIn & 1;
impulseArray[n] = Tmp + 1;
ParityCount += Tmp;
TmpIn >>= 1;
}
//calculates the bits for actual year
TmpIn = Bin2Bcd(actualYear); // 2 digit year
for (n = 50; n < 58; n++) {
Tmp = TmpIn & 1;
impulseArray[n] = Tmp + 1;
ParityCount += Tmp;
TmpIn >>= 1;
}
//equal date
if ((ParityCount & 1) == 0)
impulseArray[58] = 1;
else
impulseArray[58] = 2;
//last missing pulse
impulseArray[59] = 0; // No pulse
}
int Bin2Bcd(int dato) {
int msb, lsb;
if (dato < 10)
return dato;
msb = (dato / 10) << 4;
lsb = dato % 10;
return msb + lsb;
}
void dcfOut(){
for(int i = 0; i < 60; i++){
if(impulseArray[i] == 1){
digitalWrite(dcf_out,1);
delay(100);
digitalWrite(dcf_out,0);
delay(900);
}
if(impulseArray[i] == 2){
digitalWrite(dcf_out,1);
delay(200);
digitalWrite(dcf_out,0);
delay(800);
}
if(impulseArray[i] == 0){
digitalWrite(dcf_out,0);
delay(901);
}
}
}