#include <stdio.h>
#include <Wire.h>
#include <Time.h>
#include <Timezone.h>
#include <string.h>
#include <DS3232RTC.h> // A DS3231/DS3232 library
#include <TimeLord.h>
// west longitude and north lattitude - approximate -
// I'm not giving you my address in an online code example anyway... :-)
// 48.8143634,8.9808786
double Lw = 8.9808786;
double Ln = 48.8143634;
// 51.5023276,13.2808041
// double Ln = 51.5023276;
// double Lw = 13.2808041;
// Adjust this block of code if you have another LCD (e.g. direct connected)
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin, BACKLIGHT_PIN, POSITIVE);
// =============================================
// it's a 16x2 LCD so...
int screenWidth = 24;
int screenHeight = 2;
int countMovement = 0;
int stringStart = 0;
int stringStop = 0;
int scrollCursor = 0;
char cb[40];
char* weekdays[] = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" };
//Central European Time (Frankfurt, Paris)
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; //Central European Summer Time
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; //Central European Standard Time
Timezone CE(CEST, CET);
TimeChangeRule *tcr; //pointer to the time change rule, use to get TZ abbrev
time_t utc, local;
#define BUFF_MAX 128
// uint8_t time[8];
// char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;
int osec = -1;
int I = 50;
// Tor stuff
// Tor = 0 - auf
// Tor = 1 - zu
// Stunden 0 1 2 3 4 5 6 7 8 9
char* Torzeit [] = {"1", "1", "1", "1", "1", "1", "0", "0", "0", "0",
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0",
"1", "1", "1", "1"
};
//Wochentage So, Mo, Di, Mi, Do, Fr, Sa
char* TorTage [] = {"1", "0", "0", "0", "0", "0", "1" };
// Tor = Hour(t) > Tor TorZuZeit
boolean Tor = 0;
int Relay = 12;
const char compile_date[] = __DATE__ "-" __TIME__;
const char compile_file[] = __FILE__ ;
// ------------------------------------------------------------------------------
void setup()
{
pinMode(Relay, OUTPUT);
Serial.begin(9600);
lcd.begin(screenWidth, screenHeight); // LCD Hintergrundbeleuchtung aktivieren
lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
lcd.clear();
lcd.setCursor(0, 0);
// ------- Quick 3 blinks of backlight -------------
for(int i = 0; i< 3; i++)
{
lcd.backlight();
delay(250);
digitalWrite(Relay, LOW);
lcd.noBacklight();
delay(250);
digitalWrite(Relay, HIGH);
}
lcd.backlight(); // finish with backlight on
Serial.println(compile_date);
roop(0, compile_date, 100);
Serial.println(compile_file);
roop(1, compile_file, 100);
delay(1000);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
{
lcd.println(F("RTC sync Error"));
}
else
{
lcd.print(F("RTC sync OK"));
}
// memset(recv, 0, BUFF_MAX);
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
setTime(hour(),minute(),second(),day(),month(),(year()-2000) );
digitalClockDisplay();
CheckTor();
}
void loop()
{
if (second() != osec)
{
switch (second())
{
case 0:
break;
case 1:
CheckTor();
break;
case 15:
break;
case 30:
break;
case 45:
break;
}
osec = second();
digitalClockDisplay();
CheckClockSet();
}
}
// ---------------------------------------------------
// Tor = 0 - auf
// Tor = 1 - zu
// Tor = Hour(t) > Tor TorZuZeit
void CheckTor()
{
local = CE.toLocal(utc, &tcr);
boolean TestTor1 = CheckTorZeit(local, tcr -> abbrev);
sprintf(cb, "Lt. TorZeit soll Tor %s sein", (TestTor1)?"zu":"auf" ) ;
Serial.println(cb);
boolean TestTor2 = CheckTorTage(local, tcr -> abbrev);
sprintf(cb, "Lt. TorTag soll Tor %s sein", (TestTor2)?"zu":"auf" ) ;
Serial.println(cb);
local = CE.toLocal(utc, &tcr);
boolean TestFeiertag =feiertag(local, tcr -> abbrev); // Ermittelt ob heute ein Feiertag ist
sprintf(cb, "Heute ist %s Feiertag", (TestFeiertag)?"ein":"kein" ) ;
Serial.println(cb);
Tor = TestTor1 || TestTor2 || TestFeiertag;
sprintf(cb, "Tor ist %s", (Tor)?"zu":"auf" ) ;
Serial.println(cb);
digitalWrite(Relay, (Tor)?HIGH:LOW);
PrintSunRise();
}
boolean CheckTorZeit(time_t t, char *tz)
{
sprintf(cb, "Stunde %02d, Tor %s",hour(t), Torzeit[hour(t)] ) ;
Serial.println(cb);
if ( Torzeit[hour(t)] == "1" )
{
return true;
} else {
return false;
}
}
boolean CheckTorTage(time_t t, char *tz)
{
sprintf(cb, "Wochentag %01d, Tor %s",weekday(t), TorTage[weekday(t) - 1] ) ;
Serial.println(cb);
if ( TorTage[weekday(t) - 1] == "1" )
{
return true;
} else {
return false;
}
}
/*
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Scroll-row0");
scroll(0, "The quick brown fox jumps over the lazy dog",200);
*/
// ==========================================
void scroll(int row, String line, int speed) {
countMovement = 0;
stringStart = 0;
stringStop = 0;
scrollCursor = 0;
// Serial.print(countMovement); Serial.print("-"); Serial.println(line.length() + 1);
while ( ( countMovement ) < (line.length() + 2 ) )
{
lcd.setCursor(scrollCursor, row);
// Serial.print("Cursor: "); Serial.print(scrollCursor); Serial.print(" "); Serial.println(row);
lcd.print(line.substring(stringStart, stringStop));
// Serial.println( line.substring(stringStart, stringStop) );
delay(speed);
if (stringStart == 0 && scrollCursor > 0) {
// Serial.println(scrollCursor);
scrollCursor--;
stringStop++;
}
else if (stringStart == stringStop) {
stringStart = stringStop = 0;
scrollCursor = screenWidth;
}
else if (stringStop == line.length() && scrollCursor == 0) {
stringStart++;
}
else {
stringStart++;
stringStop++;
}
countMovement++;
}
}
// =================================================================
void digitalClockDisplay() {
utc = now();
local = CE.toLocal(utc, &tcr);
printTimeLCD(local, tcr -> abbrev);
}
void printTimeLCD(time_t t, char *tz) {
// lcd.clear();
lcd.setCursor(0, 0);
sprintf(cb, "%s %02d.%02d.%02d %s", (weekdays[weekday(t) - 1]), day(t), month(t), year(t) - 2000, tz);
lcd.print(cb);
lcd.setCursor(0, 1);
sprintf(cb, "%02d:%02d:%02d Tor %s", hour(t), minute(t), second(t), (Tor)?"zu ":"auf" ) ;
lcd.print(cb);
utc = now();
// printTime(utc, "UTC");
local = CE.toLocal(utc, &tcr);
printTime(local, tcr -> abbrev);
}
// ----------------------------------------------
// Function to print time with time zone
// ----------------------------------------------
void printTime(time_t t, char *tz)
{
sprintf(cb, "%s, %02d.%02d.%04d %02d:%02d:%02d %s", (weekdays[weekday(t) - 1]), day(t), month(t),year(t), hour(t), minute(t), second(t), tz ) ;
Serial.println(cb);
}
// ------------------------------------------------------------------------------------------------------
boolean feiertag(time_t t, char *tz)
{
String testDate;
int tag;
int monat=3;
int ostersonntag;
testDate = String(day(t)) +"."+ String(month(t));
// Zuerst die festen Feiertage
// Hinweis: 24.12 und 31.12 sind eigentlich keine Feiertage, werden aber hier als solche behandelt
if (testDate==("1.1")) { return true; } // Neujahr
if (testDate==("1.5")) { return true; } // Maifeiertag
if (testDate==("3.10")) { return true; } // Tag d. dt. Einheit
if (testDate==("24.12")) { return true; } // Heiligabend (eigentlich kein Feiertag)
if (testDate==("25.12")) { return true; } // Erster Weihnachtsfeirtag
if (testDate==("26.12")) { return true; } // Zweiter Weihnachsfeiertag
if (testDate==("31.12")) { return true; } // Silvester (eigentlich kein Feiertag)
// Nachfolgend einige Feiertage die nicht bundeseinheitlich sind: (ggf. auskommentieren)
if (testDate==("6.1")) { return true; } // Heilige Drei Könige (nur in best. Bundesländern)
//if (testDate==("15.8")) { return true; } // Mariae Himmelfahrt (nur im Saarland)
//if (testDate==("31.10")) { return true; } // Reformationstag (nur in best. Bundesländern)
if (testDate==("1.11")) { return true; } // Allerheiligen (nur in best. Bundesländern)
if (month(t)==3) { tag=day(t); } // Wenn März, aktuellen Tag ermitteln
if (month(t)==4) { tag=day(t)+31; }
if (month(t)==5) { tag=day(t)+31+30; }
if (month(t)==6) { tag=day(t)+31+30+31; }
ostersonntag = berechne_Ostern();
if (ostersonntag-2 ==tag) { return true; } // Karfreitag
if (ostersonntag ==tag) { return true; } // Ostersonntag
if (ostersonntag+1 ==tag) { return true; } // Ostermontag
if (ostersonntag+39==tag) { return true; } // Christi Himmelfahrt
if (ostersonntag+49==tag) { return true; } // Pfingstsonntag
if (ostersonntag+50==tag) { return true; } // Pfingstmontag
if (ostersonntag+60==tag) { return true; } // Fronleichnam (nicht bundeseinheitlich)
// Buss- und Bettag gibt es nur in einigen Bundeländern, also ggf. auskommentieren
// if (BussUndBettag()) {return true;}
return false;
}
int berechne_Ostern()
{
// nach der Gauß-Formel
// Rückgabewert: Datum von Ostern ab 1. März (max=56 für 25. April)
int a; int b; int c; int d; int e; int f; int k; int M; int N; int p; int q;
int jahr=year();
// Die "magische" Gauss-Formel anwenden:
a = jahr % 19;
b = jahr % 4;
c = jahr % 7;
k = jahr / 100;
p = (8*k+13) / 25;
q = k / 4;
M =(15 + k - p - q) % 30;
N = (4 + k-q) % 7;
d = (19*a + M) % 30;
e = (2*b + 4*c + 6*d + N) % 7;
f = 22+d+e; // Tag auf Maerz bezogen: 32 bedeutet Erster April usw.
if (f==57) {
f=50;
} // Wenn der 26. April ermittelt wird (31+26=57), dann muss Ostern am 19.4. sein (19+31=50)
/// Falls der 25. April ermittelt wird, gilt dies nur wenn d=28 und a>10
if ((f==56) && (d==28) && (a>10)) {
f=49;
}
return f;
}
// -------------------- kein Problem mit dem Datum und der Zeitzone, daher ohne (t) -----------------
boolean BussUndBettag()
{
// Buss- und Bettag fällt auf den Mittwoch zwischen demm 16. und 22. November
if ( (month()==11) && (day()>15) && (day ()< 23) )
{
if (weekday() == 4) {
return true;
} // Wenn heute Mittwoch ist
}
return false;
}
// ---------------------------------------------------
void CheckFeiertag ()
{
local = CE.toLocal(utc, &tcr);
boolean TestFeiertag = feiertag(local, tcr -> abbrev); // Ermittelt ob heute ein Feiertag ist
sprintf(cb, "Heute ist %s Feiertag\r\n", (TestFeiertag)?"ein":"kein" ) ;
Serial.print(cb);
}
// ------------------------------------------------------------------------
void CheckClockSet() {
if (Serial.available()) {
time_t t = processSyncMessage();
if (t > 0)
{
RTC.set(t); // set the RTC and the system time to the received value
setTime(t);
Serial.println("New Tiime has been set");
utc = now();
printTime(utc, "UTC");
local = CE.toLocal(utc, &tcr);
printTime(local, tcr -> abbrev);
}
} // if no input, just return
}
/* code to process time sync messages from the serial port */
#define TIME_MSG_LEN 11 // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER 'T' // Header tag for serial time sync message
time_t processSyncMessage() {
// return the time if a valid sync message is received on the serial port.
while (Serial.available() >= TIME_MSG_LEN ) { // time message consists of a header and ten ascii digits
char c = Serial.read() ;
Serial.print(c);
if ( c == TIME_HEADER ) {
time_t pctime = 0;
for (int i = 0; i < TIME_MSG_LEN - 1; i++) {
c = Serial.read();
if ( c >= '0' && c <= '9') {
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
}
}
return pctime;
}
}
return 0;
}
// ==========================================
void roop(int Reihe, String line2, int speed) {
countMovement = 0;
stringStart = 0;
stringStop = 0;
scrollCursor = 0;
// Serial.print(countMovement); Serial.print("-"); Serial.println(line2.length() + 1);
while ( ( countMovement ) < (line2.length() + 2 ) )
{
lcd.setCursor(scrollCursor, Reihe);
// Serial.print("Cursor: "); Serial.print(scrollCursor); Serial.print(" "); Serial.println(Reihe);
lcd.print(line2.substring(stringStart, stringStop));
// Serial.println( line2.substring(stringStart, stringStop) );
delay(speed);
if (stringStart == 0 && scrollCursor > 0) {
// Serial.println(scrollCursor);
scrollCursor--;
stringStop++;
} else if (stringStart == stringStop) {
stringStart = stringStop = 0;
scrollCursor = screenWidth;
} else if (stringStop == line2.length() && scrollCursor == 0) {
stringStart++;
} else {
stringStart++;
stringStop++;
}
countMovement++;
}
}
// ==============================================================================
void SunRise(time_t t, char *tz)
{
byte day1[] = { 0, 0, 12, day(t), month(t), year(t) }; // noon
TimeLord tardis;
tardis.TimeZone(2 * 60);
tardis.Position(Ln, Lw);
if (tardis.SunRise(day1))
{
sprintf(cb, "Sunrise: %02d:", (day1[tl_hour]) );
Serial.print(cb);
sprintf(cb, "%02d", (day1[tl_minute] ));
Serial.println(cb);
}
if (tardis.SunSet(day1))
{
// sprintf(cb, "Sunset: %02d:%02d", (day1[tl_hour], day1[tl_minute] ) ) ;
// Serial.println(cb);
sprintf(cb, "Sunset: %02d:", (day1[tl_hour]) );
Serial.print(cb);
sprintf(cb, "%02d", (day1[tl_minute] ));
Serial.println(cb);
}
}
void PrintSunRise()
{
local = CE.toLocal(utc, &tcr);
SunRise(local, tcr -> abbrev);
}
Comments