NittyGritty icon

JahresSchaltUhr.ino

NittyGritty | PRO | 03/25/18 11:58:01 AM UTC | 0 ⭐ | 513 👁️ | Never ⏰ | []
C++ |

14.33 KB

|

None

|

0 👍

/

0 👎

#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