#include "RTClib.h"
#include "U8g2lib.h"
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
// WS2812
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIN 6 // Pin für die Datenleitung
#define NUMPIXELS 16// Anzahl der WS2812 LEDs oder der NEOPIXEL
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
RTC_DS3231 rtc;
int WeckzeitStunden= 6;
int WeckzeitMinuten = 30;
int Wecker = 12; // Wecker Output (summer)
int LEDWeckerEin = 14; // LED WEcker EIN AUS (Anzeige)
int Taster1Weckzeit= 27 ;
int Taster2Uhrzeit= 26 ;//Rot
int Taster3Minuten= 25 ;
int Taster4Stunden= 33 ;
int Taster5Wecker= 32;
int setmin = 0 ;
int setstu = 0 ;
int setminuhr = 0 ;
int setstuuhr = 0 ;
int setwecker = 0 ;
int WeckerEINAUS= 0;
int Tasterstatus1Weck =0;
int Tasterstatus2Uhr =0;
int Tasterstatus3Min =0;
int Tasterstatus4Stun =0;
int Tasterstatus5Weck =0;
int Temperatur = 0;
int UhrzeitStunden = 0;
int UhrzeitMinuten = 0;
//Farbe sec
int secfarbeR =200;
int secfarbeG = 0;
int secfarbeB = 0;
//Farbe min
int minfarbeR = 0;
int minfarbeG = 200;
int minfarbeB = 0;
//Farbe stun
int stunfarbeR = 0;
int stunfarbeG = 0;
int stunfarbeB = 200;
// zur ausgabe der nummern der neopixel
int secbin1 = 0;
int secbin2 = 0;
int secbin4 = 0;
int secbin8 = 0;
int secbin16 = 0;
int secbin32 = 0;
int secbin64 = 0;
int minbin1 = 0;
int minbin2 = 0;
int minbin4 = 0;
int minbin8 = 0;
int minbin16 = 0;
int minbin32 = 0;
int minbin64 = 0;
int stunbin1 = 0;
int stunbin2 = 0;
int stunbin4 = 0;
int stunbin8 = 0;
int stunbin16 = 0;
int stunbin32 = 0;
int stunbin64 = 0;
/****** Zum berechnen Der KW /*************
*/
int year = 2014;
int month = 12;
int day = 29;
//U8G2_SH1106_128X64 u8g(U8G2_I2C_OPT_NONE); // I2C / TWI
//U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SH1106_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SH1106_128X64_VCOMH0_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but maximizes setContrast() range
/*
8-Bit-LED-Binaerzaehler mit einem Arduino UNO
Aufbau:
LEDs mit 220 Ohm Widerstaenden an Pins D5 bis D12
Druckschalter (Button) mit 10k Ohm Pullup-Widerstand an Pin D2
Quelle: https://www.roboter-bausatz.de/projekte/
*/
int sekunden = 0; //Variablen der aktuelen zeit zum rechnen
int minuten = 0;
int stunden = 0;
void setup()
{
u8g2.begin();
pixels.begin(); // Initialisierung der LEDs
Serial.begin (9600);
/* pinMode(19, OUTPUT); // Deklariere LED-Pins Sekunden als Outputs
pinMode(18, OUTPUT);
pinMode(5, OUTPUT);
pinMode(17, OUTPUT);
pinMode(16, OUTPUT);
pinMode(4, OUTPUT);
pinMode(0, OUTPUT);
pinMode(2, OUTPUT);
pinMode(15, OUTPUT); // Deklariere LED-Pins Minuten als Outputs
pinMode(8, OUTPUT);
pinMode(7, OUTPUT);
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(14, OUTPUT); // Deklariere LED-Pins Stunden als Outputs
pinMode(27, OUTPUT);
pinMode(26, OUTPUT);
pinMode(25, OUTPUT);
pinMode(33, OUTPUT);
pinMode(32, OUTPUT);
pinMode(32, OUTPUT);
pinMode(32, OUTPUT);*/
pinMode (Wecker,OUTPUT);
pinMode (LEDWeckerEin, OUTPUT);
pinMode (Taster1Weckzeit, INPUT);
pinMode (Taster2Uhrzeit, INPUT);
pinMode (Taster3Minuten, INPUT);
pinMode (Taster4Stunden, INPUT);
pinMode (Taster5Wecker, INPUT);
digitalWrite(Taster1Weckzeit, HIGH);
digitalWrite(Taster2Uhrzeit, HIGH);
digitalWrite(Taster3Minuten, HIGH);
digitalWrite(Taster4Stunden, HIGH);
digitalWrite(Taster5Wecker, HIGH);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
// When time needs to be re-set on a previously configured device, the
// following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
void loop()
{
DateTime now =rtc.now();
year=(now.year());
month=(now.month());
day=(now.day());
// put your main code here, to run repeatedly:
{
uint8_t WeekNr = GetWeekNumber(year, month, day); // die Wochennummer berechnen
char Datum[] = "Datum: DD.MM.YYYY";
char Zeit[] = "Uhrzeit hh:mm:ss";
Serial.print(" ");
Serial.print(now.hour(),DEC);
Serial.print(":");
Serial.print(now.minute(),DEC);
Serial.print(":");
Serial.print(now.second(),BIN);
Serial.print(" ");
Serial.print(now.toString(Datum));
Serial.print(" ");
Serial.print(now.toString(Zeit));
Serial.print(" ");
/*
Wochentag anzeigen
0 = Sonntag
1 = Montag
...
6 = Samstag
*/
switch (now.dayOfTheWeek())
{
case 0:
Serial.print("Sonntag");
break;
case 1:
Serial.print("Montag");
break;
case 2:
Serial.print("Dienstag");
break;
case 3:
Serial.print("Mittwoch");
break;
case 4:
Serial.print("Donnerstag");
break;
case 5:
Serial.print("Freitag");
break;
case 6:
Serial.print("Samstag");
break;
}
Serial.print(" ");
Serial.print(" ");
Serial.print(" ");
Serial.print("Weckzeit=");
Serial.print (WeckzeitStunden);
Serial.print(":");
Serial.print (WeckzeitMinuten);
Serial.print (" ");
Serial.print ("Wecker =");
Serial.print (WeckerEINAUS);
Serial.print(" ");
Serial.print (rtc.getTemperature());
Serial.print ("C°");
Serial.print(F("Wochennummer: "));
Serial.print(WeekNr);
Serial.print(" ");
Serial.print(secbin2);
Serial.print(secbin1);
Serial.println();
// Ab hier OLED Display
u8g2.setFont(u8g2_font_ncenB10_tr);
u8g2.firstPage();
do {
u8g2.setCursor(0, 20);
u8g2.print(now.toString(Zeit));
u8g2.setCursor(0, 40);
u8g2.print (now.toString(Datum));
u8g2.setCursor(0, 60);
u8g2.print ((String)rtc.getTemperature()+ " " + "°C");
u8g2.setCursor(80, 60);
u8g2.print ((String)WeekNr+ " " + "KW");
}while (u8g2.nextPage() );
}
//delay (1000);
Tasterstatus1Weck=digitalRead(Taster1Weckzeit);
Tasterstatus2Uhr=digitalRead(Taster2Uhrzeit);
Tasterstatus3Min=digitalRead(Taster3Minuten);
Tasterstatus4Stun=digitalRead(Taster4Stunden);
Tasterstatus5Weck=digitalRead(Taster5Wecker);
/************ Binäre Ausgabe LED ***************/
sekunden = (now.second());
// for (int zaehler = 0; zaehler < 255; zaehler++);
{
int a = sekunden % 2; // LSB berechnen (Least Significant Bit)
int b = sekunden / 2 % 2; // Der Modulo Operator % liefert die Restmenge einer Division. z. B. 5 % 2 = 1
int c = sekunden / 4 % 2;
int d = sekunden / 8 % 2;
int e = sekunden / 16 % 2;
int f = sekunden / 32 % 2;
int g = sekunden / 64 % 2;
int h = sekunden / 128 % 2; //MSB berechnen (Most Significant Bit)
digitalWrite(23, h); // Ausgabe MSB (LED mit hoechsten Stellenwert)
digitalWrite(23, g);
digitalWrite(23, f);
digitalWrite(23, e);
digitalWrite(23, d);
digitalWrite(23, c);
digitalWrite(23, b);
digitalWrite(23, a); // Ausgabe LSB (LED mit dem niedrigsten Stellenwert)
if ( a == HIGH)
{secbin1 = 1;}
else
{secbin1 = 0;}
if ( b == HIGH)
{secbin2 = 1;}
else
{secbin2 = 0;}
if ( c == HIGH)
{secbin4 = 1;}
else
{secbin4 = 0;}
if ( d == HIGH)
{secbin8 = 1;}
else
{secbin8 = 0;}
if ( e == HIGH)
{secbin16 = 1;}
else
{secbin16 = 0;}
if ( f == HIGH)
{secbin32 = 1;}
else
{secbin32 = 0;}
}
if (Tasterstatus1Weck == LOW) // umschlatung von Uhr zu Weckzeit anzeige
{
minuten = WeckzeitMinuten;
}
else
{
minuten =(now.minute());
}
//minuten = (aktuell.minute());
// for (int zaehler = 0; zaehler < 255; zaehler++);
{
int a = minuten % 2; // LSB berechnen (Least Significant Bit)
int b = minuten / 2 % 2; // Der Modulo Operator % liefert die Restmenge einer Division. z. B. 5 % 2 = 1
int c = minuten / 4 % 2;
int d = minuten / 8 % 2;
int e = minuten / 16 % 2;
int f = minuten / 32 % 2;
int g = minuten / 64 % 2;
int h = minuten / 128 % 2; //MSB berechnen (Most Significant Bit)
digitalWrite(23, h); // Ausgabe MSB (LED mit hoechsten Stellenwert)
digitalWrite(23, g);
digitalWrite(23, f);
digitalWrite(23, e);
digitalWrite(23, d);
digitalWrite(23, c);
digitalWrite(23, b);
digitalWrite(23, a); // Ausgabe LSB (LED mit dem niedrigsten Stellenwert)
if ( a == HIGH)
{minbin1 = 1;}
else
{minbin1 = 0;}
if ( b == HIGH)
{minbin2 = 1;}
else
{minbin2 = 0;}
if ( c == HIGH)
{minbin4 = 1;}
else
{minbin4 = 0;}
if ( d == HIGH)
{minbin8 = 1;}
else
{minbin8 = 0;}
if ( e == HIGH)
{minbin16 = 1;}
else
{minbin16 = 0;}
if ( f == HIGH)
{minbin32 = 1;}
else
{minbin32 = 0;}
}
if (Tasterstatus1Weck == LOW) // umschlatung von Uhr zu WEckzeit anzeige Stunden
{
stunden = WeckzeitStunden;
}
else
{
stunden =(now.hour());
}
// stunden = (aktuell.hour());
//for (int zaehler = 0; zaehler < 255; zaehler++);
{
int a = stunden % 2; // LSB berechnen (Least Significant Bit)
int b = stunden / 2 % 2; // Der Modulo Operator % liefert die Restmenge einer Division. z. B. 5 % 2 = 1
int c = stunden / 4 % 2;
int d = stunden / 8 % 2;
int e = stunden / 16 % 2;
int f = stunden / 32 % 2;
int g = stunden / 64 % 2;
int h = stunden / 128 % 2; //MSB berechnen (Most Significant Bit)
digitalWrite(23, h); // Ausgabe MSB (LED mit hoechsten Stellenwert)
digitalWrite(23, g);
digitalWrite(23, f);
digitalWrite(23, e);
digitalWrite(23, d);
digitalWrite(23, c);
digitalWrite(23, b);
digitalWrite(23, a); // Ausgabe LSB (LED mit dem niedrigsten Stellenwer
if ( a == HIGH)
{stunbin1 = 1;}
else
{stunbin1 = 0;}
if ( b == HIGH)
{stunbin2 = 1;}
else
{stunbin2 = 0;}
if ( c == HIGH)
{stunbin4 = 1;}
else
{stunbin4 = 0;}
if ( d == HIGH)
{stunbin8 = 1;}
else
{stunbin8 = 0;}
if ( e == HIGH)
{stunbin16 = 1;}
else
{stunbin16 = 0;}
if ( f == HIGH)
{stunbin32 = 1;}
else
{stunbin32 = 0;}
}
/******AB hier ausgabe WS2812 *********************/
if ( secbin1 == HIGH)
{pixels.setPixelColor(0, pixels.Color(secfarbeR,secfarbeG,secfarbeB));}
else
{pixels.setPixelColor(0, pixels.Color(0,0,0));}
if ( secbin2 == HIGH)
{pixels.setPixelColor(1, pixels.Color(secfarbeR,secfarbeG,secfarbeB));}
else
{pixels.setPixelColor(1, pixels.Color(0,0,0));}
if ( secbin4 == HIGH)
{pixels.setPixelColor(2, pixels.Color(secfarbeR,secfarbeG,secfarbeB));}
else
{pixels.setPixelColor(2, pixels.Color(0,0,0));}
if ( secbin8 == HIGH)
{pixels.setPixelColor(3, pixels.Color(secfarbeR,secfarbeG,secfarbeB));}
else
{pixels.setPixelColor(3, pixels.Color(0,0,0));}
if ( secbin16 == HIGH)
{pixels.setPixelColor(4, pixels.Color(secfarbeR,secfarbeG,secfarbeB));}
else
{pixels.setPixelColor(4, pixels.Color(0,0,0));}
if ( secbin32 == HIGH)
{pixels.setPixelColor(5, pixels.Color(secfarbeR,secfarbeG,secfarbeB));}
else
{pixels.setPixelColor(5, pixels.Color(0,0,0));}
/******** Minuten **************/
if ( minbin1 == HIGH)
{pixels.setPixelColor(6, pixels.Color(minfarbeR,minfarbeG,minfarbeB));}
else
{pixels.setPixelColor(6, pixels.Color(0,0,0));}
if ( minbin2 == HIGH)
{pixels.setPixelColor(7, pixels.Color(minfarbeR,minfarbeG,minfarbeB));}
else
{pixels.setPixelColor(7, pixels.Color(0,0,0));}
if ( minbin4 == HIGH)
{pixels.setPixelColor(8, pixels.Color(minfarbeR,minfarbeG,minfarbeB));}
else
{pixels.setPixelColor(8, pixels.Color(0,0,0));}
if ( minbin8 == HIGH)
{pixels.setPixelColor(9, pixels.Color(minfarbeR,minfarbeG,minfarbeB));}
else
{pixels.setPixelColor(9, pixels.Color(0,0,0));}
if ( minbin16 == HIGH)
{pixels.setPixelColor(10, pixels.Color(minfarbeR,minfarbeG,minfarbeB));}
else
{pixels.setPixelColor(10, pixels.Color(0,0,0));}
if ( minbin32 == HIGH)
{pixels.setPixelColor(11, pixels.Color(minfarbeR,minfarbeG,minfarbeB));}
else
{pixels.setPixelColor(11, pixels.Color(0,0,0));}
/******** Stunden **************/
if ( stunbin1 == HIGH)
{pixels.setPixelColor(12, pixels.Color(stunfarbeR,stunfarbeG,stunfarbeB));}
else
{pixels.setPixelColor(12, pixels.Color(0,0,0));}
if ( stunbin2 == HIGH)
{pixels.setPixelColor(13, pixels.Color(stunfarbeR,stunfarbeG,stunfarbeB));}
else
{pixels.setPixelColor(13, pixels.Color(0,0,0));}
if ( stunbin4 == HIGH)
{pixels.setPixelColor(14, pixels.Color(stunfarbeR,stunfarbeG,stunfarbeB));}
else
{pixels.setPixelColor(14, pixels.Color(0,0,0));}
if ( stunbin8 == HIGH)
{pixels.setPixelColor(15, pixels.Color(stunfarbeR,stunfarbeG,stunfarbeB));}
else
{pixels.setPixelColor(15, pixels.Color(0,0,0));}
if ( stunbin16 == HIGH)
{pixels.setPixelColor(16, pixels.Color(stunfarbeR,stunfarbeG,stunfarbeB));}
else
{pixels.setPixelColor(16, pixels.Color(0,0,0));}
if ( stunbin32 == HIGH)
{pixels.setPixelColor(17, pixels.Color(stunfarbeR,stunfarbeG,stunfarbeB));}
else
{pixels.setPixelColor(17, pixels.Color(0,0,0));}
pixels.show(); // Senden der aktualisierten Daten an die WS2812 LEDs
pixels.clear(); // Deaktivieren aller LEDs
/************** AB HIER WECKER********************/
// Wecker Vergleicht minunten und stunden und bei gleich löst er wecker aus
// bei nicht gleich (else) schaltet er aus
if ((WeckzeitMinuten == (now.minute())) & ((WeckerEINAUS== 1)) & (WeckzeitStunden == (now.hour())))
{
digitalWrite (Wecker, HIGH );
}
if ( ((WeckerEINAUS== 0)) )
{
digitalWrite (Wecker, LOW );
}
// Wecker EIN AUS Schalten
if (Tasterstatus5Weck==LOW && setwecker==0)
{
WeckerEINAUS++;
setwecker=1;
}
if (Tasterstatus5Weck == HIGH && setwecker == 1) {
delay(250);
setwecker=0;
}
if (WeckerEINAUS > 1)
{
WeckerEINAUS=0;
}
// LED ob Wecker Ein AUS
if (WeckerEINAUS == HIGH & (Tasterstatus1Weck == LOW) )
{
digitalWrite (LEDWeckerEin, HIGH);
}
else
{digitalWrite(LEDWeckerEin, LOW);
}
// Ab hier weckzeit einstellen Minuten
if (Tasterstatus3Min==LOW && setmin==0)
{
WeckzeitMinuten++;
setmin=1;
}
if (Tasterstatus3Min == HIGH && Tasterstatus1Weck == LOW &&setmin == 1) {
delay(250);
setmin=0;
}
if (WeckzeitStunden > 23)
{
WeckzeitStunden=0;
}
// Ab hier weckzeit einstellen Stunden
if (Tasterstatus4Stun==LOW && setstu==0)
{
WeckzeitStunden++;
setstu=1;
}
if (Tasterstatus4Stun == HIGH && Tasterstatus1Weck == LOW && setstu == 1) {
delay(250);
setstu=0;
}
if (WeckzeitMinuten > 59)
{
WeckzeitMinuten=0;
}
//ab Hier Uhrzeiteinstellen
if (Tasterstatus2Uhr == LOW)
{ rtc.adjust(DateTime(2020, 10, 28, UhrzeitStunden, UhrzeitMinuten, 30));} // Es wird die Uhr Gestellt
//Stunden einstellen
if (Tasterstatus4Stun==LOW && setstuuhr==0)// Stunden Einstelllen
{
UhrzeitStunden++;
setstuuhr=1;
}
if (Tasterstatus4Stun == HIGH && setstuuhr == 1) {
delay(250);
setstuuhr=0;
}
if (UhrzeitStunden > 23)
{
UhrzeitStunden=0;
}
//Minuten einstellen
if (Tasterstatus3Min==LOW && setminuhr==0)// Stunden Einstelllen
{
UhrzeitMinuten++;
setminuhr=1;
}
if (Tasterstatus3Min == HIGH && setminuhr == 1) {
delay(250);
setminuhr=0;
}
if (UhrzeitMinuten > 59)
{
UhrzeitMinuten=0;
}
/***************** AB Hier Datum Einstellen */
// wenn Taster Uhrzeit und wecker gedrückt sind kann mit den 3 tastern Minuten Stunden * Wecker (Ein AUS ) Tage Monate und Jahre verstellt werden
}
const int t_Table[] PROGMEM = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
/***** Den Wochentag nach ISO 8601 (1 = Mo, 2 = Di, 3 = Mi, 4 = Do, 5 = Fr, 6 = Sa, 7 = So) berechnen *****/
uint8_t GetWeekday(uint16_t y, uint8_t m, uint8_t d) {
y -= m < 3;
uint8_t wd = (y + y / 4 - y / 100 + y / 400 + pgm_read_word(t_Table + m - 1) + d) % 7;
return (wd == 0 ? 7 : wd);
}
/***** Die Wochennummer nach ISO 8601 berechnen *****/
uint8_t GetWeekNumber(uint16_t y, uint8_t m, uint8_t d) {
bool LeapYear;
uint16_t doy = GetDayOfYear(y, m, d); // Anzahl der Tage im Jahr ermitteln
uint8_t wd = GetWeekday(y, m, d); // Wochentag ermitteln
uint8_t wnr = (doy - wd + 7) / 7; // die Wochennummer berechnen
switch (wnr) {
case 0: // wenn die Wochennummer Null ergibt, dann liegt der Tag am Anfang des Jahres (1. Sonderfall)
wd = GetWeekday(y - 1, 12, 31); // den letzten Wochentag aus dem Vorjahr ermitteln
LeapYear = IsLeapYear(y - 1); // ermitteln, ob es sich beim Vorjahr um ein Schaltjahr handelt
break; // und nach dem Switch weitermachen...
case 52: // wenn die Wochennummer 52 ergibt, dann liegt der Tag am Ende des Jahres (2. Sonderfall)
wd = GetWeekday(y, 12, 31); // den letzten Wochentag aus diesem Jahr ermitteln
LeapYear = IsLeapYear(y); // ermitteln, ob es sich bei diesem Jahr um ein Schaltjahr handelt
break; // und nach dem Switch weitermachen...
default: // in den anderen Faellen kann die Funktion
return wnr; // hier verlassen und die Wochennummer zurueckgegeben werden
}
if (wd < 4) { // wenn der 31.12. vor dem Donnerstag liegt, dann...
wnr = 1; // ist das die erste Woche des Jahres
} else { // anderenfalls muss ermittelt werden, ob es eine 53. Woche gibt (3. Sonderfall)
/* wenn der letzte Wochentag auf einen Donnerstag oder, */
/* in einem Schaltjahr, auf einen Donnerstag oder Freitag fällt, */
/* dann ist das die 53. Woche, ansonsten die 52. Woche. */
wnr = ((wd == 4) || (LeapYear && wd == 5)) ? 53 : 52;
}
return wnr;
}
const uint16_t mdays_Table[] PROGMEM = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
/***** die Anzahl der Tage (Tag des Jahres) berechnen *****/
uint16_t GetDayOfYear(uint16_t y, uint8_t m, uint8_t d) {
return d + pgm_read_word(mdays_Table + m - 1) + (m >= 2 && IsLeapYear(y));
}
/***** Testen, ob das Jahr ein Schaltjahr ist *****/
bool IsLeapYear(uint16_t y) {
return !(y % 4) && ((y % 100) || !(y % 400)); // Schaltjahrberechnung (true = Schaltjahr, false = kein Schaltjahr)
}FPS: 0
Power: 0.00W
Power: 0.00W