Benutzer-Werkzeuge

Webseiten-Werkzeuge


arduino:schlafphasenwecker:programmversion_0.5

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
arduino:schlafphasenwecker:programmversion_0.5 [27.12.2016 16:05] Frickelpietarduino:schlafphasenwecker:programmversion_0.5 [18.05.2023 12:34] (aktuell) – Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 ====== Schlafphasenwecker Programmversion 0.5 ====== ====== Schlafphasenwecker Programmversion 0.5 ======
-Die Namengebende Funktion des Weckers ist seine Fähigkeit, die Weckzeit an die Schlafphasen des Schlafenden anzupassen. Der Weckalarm zu einem Zeitpunkt ausgelöst werden, der für den Schlafenden am angenehmsten ist. Meine Annahme ist, dass das Wecken in einer Leichtschlafphase erfolgen sollte. Der Wecker muss also Fähig sein, Leichtschlafphasen von anderen Schlafphasen zu ermitteln. Möglich wäre das beispielsweise mittels einer  Elektroenzephalografie, aber die vielen Kabel am Kopf würden den Schlaf doch sehr stören. Insofern in den Phasen leichten Schlafs die Körperbewegungen zunehmen, sollte es möglich sein, Leichtschlafphasen durch die Messung von Körperbewegungen zu dedektieren. Zu diesem Zweck hat der Schlafphasenwecker einen Sensor, der unter der Matratze , etwa in der Körpermitte am Rattenrost befestigt wird.+<box 30% green right|**Achtung**>Dies ist eine alte Programmversion.</box>Die Namengebende Funktion des Weckers ist seine Fähigkeit, die Weckzeit an die Schlafphasen des Schlafenden anzupassen. Der Weckalarm zu einem Zeitpunkt ausgelöst werden, der für den Schlafenden am angenehmsten ist. Meine Annahme ist, dass das Wecken in einer Leichtschlafphase erfolgen sollte. Der Wecker muss also Fähig sein, Leichtschlafphasen von anderen Schlafphasen zu ermitteln. Möglich wäre das beispielsweise mittels einer  Elektroenzephalografie, aber die vielen Kabel am Kopf würden den Schlaf doch sehr stören. Insofern in den Phasen leichten Schlafs die Körperbewegungen zunehmen, sollte es möglich sein, Leichtschlafphasen durch die Messung von Körperbewegungen zu dedektieren. Zu diesem Zweck hat der Schlafphasenwecker einen Sensor, der unter der Matratze , etwa in der Körpermitte am Rattenrost befestigt wird.
  
-Die Programmversion 0.5 fokussiert auf die Auswertung der Daten dieses "Matraztensonsors". Der Matratzensosor ist Fähig, Beschleunigungen und Drehungen auf der X-, Y- und Z-Achse zu messen. Es wird bei meinem Bett an einem Teller eines Tempur-Flex-Systemrahmens befestigt. Um gute Messwerte zu erzielen, sollte der Abstand zwischen den Bewegungen des Sensors verursacht durch den Schlafenden auf der Matratze) und dem Rauschen des Sensors möglichst groß ausfallen. Da der Sensor sich bei der Befestigung an einem Lattenrost auf und ab, aber kaum nach vor und zurück oder seitlich bewegen kann, verspricht die Auswertung der Beschleunigungswerte auf der Z-Achse gute Messwerte. Bei der Befestigung an einem Teller eines Tempur-Lattenrostes sind darüber hinaus prinzipbedingt aber auch Drehbewegungen um die X- und Y-Achse möglich (Roll und Pitch).+Die Programmversion 0.5 fokussiert auf die Auswertung der Daten dieses "Matratzensonsors". Der Matratzensosor ist fähig, Beschleunigungen und Drehungen auf der X-, Y- und Z-Achse zu messen. Es wird bei meinem Bett an einem Teller eines Tempur-Flex-Systemrahmens befestigt. Um gute Messwerte zu erzielen, sollte der Abstand zwischen den Bewegungen des Sensors (verursacht durch den Schlafenden auf der Matratze) und dem Rauschen des Sensors möglichst groß ausfallen. Da der Sensor sich bei der Befestigung an einem Lattenrost auf und ab, aber kaum nach vor und zurück oder seitlich bewegen kann, verspricht die Auswertung der Beschleunigungswerte auf der Z-Achse gute Messwerte. Bei der Befestigung an einem Teller eines Tempur-Lattenrostes sind darüber hinaus prinzipbedingt aber auch Drehbewegungen um die X- und Y-Achse möglich (Roll und Pitch).
  
-Das Programm soll den Weckalarm in einem definierten Zeitfenster vor der eingestellten Weckzeit durch eine dedektierte Leichtschlafphase auslösen. Da gegen Ende der Nacht die Häufigkeit der Leichtschlafphasen zunimmt, wird dieses Zeitfenster zunächst auf 30 Minuten festgelegt. Da in meinem Bett auch zwei Katzen schlafen, muss a) der Sensor so positioniert und b) müssen die Sensordaten so ausgewertet werden, dass vor allem meine Bewegungen erfasst werden. Hierfür müssen gute Schwellenwerte empirisch ermittelt werden.+Diese drei Werte werden zunächst jeweils mit einem Kalman-Filter geglättet (ein ordinärer rolling average würde sicherlich auch seinen Zweck erfüllen). Anschließend wird der jeweils aktuellste Wert von dem geglätteten Wert substrahiert. Überschreitet die Differenz einen Schwellenwert, wird ein Eventzähler um den Wert 1 erhöht.  
 + 
 +Das Programm löst den Weckalarm in einem definierten Zeitfenster vor der eingestellten Weckzeit durch eine dedektierte Leichtschlafphase aus. Da gegen Ende der Nacht die Häufigkeit der Leichtschlafphasen zunimmt, kann dieses Zeitfenster auf 15, 30 oder 45 Minuten festgelegt werden. Da in meinem Bett auch zwei Katzen schlafen, muss a) der Sensor so positioniert und b) müssen die Sensordaten so ausgewertet werden, dass vor allem meine Bewegungen erfasst werden. Hierfür müssen gute Schwellenwerte empirisch ermittelt werden.
  
 Hilfreiche Links: Hilfreiche Links:
   * https://github.com/bachagas/Kalman   * https://github.com/bachagas/Kalman
   * https://de.wikipedia.org/wiki/Kalman-Filter   * https://de.wikipedia.org/wiki/Kalman-Filter
 +  * http://www.cbcity.de/das-kalman-filter-einfach-erklaert-teil-1
  
-In einer nächsten Programmversion müssen nun endlich die Audio-Funktionen integriert werden. Das wird nicht einfach ...+<code> 
 +// Schlafphasenwecker Version 0.5
  
-Hilfreiche Links: +// Bibliotheken einbinden 
-  * TPA 2016: https://learn.adafruit.com/adafruit-tpa2016-2-8w-agc-stereo-audio-amplifier/overview +#include <TimeLib.h>               // Stellt verschiedene Zeitfunktionen zur Verfügung 
-  * Wie man den Onboard SD Card Slot ans Laufen bekommt: https://forum.pjrc.com/threads/37652-microSD-slot-on-teensy-3-6+#include <EEPROM.h>                // Ermöglicht den Zugriff auf den EEPROM 
 +#include <DCF77.h>                 /Bibliothek für das DCF77-Modul 
 +#include <Adafruit_GFX.h>          // Core graphics library 
 +#include <SPI.h>                   // this is needed for display 
 +#include <Adafruit_ILI9341.h>      // TFT-Display 
 +#include <Wire.h>                  /this is needed for FT6206 
 +#include <Adafruit_FT6206.h>       // Kapazitiver Touchsensor 
 +#include <Adafruit_Sensor.h>       // Adafruit Unified Sensor Driver 
 +#include <Adafruit_TSL2591.h>      // Bibliothek für den Lichtsensor TSL2591 
 +#include <Adafruit_LSM303_U.h>     // Bibliothek für den Beschleunigungssensor LSM303 
 +#include <Adafruit_Simple_AHRS.h> 
 +#include <Kalman.h> 
 +//#include "SdFat.h"                 // The Arduino SdFat library provides read/write access to FAT16/FAT32 file systems on SD/SDHC flash cards 
 +#include <Fonts/FreeSans9pt7b.h>   // Font 
 +#include <Fonts/FreeSans12pt7b.h>  // Font 
 +#include <Fonts/FreeSans18pt7b.h>  // Font 
 +//#include <Fonts/FreeSans24pt7b.h>// Font
  
-Um die SDFat beta zum Laufen zu bringen, müssen im Board Manager die Arduino AVR Boards Version 1.6.11 installiert werden. 
-  * Die TeensySdioDemo läuft 
  
-<code+// Definiert Adressen im EEPROM 
-SdFatSdioEX uses extended multi-block transfers without DMA+int addrAlarmHour = 0; 
-SdFatSdio uses traditional DMA SDIO implementation+int addrAlarmMinute = 1; 
-Note the difference is speed and busy yield time.+int addrAlarmMode = 2; 
 +int addrDisplayedAlarmHour = 3; 
 +int addrDisplayedAlarmMinute = 4; 
 +//int addrAlarmAdvancetime = 5; 
 + 
 +// Definiert die Pins 
 +#define DCF_PIN 2                  // Connection pin to DCF 77 device 
 +#define DCF_INTERRUPT 2            // Interrupt number associated with pin 
 +#define TFTbacklightPin 7          // PWM Backlight TFT 
 + 
 +// Definiert die Farben für das Menü (im RGB585-Format) 
 +#define white 0xFFFF               // weiß 
 +#define black 0x0000               // schwarz 
 +#define red 0xF800                 // rot 
 +#define orange  0xFB20             // orange 
 + 
 +// Definiert die DCF77-Bibliothek 
 +DCF77 DCF = DCF77(DCF_PIN, DCF_INTERRUPT, false);  
 + 
 +// The FT6206 uses hardware I2C (SCL/SDA) 
 +Adafruit_FT6206 ctp = Adafruit_FT6206(); 
 + 
 +// The display also uses hardware SPI, plus #9 & #10 
 +#define TFT_CS 10                  // ChipSelect-Signal an Teensy-Pin 10 
 +#define TFT_DC 9                   // Data/Command-Signal an Teensy-Pin 9 
 +Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); 
 + 
 +//  pass in a number for the sensor identifier (for your use later) 
 +Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); 
 + 
 +/* Assign a unique ID to this sensor at the same time */ 
 +Adafruit_LSM303_Accel_Unified accel(30301); 
 +Adafruit_LSM303_Mag_Unified   mag(30302); 
 + 
 +// Create simple AHRS algorithm using the above sensors. 
 +Adafruit_Simple_AHRS          ahrs(&accel, &mag); 
 + 
 +// Definiert die Variablen 
 +int flankUp = 0; 
 +int flankDown = 0; 
 +int PreviousflankUp; 
 +bool Up = false; 
 + 
 +boolean IMUconnected = false;             // Wird wahr, wenn die IMU gefunden wurde. 
 +boolean DCFtimesignalFound = false;       // Wird wahr, sobald ein DCF77-Zeitzeichen erfolgreich empfangen wurde. 
 + 
 +time_t DCFtime = 0;                       // Das aktuelleste erfolgreich empfangene Zeitzeichen im Variablenformat time_t (Sekunden seit dem 1.1.1970) 
 +time_t t = 0;                             // Die Zeit der Real Time Clock im Variablenformat time_t (Sekunden seit dem 1.1.1970) 
 +time_t DefaultTime = 1477958400;          // Die bis zum 1.11.2016 verstrichene Zeit in Sekunden seit dem 1.1.1970. 
 +unsigned long lastDCFsignal;              // Zeit in Millisekunden, sie seit dem letzten erfolgrich empfangenen DCF77-Zeitzeichen vergangen ist. 
 +unsigned long noDCFsignal;                // Zeit in Millisekunden, die seit dem Systemstart bis zum ersten erfolgreich empfangenen DCF-Zeitzeichen vergangen ist. 
 +unsigned long currentDCFsignal; 
 +unsigned long receivedDCFsignals = 0;     // Zählt die Anzahl der erfolgreich empfangenen DCF77-Zeitzeichen seit dem Systemstart. 
 +float DCFsuccessRate = 0;                 // Wert für die Quote der erfolgreich empfangenen DCF77-Zeitzeichen seit dem Systemstart. 
 + 
 + 
 +int displayedAlarmHour = 6;               // Stunde, die auf dem TFT als Alarmzeit angezeigt wird. Wird als Integer definiert, damit die Variable theoretisch negativ werden kann. (Das ist für den Rollover von 0 auf 23 nötig.) 
 +int displayedAlarmMinute = 0;             // Minute, die auf dem TFT als Alarmzeit angezeigt wird. Wird als Integer definiert, damit die Variable theoretisch negativ werden kann. (Das ist für den Rollover von 0 auf 45 nötig.) 
 +int alarmHour = 5;                        // Stunde, zu der ein schlafphasensensibler Alarm frühestens ausgelöst werden soll. Wird als Integer definiert, damit die Variable theoretisch negativ werden kann. (Das ist für den Rollover von 0 auf 23 nötig.) 
 +int alarmMinute = 30;                      // Minute, zu der ein schlafphasensensibler Alarm frühestens ausgelöst werden soll. Wird als Integer definiert, damit die Variable theoretisch negativ werden kann. (Das ist für den Rollover von 0 auf 45 nötig.) 
 +int alarmAdvancetime = 30;                // Größe des Zeitfensters in Minuten, in der der schlafphasensensible Alarm ausgelöst werden kann.  
 +byte alarmMode = 0;                       // Alarmmodus (0 = Alarm aus) 
 +boolean alarmOn = false;                  // Wird wahr, so lange ein Alarm läuft 
 + 
 + 
 +uint16_t ir;                              // Helligkeitswert für den Infrarotanteil des Lichts 
 +uint16_t full;                            // Helligkeitswert für das Infrarotanteil und das sichtbare Licht 
 +uint32_t lum; 
 +uint16_t lux; 
 + 
 +float accelX; 
 +float accelY; 
 +double accelZ, filteredAccelZ; 
 + 
 +double roll, filteredRoll; 
 +double pitch, filteredPitch; 
 +float heading; 
 + 
 +Kalman accelZFilter(0.25,8,1023,0);  //suggested initial values for high noise filtering (q [process noise covariance], r [measurement noise covariance], p [estimation error covariance], x [value]) 
 +Kalman rollFilter(0.25,8,1023,0);    //suggested initial values for high noise filtering 
 +Kalman pitchFilter(0.25,8,1023,0);   //suggested initial values for high noise filtering 
 + 
 +int eventAccelZ = 0;                      // Zählt Ereignisse auf der Beschleunigungsachse Z 
 +int eventRoll = 0;                        // Zählt Ereignisse auf der Rollachse 
 +int eventPitch = 0;                       // Zählt Ereignisse auf der Pitchachse 
 +int eventTotal = 0; 
 + 
 +boolean touch = false; 
 +boolean prevtouch = false; 
 +boolean touch2 = false; 
 +boolean prevtouch2 = false; 
 + 
 +boolean TFTbacklightOn = false;       // Wird wahr, sobald das TFT Backlight an ist 
 +byte TFTbrightness = 0;                   // Wert für die aktuelle Helligkeit des TFT Backlights 
 +//byte TFTmaxbrightness = 255;            // Wert für die maximale Helligkeit des TFT backlights 
 +//byte TFTminbrightness = 0;              // Wert für die minimale Helligkeit des TFT backlights 
 +const unsigned long TFTbacklightDelay = 60000; // Zeit in Millisekunden, nach der das TFT Backlight abgeschaltet wird. 
 +unsigned long TFTbacklightTime = 0;    
 +boolean TFTrefresh = false;                  // Wird true, wenn ein Menü aktualisiert werden soll 
 + 
 + 
 +byte menuPage = 0;                        // Wert für das aktuell auf dem TFT angezeigten Menü. Gestartet wird mit Menü Nr. 0. 
 +byte previousmenuPage = 1;                // Wert für die Menüseite, die in dem vormaligen Durchlauf aktuell war. 
 +int tx;                                   // Auf dem Touchscreen gedrücktes Pixel auf der x-Achse. Pixelspalte Nr. 0 ist links. 
 +int ty;                                   // Auf dem Touchscreen gedrücktes Pixel auf der y-Achse. Pixelzeile Nr. 0 ist oben. 
 + 
 + 
 +// Definiert die Tracking-Variablen für die IF-Abfragen 
 +unsigned long previousMillisSetRTC = 0; 
 +unsigned long previousMillisAlarmClock = 0; 
 +unsigned long previousMillisTFTScreen = 0; 
 +unsigned long previousMillisTouchScreen = 0; 
 +unsigned long previousMillisSensorData = 0; 
 +unsigned long previousMillisSerialPrint = 0; 
 +unsigned long previousMillisDCFPulseLength = 0; 
 + 
 +// Definiert die Intervalle für die IF-Abfragen in Millisekunden 
 +const unsigned long intervalSetRTC = 1000;        // konstanter Delay für Holen der Zeit 
 +const unsigned long intervalAlarmClock = 1000;    // konstanter Delay für die Weckfunktionen 
 +unsigned long intervalTFTScreen = 100;            // variabler Delay für Anteuerung des TFT-Screens 
 +const unsigned long intervalTouchScreen = 50;     // konstanter Delay für Anteuerung des kapazitiven Touchsreens 
 +const unsigned long intervalSensorData = 100;     // konstanter Delay für Auslesen der Sensoren 
 +const unsigned long intervalSerialPrint = 100;   // konstanter Delay für serielle Ausgabe 
 +const unsigned long intervalDCFPulseLength = 1;   // konstanter Delay für die Messung der Periode und Pulsweite des Zeitsignals 
 + 
 + 
 +void setup() 
 +  // Initalisiert die Pins 
 +  pinMode(DCF_PIN, INPUT_PULLUP);                 // DFC77-Modul 
 +  pinMode(TFTbacklightPin, OUTPUT);               // PWM für TFT Backlight 
 +   
 +  // set the Time library to use Teensy 3.0's RTC to keep time 
 +  setSyncProvider(getTeensy3Time); 
 + 
 +  // Initialisiert den TFT-Bildschirm 
 +  tft.begin(); 
 +  tft.setRotation(1); 
 +  tft.fillScreen(ILI9341_BLACK); 
 + 
 +  // Initialisiert die serielle Schnittstelle 
 +  Serial.begin(115200); 
 + 
 +  // Zeigt auf dem TFT einen Startbildschirm an 
 +  //StartupScreen(); 
 +   
 +  delay(100); 
 +  if (timeStatus()!= timeSet) { 
 +    Serial.println("Unable to sync with the RTC"); 
 +  } else { 
 +    Serial.println("RTC has set the system time"); 
 +  } 
 + 
 +  if (! ctp.begin(40)) {                               // Stellt u.a. die Sensitivität des Touchscreens ein 
 +    Serial.println("Couldn't start FT6206 touchscreen controller"); 
 +    //while (1); 
 +  } else { 
 +    Serial.println("Capacitive touchscreen started"); 
 +  } 
 + 
 +  /* Initiolisiere den Beschleunigungssensor LSM303 */ 
 +  if(!accel.begin()) { 
 +    /* There was a problem detecting the ADXL345 ... check your connections */ 
 +    Serial.println("Ooops, no LSM303 detected ... Check your wiring!"); 
 +    //while(1); 
 +  } else { 
 +    IMUconnected = true; 
 +  } 
 +  if(!mag.begin()) { 
 +    /* There was a problem detecting the ADXL345 ... check your connections */ 
 +    Serial.println("Ooops, no LSM303 detected ... Check your wiring!"); 
 +    //while(1); 
 +  } 
 + 
 +   
 +// Konfiguration des TSL2591 
 +  // You can change the gain on the fly, to adapt to brighter/dimmer light situations 
 +  //tsl.setGain(TSL2591_GAIN_LOW);    // 1x gain (bright light) 
 +  tsl.setGain(TSL2591_GAIN_MED);      // 25x gain 
 +  // tsl.setGain(TSL2591_GAIN_HIGH);   // 428x gain 
 +   
 +  // Changing the integration time gives you a longer time over which to sense light 
 +  // longer timelines are slower, but are good in very low light situtations! 
 +  tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);  // shortest integration time (bright light) 
 +  // tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS); 
 +  // tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS); 
 +  // tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS); 
 +  //tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS); 
 +  // tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);  // longest integration time (dim light) 
 + 
 +// Initialisiert den TSL2591 
 +  tsl.begin(); //Lichtsensor 
 + 
 +// Displays some basic information on this sensor from the unified sensor API sensor_t type 
 +  sensor_t sensor; 
 +  tsl.getSensor(&sensor); 
 +  Serial.println("------------------------------------"); 
 +  Serial.print  ("Sensor:       "); Serial.println(sensor.name); 
 +  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version); 
 +  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id); 
 +  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" lux"); 
 +  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" lux"); 
 +  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" lux");   
 +  Serial.println("------------------------------------"); 
 +  Serial.println(""); 
 +   
 +   
 +  // Startet die Abfrage des DCF77-Moduls 
 +  DCF.Start(); 
 +  Serial.println("Waiting for DCF77 time ... "); 
 +  Serial.println("It will take at least 2 minutes until a first update can be processed.");  
 +   
 +   
 +  // Lese die abgespeicherten Werte für die angezeigte Alarmzeit, die schlafphasenabhängige Alarmzeit und den Alarmmmodus 
 +  alarmHour = EEPROM.read(addrAlarmHour); 
 +  alarmMinute = EEPROM.read(addrAlarmMinute); 
 +  alarmMode = EEPROM.read(addrAlarmMode);   
 +  displayedAlarmMinute = EEPROM.read(addrDisplayedAlarmMinute); 
 +  displayedAlarmHour = EEPROM.read(addrDisplayedAlarmHour); 
 +  //alarmAdvancetime = EEPROM.read(addrAlarmAdvancetime); 
 +   
 +  // Es wird einmalig die Funktion zur Berechnung des Sonnenauf- und untergangs aufgerufen. 
 +  sunrise(); 
 +
 + 
 + 
 +void loop() { 
 +// Aktuelle Zeit abfragen 
 +  unsigned long currentMillis = millis(); 
 + 
 + 
 +// Stelle die Real Time Clock (RTC) auf die aktuelle Zeit 
 +  if ((unsigned long)(currentMillis - previousMillisSetRTC) >= intervalSetRTC) { 
 + 
 +  DCFtime = DCF.getTime();              // Check if new DCF77 time is available 
 + 
 +  // Wenn die serielle Schnittstelle verfügbar ist, setze die RTC auf diese Zeit 
 +  if (Serial.available() && DCFtime DefaultTime) { 
 +    t = processSyncMessage(); 
 +    if (t != 0) { 
 +      Teensy3Clock.set(t);             // set the RTC 
 +      setTime(t); 
 +    } 
 +  } 
 + 
 +  // Wenn ein Zeitsignal vom DCF77-Modul verfügbar ist, setze die RTC auf diese Zeit 
 +  if (DCFtime DefaultTime) { 
 +    t = DCFtime; 
 +    Serial.println("RTC has been updated to DCF77 time"); 
 +    Teensy3Clock.set(t);               // set the RTC 
 +    setTime(t); 
 +    DCFtimesignalFound = true; 
 +    receivedDCFsignals = receivedDCFsignals + 1; 
 +    currentDCFsignal = millis(); 
 +  } 
 + 
 +  // Berechne die Zeit (in Sekunden) die seit dem Empfang des letzten gültigen DCF-Signals vergangen ist 
 +  if (DCFtimesignalFound == false) { 
 +    noDCFsignal = millis() /1000; 
 +  } 
 +  else { 
 +    lastDCFsignal = (millis() - currentDCFsignal) / 1000; 
 +  } 
 + 
 +  
 +  // Berechnet die Quote erfolgreich empfangener DCF77-Signale seit dem letzten Systemstart 
 +  DCFsuccessRate = (receivedDCFsignals / ((millis() / 60000))) * 100; 
 +   
 +  //Speichere die aktuelle Zeit in die zughörige Variable 
 +  previousMillisSetRTC = currentMillis; 
 +  } 
 + 
 + 
 +// Alarm-Funktionen 
 +  if ((unsigned long)(currentMillis - previousMillisAlarmClock) >= intervalAlarmClock) { 
 +     
 +    // Die Schleife wird durchlaufen, a) wenn ein Alarm eingestellt und die Zeit dafür gekommen ist oder b) eine Alarmfunktion läuft
 +    if (alarmMode != 0 && hour() == alarmHour && minute() == alarmMinute && second() == 0 || alarmOn == true) { 
 +       
 +      // Die Eventzähler müssen zu beginn einer Alarmphase einmalig zurückgesetzt werden 
 +      if (alarmOn == false) { 
 +        eventAccelZ = 0; 
 +        eventRoll =0; 
 +        eventPitch = 0; 
 +        eventTotal = 0; 
 +      } 
 +       
 +      if (alarmMode == 1) { 
 +        Serial.print("Alarmphase 1 aktiv!"); 
 +        if (eventTotal >= 100) { 
 +          Serial.print("ALARM 1!!!!"); 
 +        } 
 +      } 
 +      else if (alarmMode == 2) { 
 +        Serial.print("Alarmphase 2 aktiv!"); 
 +        if (eventTotal >= 100) { 
 +          Serial.print("ALARM 2!!!!"); 
 +        } 
 +      } 
 +      else if (alarmMode == 3) { 
 +        Serial.print("Alarmphase 3 aktiv!"); 
 +        if (eventTotal >= 100) { 
 +          Serial.print("ALARM 3!!!!"); 
 +        } 
 +      } 
 +       
 +      TFTbrightness = 255; 
 +      analogWrite(TFTbacklightPin, TFTbrightness); 
 +      TFTbacklightOn = true; 
 +      alarmOn = true; 
 +       
 +      if (menuPage != 7) {               // Das Menü "Alarm aus/Snooze" soll nur einmal aufgerufen werden. 
 +        menuPage = 7; 
 +        TFTrefresh = true; 
 +      } 
 +    } 
 +   
 +  //Speichere die aktuelle Zeit in die zughörige Variable 
 +  previousMillisAlarmClock = currentMillis; 
 +  } 
 + 
 + 
 +// Abfrage verschiedener Sensoren 
 +  if ((unsigned long)(currentMillis - previousMillisSensorData) >= intervalSensorData) { 
 + 
 +    if (IMUconnected == true) { 
 +      // Auslesen des Beschleunigungs- / Lagesensors und Magnetometers LSM303 
 +      sensors_event_t event; 
 +      accel.getEvent(&event); 
 +      sensors_vec_t   orientation; 
 +      ahrs.getOrientation(&orientation); 
 + 
 +      accelX = event.acceleration.x; 
 +      accelY = event.acceleration.y; 
 +      accelZ = event.acceleration.z; 
 + 
 +      pitch = orientation.roll;                 // Pitch und Roll müssen vertauscht werden, damit die Orientierung zur Einbaulage des Sensors passt 
 +      roll = orientation.pitch; 
 +      heading = orientation.heading; 
 +    } 
 +     
 +    // Die Werte für accelZ, pitch und roll werden mit einem Kalman-Filter geglättet 
 +    filteredAccelZ = accelZFilter.getFilteredValue(accelZ); 
 +    filteredRoll = rollFilter.getFilteredValue(roll); 
 +    filteredPitch = pitchFilter.getFilteredValue(pitch); 
 + 
 +    // Relativ schnelle Änderungen der Sensordaten lösen Ereignisse aus  
 +    if (filteredAccelZ - accelZ > 1 || filteredAccelZ - accelZ < -1) { 
 +      eventAccelZ = eventAccelZ +1; 
 +    } 
 +    if (filteredRoll - roll > 5 || filteredRoll - roll < -5) { 
 +      eventRoll = eventRoll +1; 
 +    } 
 +    if (filteredPitch - pitch > 5 || filteredPitch - pitch < -5) { 
 +      eventPitch = eventPitch +1; 
 +    } 
 + 
 +    // Berechne die Summe aller Ereignisse 
 +    eventTotal = eventAccelZ + eventRoll + eventPitch; 
 +     
 +  //Auslesen des Helligkeitssensors TSL2591 
 +  lum = tsl.getFullLuminosity(); 
 +  ir = lum >> 16; 
 +  full = lum & 0xFFFF; 
 +  lux = tsl.calculateLux(full, ir); 
 +   
 +  //Speichere die aktuelle Zeit in die zughörige Variable 
 +  previousMillisSensorData = currentMillis; 
 +  } 
 + 
 + 
 +// TFT- imd Touchscreen 
 +  if ((unsigned long)(currentMillis - previousMillisTouchScreen) >= intervalTouchScreen) { 
 + 
 +    // Auslesen des kapazitiven Touchsensors 
 +    if (ctp.touched()) { 
 +      // Retrieve point   
 +      TS_Point p = ctp.getPoint(); 
 +      // Damit der Wert 0, 0 des Touchsensors mit dem Pixel 0, 0 des TFT-Screens übereinstimmt, müssen p.x und p.y rekodiert werden 
 +      tx = map(p.y, 0, 320, 320, 0); 
 +      ty = p.x; 
 + 
 +      // Variablen für die Steuerung des Backlights 
 +      touch = true;                              // Wird wahr, so lange der Touchsensor berührt wird (d.h. wird am Ende der TouchScreen-Schleife false). 
 +      prevtouch = touch;                          
 +      TFTbacklightTime = currentMillis;               // Wird auf die aktuelle Systemzeit gesetzt, soblad der Touchsensor berührt wird. 
 + 
 +      // Variablen für die Steurung des Menüs 
 +      if (TFTbacklightOn == true) { 
 +        touch2 = true; 
 +        prevtouch2 = touch2; 
 +      } 
 +    } 
 + 
 +    // Das Backlight wird eingeschaltet, nachdem der Touchsensor losgelassen wird. 
 +    if (touch == false && prevtouch == true) { 
 +      TFTbrightness = 255; 
 +      analogWrite(TFTbacklightPin, TFTbrightness); 
 +      TFTbacklightOn = true; 
 +      TFTrefresh = true;                       // Wenn das Backlight eingeschaltet wird, muss einmal das alte Menü aufgebaut werden 
 +      prevtouch = false; 
 +    } 
 + 
 +    // Wenn das Backlight an ist, soll es nach einer bestimmten Zeit wieder ausgeschaltet werden. Allerdings nur dann, wenn keine Alarmfunktion läuft. 
 +    if (alarmOn == false) { 
 +      if (TFTbacklightOn == true && (millis() > TFTbacklightTime + TFTbacklightDelay)) { 
 +        TFTbrightness = TFTbrightness - 1; 
 +        if (TFTbrightness == 0) { 
 +          TFTbacklightOn = false; 
 +          tft.fillScreen(ILI9341_BLACK); 
 +        } 
 +        analogWrite(TFTbacklightPin, TFTbrightness); 
 +      } 
 +    } 
 + 
 +    // Wenn das Backlight an ist, kann das Menü mit dem Touchsensor bedient werden         
 +    // Es folgen für jedes einzelne Menü die Definitionen der jeweils sensiblen Bereiche einschließlich der Befehle, die jeweils ausgelöst werden sollen.  
 +    if (menuPage == 0 && touch2 == false && prevtouch2 == true) {           // Wenn der Touchscreen losgelassen wurd und Menüseite 0 ausgewählt ist ... 
 +      if ((tx >= 0) && (tx <= 120) && (ty >= 0) && (ty <= 59)) {            // ... und der TouchScreen in dem angegebenen Bereich berührt wird ...  
 +        menuPage = 1;                                                       // ... dann rufe Menüseite 1 auf. 
 +      }  
 +      else if ((tx >= 0) && (tx <= 120) && (ty >= 60) && (ty <= 120)) { 
 +        menuPage = 2; 
 +      } 
 +      else if ((tx >= 0) && (tx <= 120) && (ty >= 121) && (ty <= 180)) { 
 +        menuPage = 3; 
 +      } 
 +      else if ((tx >= 0) && (tx <= 120) && (ty >= 181) && (ty <= 240)) { 
 +        menuPage = 4; 
 +      }  
 +      else if ((tx >= 121) && (tx <= 320) && (ty >= 1) && (ty <= 240)) { 
 +        menuPage = 5; 
 +      } 
 +      TFTrefresh = true;                                                    // Aktualisiere den Inhalt des TFT-Screens 
 +      prevtouch2 = false;                                                   // Wird unwahr, damit die folgenden Schleifen übersprungen werden. 
 +    } 
 + 
 +    // Menü Snoozle 
 +    if (menuPage == 1 && touch2 == false && prevtouch2 == true) { 
 +      // Zurück zum Hauptmenü 
 +      if ((tx >= 0) && (tx <= 40) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 0; 
 +      }  
 +      else if ((tx >= 41) && (tx <= 320) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 0; 
 +      } 
 +      TFTrefresh = true; 
 +      prevtouch2 = false; 
 +    } 
 + 
 +    // Menü Ziffernblatt 
 +    if (menuPage == 2 && touch2 == false && prevtouch2 == true) { 
 +      // Zurück zum Hauptmenü 
 +      if ((tx >= 0) && (tx <= 40) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 0; 
 +      }  
 +      else if ((tx >= 41) && (tx <= 320) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 0; 
 +      } 
 +      TFTrefresh = true; 
 +      prevtouch2 = false; 
 +    } 
 + 
 +    // Menü Einstellungen 
 +    if (menuPage == 3 && touch2 == false && prevtouch2 == true) { 
 +      // Zurück zum Hauptmenü 
 +      if ((tx >= 0) && (tx <= 40) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 0; 
 +      }  
 +      else if ((tx >= 41) && (tx <= 320) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 0; 
 +      } 
 +      TFTrefresh = true; 
 +      prevtouch2 = false; 
 +    } 
 + 
 +    // Menü Informationen 
 +    if (menuPage == 4 && touch2 == false && prevtouch2 == true) { 
 +      // Zurück zum Hauptmenü 
 +      if ((tx >= 0) && (tx <= 40) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 0; 
 +      }  
 +      // Zum Uhntermenü DCF Zeitsignal 
 +      else if ((tx >= 51) && (tx <= 184) && (ty >= 0) && (ty <= 59)) {                           // ... und der TouchScreen in dem angegebenen Bereich berührt wird ...  
 +        menuPage = 41;                                                                      // ... dann rufe Menüseite 1 auf. 
 +      }  
 +      // Zum Untermenü LSM303 
 +      else if ((tx >= 51) && (tx <= 184) && (ty >= 60) && (ty <= 120)) { 
 +        menuPage = 42; 
 +      } 
 +      /* 
 +      // Zum Menü "frei" 
 +      else if ((tx >= 51) && (tx <= 184) && (ty >= 121) && (ty <= 180)) { 
 +        menuPage = 43; 
 +      } 
 +      // Zum Menü "frei" 
 +      else if ((tx >= 51) && (tx <= 184) && (ty >= 181) && (ty <= 240)) { 
 +        menuPage = 44; 
 +      }  
 +      */ 
 +      // Zum Menü TSL2591-Sensor 
 +      else if ((tx >= 186) && (tx <= 319) && (ty >= 0) && (ty <= 59)) {                           // ... und der TouchScreen in dem angegebenen Bereich berührt wird ...  
 +        menuPage = 45;                                                                      // ... dann rufe Menüseite 1 auf. 
 +      } 
 +      /*  
 +      // Zum Menü "frei" 
 +      else if ((tx >= 186) && (tx <= 319) && (ty >= 60) && (ty <= 120)) { 
 +        menuPage = 46; 
 +      } 
 +      // Zum Menü "frei" 
 +      else if ((tx >= 186) && (tx <= 319) && (ty >= 121) && (ty <= 180)) { 
 +        menuPage = 47; 
 +      } 
 +      // Zum Menü "frei" 
 +      else if ((tx >= 186) && (tx <= 319) && (ty >= 181) && (ty <= 240)) { 
 +        menuPage = 48; 
 +      }  
 +      */ 
 +      TFTrefresh = true; 
 +      prevtouch2 = false; 
 +    } 
 + 
 +    // Untermenü DCF77 Zeitsignal 
 +    if (menuPage == 41 && touch2 == false && prevtouch2 == true) { 
 +      // Zurück zum Untermenü Informationen 
 +      if ((tx >= 0) && (tx <= 40) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 4; 
 +      }  
 +      else if ((tx >= 41) && (tx <= 320) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 4; 
 +      } 
 +      TFTrefresh = true; 
 +      prevtouch2 = false; 
 +    } 
 +   
 +    // Untermenü TSL2591 Sensor 
 +    if (menuPage == 45 && touch2 == false && prevtouch2 == true) { 
 +      // Zurück zum Untermenü Informationen 
 +      if ((tx >= 0) && (tx <= 40) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 4; 
 +      }  
 +      else if ((tx >= 41) && (tx <= 320) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 4; 
 +      } 
 +      TFTrefresh = true; 
 +      prevtouch2 = false; 
 +    } 
 +    
 +    // Untermenü TSL303 Sensor 
 +    if (menuPage == 42 && touch2 == false && prevtouch2 == true) { 
 +      // Zurück zum Untermenü Informationen 
 +      if ((tx >= 0) && (tx <= 40) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 4; 
 +      }  
 +      else if ((tx >= 41) && (tx <= 320) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 4; 
 +      } 
 +      TFTrefresh = true; 
 +      prevtouch2 = false; 
 +    } 
 +    
 +    // Menü Alarmzeit stellen. Vor dem Speichern werden von der eingestellten Zeit 30 Minuten abgezogen. 
 +    if (menuPage == 5 && touch2 == false && prevtouch2 == true) { 
 +      // Zurück zum Hauptmenü 
 +      if ((tx >= 0) && (tx <= 49) && (ty >= 0) && (ty <= 239)) { 
 +        menuPage = 0; 
 +        tft.fillScreen(ILI9341_BLACK); 
 + 
 +        // Vor dem Speichern der Alarmzeit ins EEPROM wird die angezeigte Alarmzeit in die schlafphasensensible Alarmzeit umgerechnet 
 +        alarmMinute = displayedAlarmMinute;        // Damit es bei leerem EEPROM nicht zu Chaos kommt 
 +        alarmHour = displayedAlarmHour;            // Damit es bei leerem EEPROM nicht zu Chaos kommt 
 +         
 +        if (alarmAdvancetime == 15) { 
 +          if (displayedAlarmMinute == 0) { 
 +            alarmMinute = displayedAlarmMinute - 15; 
 +            alarmHour = displayedAlarmHour - 1; 
 +            if (alarmHour < 0) { 
 +              alarmHour = 23; 
 +            } 
 +          } 
 +          else if (displayedAlarmMinute == 15) { 
 +            alarmMinute = displayedAlarmMinute - 15; 
 +          } 
 +          else if (displayedAlarmMinute == 30) { 
 +            alarmMinute = displayedAlarmMinute - 15; 
 +          } 
 +          else if (displayedAlarmMinute == 45) { 
 +            alarmMinute = displayedAlarmMinute - 15; 
 +          } 
 +        } 
 +        else if (alarmAdvancetime == 30) { 
 +          if (displayedAlarmMinute == 0) { 
 +            alarmMinute = 30; 
 +            alarmHour = displayedAlarmHour - 1; 
 +            if (alarmHour < 0) { 
 +              alarmHour = 23; 
 +            } 
 +          } 
 +          else if (displayedAlarmMinute == 15) { 
 +            alarmMinute = 45; 
 +            alarmHour = displayedAlarmHour - 1; 
 +            if (alarmHour < 0) { 
 +              alarmHour = 23; 
 +            } 
 +          } 
 +          else if (displayedAlarmMinute == 30) { 
 +            alarmMinute = 0; 
 +          } 
 +          else if (displayedAlarmMinute == 45) { 
 +            alarmMinute = 15; 
 +          } 
 +        } 
 +        else if (alarmAdvancetime == 45) { 
 +          if (displayedAlarmMinute == 0) { 
 +            alarmMinute = displayedAlarmMinute - 45; 
 +            alarmHour = displayedAlarmHour -1; 
 +            if (alarmHour < 0) { 
 +              alarmHour = 23; 
 +            } 
 +          } 
 +          else if (displayedAlarmMinute == 15) { 
 +            alarmMinute = displayedAlarmMinute - 45; 
 +            alarmHour = displayedAlarmHour -1; 
 +            if (alarmHour < 0) { 
 +              alarmHour = 23; 
 +            } 
 +          } 
 +          else if (displayedAlarmMinute == 30) { 
 +            alarmMinute = displayedAlarmMinute - 45; 
 +            alarmHour = displayedAlarmHour -1; 
 +            if (alarmHour < 0) { 
 +              alarmHour = 23; 
 +            } 
 +          } 
 +          else if (displayedAlarmMinute == 45) { 
 +            alarmMinute = displayedAlarmMinute - 45; 
 +          } 
 +        } 
 +       
 +        // Um das EEPROM zu schonen, werden die Alarmzeit und der Alarmmodus erst gespeichert, wenn das Hauptmenü aufgerufen wird. 
 +        // Um Speicherplatz im EEPROM zu sparen, werden die Integervariablen alarmHour, alarmMinute etc. als Byte gespeichert. 
 +        EEPROM.write(addrDisplayedAlarmHour, byte(displayedAlarmHour)); 
 +        EEPROM.write(addrDisplayedAlarmMinute, byte(displayedAlarmMinute));         
 +        EEPROM.write(addrAlarmHour, byte(alarmHour)); 
 +        EEPROM.write(addrAlarmMinute, byte(alarmMinute)); 
 +        EEPROM.write(addrAlarmMode, alarmMode); 
 + 
 +        // Ausgabe an die serielle Schnittstelle  
 +        Serial.print("Angezeigte Alarmzeit: "); Serial.print(displayedAlarmHour); 
 +        Serial.print(":"); Serial.print(displayedAlarmMinute); Serial.println(" Uhr"); 
 +        Serial.print("Startzeit der Weckphase: "); Serial.print(alarmHour); 
 +        Serial.print(":"); Serial.print(alarmMinute); Serial.println(" Uhr"); 
 +      }  
 +      // Stunden auf 
 +      else if ((tx >= 50) && (tx <= 159) && (ty >= 0) && (ty <= 119)) { 
 +        displayedAlarmHour = displayedAlarmHour + 1; 
 +        if (displayedAlarmHour >= 24) { 
 +          displayedAlarmHour = 0; 
 +        } 
 +      }  
 +      // Minuten auf 
 +      else if ((tx >= 160) && (tx <= 268) && (ty >= 0) && (ty <= 119)) { 
 +        displayedAlarmMinute = displayedAlarmMinute + 15; 
 +        if (displayedAlarmMinute >= 60) { 
 +          displayedAlarmMinute = 0; 
 +          displayedAlarmHour = displayedAlarmHour + 1; 
 +        } 
 +      }  
 +      // Stunden ab 
 +      else if ((tx >= 50) && (tx <= 159) && (ty >= 120) && (ty <= 239)) { 
 +        displayedAlarmHour = displayedAlarmHour - 1; 
 +        if (displayedAlarmHour < 0) { 
 +          displayedAlarmHour = 23; 
 +        } 
 +      }  
 +      // Minuten ab 
 +      else if ((tx >= 160) && (tx <= 268) && (ty >= 120) && (ty <= 239)) { 
 +        displayedAlarmMinute = displayedAlarmMinute - 15; 
 +        if (displayedAlarmMinute < 0) { 
 +          displayedAlarmMinute = 45; 
 +          displayedAlarmHour = displayedAlarmHour - 1; 
 +        } 
 +      }  
 +      // Zum Menü Weckmodus stellen 
 +      else if ((tx >= 269) && (tx <= 319) && (ty >= 0) && (ty <= 239)) { 
 +        menuPage = 51; 
 +        tft.fillScreen(ILI9341_BLACK); 
 +      } 
 +      TFTrefresh = true; 
 +      prevtouch2 = false; 
 +    } 
 + 
 +    // Untermenü Weckmodus stellen 
 +    if (menuPage == 51 && touch2 == false && prevtouch2 == true) { 
 +      // Zurück zum Untermenü Informationen 
 +      if ((tx >= 0) && (tx <= 49) && (ty >= 0) && (ty <= 240)) { 
 +        menuPage = 5; 
 +      }  
 +      else if ((tx >= 50) && (tx <= 320) && (ty >= 0) && (ty <= 59)) { 
 +        alarmMode = 0; 
 +      } 
 +      else if ((tx >= 50) && (tx <= 320) && (ty >= 60) && (ty <= 119)) { 
 +        alarmMode = 1; 
 +      } 
 +      else if ((tx >= 50) && (tx <= 320) && (ty >= 120) && (ty <= 179)) { 
 +        alarmMode = 2; 
 +      }     
 +      else if ((tx >= 50) && (tx <= 320) && (ty >= 180) && (ty <= 239)) { 
 +        alarmMode = 3; 
 +      } 
 +      TFTrefresh = true; 
 +      prevtouch2 = false;   
 +    } 
 + 
 +    // Untermenü "Wecker aus"/"Schlummern" 
 +    if (menuPage == 7 && touch2 == false && prevtouch2 == true) { 
 +      // Zurück zum Untermenü Informationen 
 +      if ((tx >= 0) && (tx <= 213) && (ty >= 0) && (ty <= 239)) { 
 +        menuPage = 0; 
 +        alarmOn = false; 
 +      }  
 +      else if ((tx >= 214) && (tx <= 319) && (ty >= 0) && (ty <= 239)) { 
 +        menuPage = 0; 
 +        alarmOn = false; 
 +      } 
 +      TFTrefresh = true; 
 +      prevtouch2 = false; 
 +    } 
 +   
 + 
 + 
 + 
 +    // Der Inhalt des Bildschirms wird nur dann neu aufgebaut, wenn a) das Backlight an ist und b) ein Refresh angewiesen wurde. 
 +    if (TFTbacklightOn == true) { 
 +      // Die Nummerierung der Menüseiten erfolgt nach dem folgendendem Muster: 
 +      // Hauptmenü = 0; von dort Verzweigungen zu den Untermenüs 1 bis 5 
 + 
 +      // Hauptmenü 
 +      if (menuPage == 0 && TFTrefresh == true) { 
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +        // Linke Spalte des Menüs 
 +        tft.fillCircle(20, 35, 20, red); 
 +        tft.fillCircle(20, 91, 20, red); 
 +        tft.fillCircle(20, 147, 20, red); 
 +        tft.fillCircle(20, 204, 20, red); 
 + 
 +        tft.setTextColor(white); 
 +        tft.setFont(&FreeSans9pt7b); 
 +        tft.setCursor(15, 41); 
 +        tft.print("Snoozle"); 
 +        tft.setCursor(15, 97); 
 +        tft.print("Ziffernblatt"); 
 +        tft.setCursor(15, 153); 
 +        tft.print("Einstellung"); 
 +        tft.setCursor(15, 209); 
 +        tft.print("Information"); 
 + 
 +        // Anzeige Uhrzeit 
 +        tft.setTextColor(white, black); 
 +        tft.setFont(&FreeSans9pt7b); 
 +        tft.setCursor(190, 25); 
 +        tft.print("Uhrzeit"); 
 +        if (DCFtimesignalFound == true) { 
 +          tft.setTextColor(red, black); 
 +          tft.print(" DCF77"); 
 +          tft.setTextColor(white, black); 
 +        } 
 + 
 +        // Die Uhrzeit wird unabhängig davon einmal pro Sekunde aktualisiert 
 +     
 +        tft.fillRect(130, 119, 180, 2, white); 
 +     
 +        //Anzeige Alarmzeit 
 +        tft.setTextColor(white, black); 
 +        if (alarmMode == 0) { 
 +          tft.setFont(&FreeSans18pt7b); 
 +          tft.setCursor(140, 190); 
 +          tft.print("Alarm aus"); 
 +        } 
 +        else { 
 +          tft.setFont(&FreeSans9pt7b); 
 +          tft.setCursor(180, 140); 
 +          tft.print("Alarmzeit"); 
 + 
 +          tft.setFont(&FreeSans18pt7b); 
 +          tft.setCursor(165, 190); 
 +            if(alarmHour < 10) { 
 +              tft.print('0'); 
 +            }  
 +          tft.print(displayedAlarmHour); 
 +          tft.print(" : "); 
 +            if(displayedAlarmMinute < 10) { 
 +              tft.print('0'); 
 +            } 
 +          tft.print(displayedAlarmMinute); 
 +          tft.setFont(&FreeSans9pt7b); 
 +          tft.setCursor(155, 225); 
 +          tft.print("Alarmmodus: "); 
 +          tft.print(alarmMode);    
 +        } 
 +        TFTrefresh = false; 
 +      } 
 + 
 +      if (menuPage == 0 && ((unsigned long)(currentMillis - previousMillisTFTScreen) >= intervalTFTScreen)) { 
 +        intervalTFTScreen = 1000; 
 + 
 +        tft.fillRect(140,40, 160, 40, black); 
 +        tft.setTextColor(white, black); 
 +        tft.setCursor(150, 70); 
 +        tft.setFont(&FreeSans18pt7b);     
 +        if(hour() < 10) { 
 +          tft.print('0'); 
 +        } 
 +        tft.print(hour()); 
 +        tftprintDigits(minute()); 
 +        tftprintDigits(second()); 
 +        tft.setFont(&FreeSans9pt7b);     
 +        tft.setCursor(170, 100); 
 +        tft.print(day()); 
 +        tft.print("."); 
 +        tft.print(month()); 
 +        tft.print("."); 
 +        tft.print(year()); 
 + 
 +        previousMillisTFTScreen = currentMillis; 
 +      } 
 + 
 +      // Untermenü "Snoozle" 
 +      if (menuPage == 1 && TFTrefresh == true) { 
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +        // Zurück zum Hauptmenü 
 +        tft.fillCircle(20, 120, 20, white); 
 + 
 +        // Snoozle stellen 
 +        tft.setTextColor(white, black); 
 +        tft.setFont(&FreeSans9pt7b); 
 +        tft.setCursor(50, 120); 
 +        tft.print("Menue Snoozle stellen"); 
 + 
 +        TFTrefresh = false; 
 +        } 
 + 
 +      // Untermenü "Ziffernblatteffekte" 
 +      if (menuPage == 2 && TFTrefresh == true) { 
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +        // Zurück zum Hauptmenü 
 +        tft.fillCircle(20, 120, 20, white); 
 + 
 +        // Effekte einstellen 
 +        tft.setTextColor(white, black); 
 +        tft.setFont(&FreeSans9pt7b); 
 +        tft.setCursor(50, 120); 
 +        tft.print("Menue Effekte einstellen"); 
 + 
 +        TFTrefresh = false; 
 +        } 
 + 
 +      // Untermenü "Einstellungen" 
 +      if (menuPage == 3 && TFTrefresh == true) { 
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +        // Zurück zum Hauptmenü 
 +        tft.fillCircle(20, 120, 20, white); 
 + 
 +        // Einstellungen stellen 
 +        tft.setTextColor(white, black); 
 +        tft.setFont(&FreeSans9pt7b); 
 +        tft.setCursor(50, 120); 
 +        tft.print("Menue Einstellungen"); 
 + 
 +        TFTrefresh = false; 
 +        } 
 + 
 +      // Untermenü "Informationen" 
 +      if (menuPage == 4 && TFTrefresh == true) { 
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +       // Zurück zum Hauptmenü 
 +        tft.fillCircle(20, 120, 20, white); 
 + 
 +        // Linke Spalte 
 +        tft.fillCircle(69, 35, 20, red); 
 +        tft.fillCircle(69, 91, 20, red); 
 +        tft.fillCircle(69, 147, 20, red); 
 +        tft.fillCircle(69, 204, 20, red); 
 +     
 +        tft.setTextColor(white); 
 +        tft.setFont(&FreeSans9pt7b); 
 +        tft.setCursor(64, 41); 
 +        tft.print("Zeitsignal"); 
 +        tft.setCursor(64, 97); 
 +        tft.print("LSM303"); 
 +        tft.setCursor(64, 153); 
 +        tft.print("frei"); 
 +        tft.setCursor(64, 209); 
 +        tft.print("frei"); 
 + 
 +       // Rechte Spalte 
 +        tft.fillCircle(199, 35, 20, red); 
 +        tft.fillCircle(199, 91, 20, red); 
 +        tft.fillCircle(199, 147, 20, red); 
 +        tft.fillCircle(199, 204, 20, red); 
 + 
 +        tft.setTextColor(white); 
 +        tft.setFont(&FreeSans9pt7b); 
 +        tft.setCursor(194, 41); 
 +        tft.print("TSL2591"); 
 +        tft.setCursor(194, 97); 
 +        tft.print("frei"); 
 +        tft.setCursor(194, 153); 
 +        tft.print("frei"); 
 +        tft.setCursor(194, 209); 
 +        tft.print("frei"); 
 + 
 +        TFTrefresh = false; 
 +        } 
 + 
 +      // Unteruntermenü "DCF-Empfang" 
 +      if (menuPage == 41 && TFTrefresh == true) { 
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +        // Zurück zum Untermenü Informationen 
 +        tft.fillCircle(20, 120, 20, white); 
 + 
 +        TFTrefresh = false; 
 +      } 
 +     
 +       if (menuPage == 41 && ((unsigned long)(currentMillis - previousMillisTFTScreen) >= intervalTFTScreen)) { 
 +        intervalTFTScreen = 50; 
 +       
 +        tft.setFont(); 
 +        tft.setTextSize(1); 
 + 
 +        // Datenausgabe 
 +        tft.setFont(); 
 +        tft.setTextSize(1); 
 +     
 +        if (DCFtimesignalFound == false){ 
 +          tft.setCursor(60, 10); 
 +          tft.setTextColor(white, black); 
 +          tft.print("Kein Zeitzeichen erfolgreich empfangen"); 
 +          tft.setCursor(60, 20); 
 +          tft.print("seit "); 
 +          tft.setTextColor(red, black); 
 +          tft.print(noDCFsignal); 
 +          tft.setTextColor(white, black); 
 +          tft.print(" Sekunden."); 
 +        } 
 +        else { 
 +          tft.setCursor(60, 10); 
 +          tft.setTextColor(white, black); 
 +          tft.println("Letztes Zeitsignal erfolgreich empfangen"); 
 +          tft.setCursor(60, 20); 
 +          tft.print("vor "); 
 +          tft.setTextColor(red, black); 
 +          tft.print(lastDCFsignal); 
 +          tft.setTextColor(white, black); 
 +          tft.print(" Sekunden."); 
 +        } 
 + 
 +        tft.setCursor(60, 40); 
 +        tft.setTextColor(white, black); 
 +        tft.print("Anzahl erfolgreich empfangener Zeitzeichen"); 
 +        tft.setCursor(60, 50); 
 +        tft.print("seit dem letzten Systemstart: "); 
 +        tft.setTextColor(red, black); 
 +        tft.print(receivedDCFsignals); 
 +        tft.setTextColor(white, black); 
 +        tft.print("."); 
 + 
 +        tft.setCursor(60, 70); 
 +        tft.setTextColor(white, black); 
 +        tft.print("Anteil erfolgreich empfangener Zeitzeichen"); 
 +        tft.setCursor(60, 80); 
 +        tft.print("seit dem letzten Systemstart: "); 
 +        tft.setTextColor(red, black); 
 +        tft.print(DCFsuccessRate); 
 +        tft.setTextColor(white, black); 
 +        tft.print(" %"); 
 + 
 +        tft.setCursor(60, 100); 
 +        tft.setTextColor(white, black); 
 +        tft.print("(System ist seit "); 
 +        tft.setTextColor(red, black); 
 +        tft.print(millis()/60000); 
 +        tft.setTextColor(white, black); 
 +        tft.print(" Minuten in Betrieb.)"); 
 + 
 + 
 +        tft.fillRect(60,120, 250, 50, black); 
 +        tft.setCursor(60, 130); 
 +        tft.setTextColor(white, black); 
 +        tft.print("Periode: "); 
 +        tft.setTextColor(red, black); 
 +        tft.print(flankUp-PreviousflankUp); 
 +        tft.setTextColor(white, black); 
 +        tft.print(" Pulsweite :"); 
 +        tft.setTextColor(red, black); 
 +        tft.print(flankDown - flankUp); 
 + 
 +        previousMillisTFTScreen = currentMillis; 
 +      } 
 + 
 +      // Unteruntermenü "LSM303" 
 +      if (menuPage == 42 && TFTrefresh == true) {  
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +        // Zurück zum Untermenü Informationen 
 +        tft.fillCircle(20, 120, 20, white); 
 + 
 +        TFTrefresh = false; 
 +      } 
 +     
 +      if (menuPage == 42 && ((unsigned long)(currentMillis - previousMillisTFTScreen) >= intervalTFTScreen)) { 
 +        intervalTFTScreen = 50;     
 +     
 +        // Datenausgabe 
 +        tft.setFont(); 
 +        tft.setTextSize(1); 
 + 
 +        tft.setCursor(60, 10); 
 +        tft.setTextColor(white, black); 
 +        tft.print("Beschleunigungswerte: "); 
 +        tft.setCursor(60, 20); 
 +        tft.print("X: "); 
 +        tft.setTextColor(red, black); 
 +        tft.print(accelX); 
 +        tft.setTextColor(white, black); 
 +        tft.print(" Y: "); 
 +        tft.setTextColor(red, black); 
 +        tft.print(accelY); 
 +        tft.setTextColor(white, black); 
 +        tft.print(" Z: "); 
 +        tft.setTextColor(red, black); 
 +        tft.print(accelZ); 
 + 
 +        tft.setCursor(60, 40); 
 +        tft.setTextColor(white, black); 
 +        tft.print("Orientierung: "); 
 +        tft.setCursor(60, 50); 
 +        tft.print("Roll: "); 
 +        tft.setTextColor(red, black); 
 +        tft.print(roll); 
 +        tft.setTextColor(white, black); 
 +        tft.print("Pitch: "); 
 +        tft.setTextColor(red, black); 
 +        tft.print(pitch); 
 +        tft.setTextColor(white, black);             
 +        tft.print("Heading: "); 
 +        tft.setTextColor(red, black); 
 +        tft.print(heading); 
 + 
 +        previousMillisTFTScreen = currentMillis; 
 +      } 
 +     
 +      // Unteruntermenü "TSL2591" 
 +      if (menuPage == 45 && TFTrefresh == true) { 
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +        // Zurück zum Untermenü Informationen 
 +        tft.fillCircle(20, 120, 20, white); 
 +         
 +        TFTrefresh = false; 
 +      } 
 +   
 +      if (menuPage == 45 && ((unsigned long)(currentMillis - previousMillisTFTScreen) >= intervalTFTScreen)) { 
 +        intervalTFTScreen = 500; 
 +     
 +        // Datenausgabe 
 +        tft.setFont(); 
 +        tft.setTextSize(1); 
 +     
 +        tft.setCursor(60, 10); 
 +        tft.setTextColor(white, black); 
 +        tft.print("Infrarot: "); 
 +        tft.setTextColor(red, black); 
 +        tft.println(ir); 
 +        tft.setCursor(60, 30); 
 +        tft.setTextColor(white, black); 
 +        tft.print("Full: "); 
 +        tft.setTextColor(red, black); 
 +        tft.println(full); 
 +        tft.setCursor(60, 50); 
 +        tft.setTextColor(white, black); 
 +        tft.print("Visible: "); 
 +        tft.setTextColor(red, black); 
 +        tft.println(full - ir); 
 +        tft.setCursor(60, 70); 
 +        tft.setTextColor(white, black); 
 +        tft.print("Lux: "); 
 +        tft.setTextColor(red, black); 
 +        tft.println(lux); 
 +     
 +        previousMillisTFTScreen = currentMillis; 
 +      } 
 + 
 +      // Unteruntermenü "DHT22" 
 +      if (menuPage == 46 && TFTrefresh == true) { 
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +        // Zurück zum Untermenü Informationen 
 +        tft.fillCircle(20, 120, 20, white); 
 +     
 +        // Obere Reihe des Menüs 
 +        tft.setTextSize(1); 
 +        tft.setTextColor(black, white); 
 +        tft.setCursor(35, 12); 
 +        tft.print("Hauptmenü"); 
 +        tft.setCursor(145, 12); 
 +        tft.print("Informationen DHT22"); 
 + 
 +        // Bereich der Datenausgabe 
 +        tft.print("Der Sensor ist noch nicht in das System eingebunden"); 
 + 
 +        TFTrefresh = false; 
 +      } 
 + 
 +      // Unteruntermenü "Systeminformationen" 
 +      if (menuPage == 48 && TFTrefresh == true) { 
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +        // Zurück zum Untermenü Informationen 
 +        tft.fillCircle(20, 120, 20, white); 
 + 
 +        // Obere Reihe des Menüs 
 +        tft.setTextSize(1); 
 +        tft.setTextColor(black, white); 
 +        tft.setCursor(35, 12); 
 +        tft.print("Hauptmenü"); 
 +        tft.setCursor(145, 12); 
 +        tft.print("Informationen"); 
 +        tft.setTextColor(white, black); 
 +        tft.setCursor(255, 7); 
 +        tft.print("System-"); 
 +        tft.setCursor(245, 18); 
 +        tft.print("informationen"); 
 + 
 +        // Bereich der Datenausgabe 
 +        tft.print("Das System ist seit "); 
 +        tft.print(millis() / 60000); 
 +        tft.print(" Minuten in Betrieb"); 
 + 
 +        TFTrefresh = false; 
 +      } 
 + 
 +      // Untermenü "Alarmzeit einstellen" 
 +      if (menuPage == 5 && TFTrefresh == true) { 
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +        // Zurück zum Hauptmenü 
 +        tft.fillCircle(20, 120, 20, white); 
 +    
 +        // Wecker stellen 
 +        tft.fillCircle(105, 69, 20, red); // Stunden auf 
 +        tft.fillCircle(214, 69, 20, red); // Minuten auf 
 +        tft.fillCircle(105, 169, 20, red); // Stunden ab     
 +        tft.fillCircle(214, 169, 20, red); // Minuten ab 
 + 
 +        tft.setFont(&FreeSans9pt7b); 
 +        tft.setTextColor(white, black); 
 +        tft.setCursor(125, 20); 
 +        tft.print("Weckzeit"); 
 + 
 +        tft.fillRect(80,90, 50, 50, black); 
 +        tft.setFont(&FreeSans18pt7b); 
 +        tft.setTextColor(red, black); 
 +        tft.setCursor(90, 130); 
 +        if(displayedAlarmHour < 10) { 
 +          tft.print('0'); 
 +        }  
 +        tft.print(displayedAlarmHour); 
 + 
 +        tft.setCursor(159, 130); 
 +        tft.print(":"); 
 + 
 +        tft.fillRect(185,90, 50, 50, black); 
 +        tft.setCursor(195, 130); 
 +        if(displayedAlarmMinute < 10) { 
 +          tft.print('0'); 
 +        } 
 +        tft.print(displayedAlarmMinute); 
 +     
 +        tft.setFont(&FreeSans9pt7b); 
 +        tft.setTextColor(white, black); 
 +        tft.setCursor(120, 230); 
 +        if (alarmMode == 0) { 
 +          tft.print("Alarm aus");     
 +        } 
 +        else if (alarmMode == 1) { 
 +          tft.print("Alarm an"); 
 +        } 
 + 
 +        // Weiter zur Auswahl des Programmmodus 
 +        tft.fillCircle(299, 120, 20, white); 
 + 
 +        tft.setTextSize(0); 
 +     
 +        TFTrefresh = false; 
 +      } 
 + 
 +      // Unteruntermenü "Alarmmodus einstellen" 
 +      if (menuPage == 51 && TFTrefresh == true) { 
 +        // Zurück zum "Alarmzeit einstellen" 
 +        tft.fillCircle(20, 120, 20, white); 
 +     
 +        // Optionen 
 +        tft.setFont(&FreeSans9pt7b); 
 +        tft.setCursor(84, 41); 
 +        if (alarmMode == 0) { 
 +          tft.fillCircle(89, 35, 20, red); 
 +          tft.setTextColor(white); 
 +        } 
 +        else { 
 +          tft.fillCircle(89, 35, 20, white); 
 +          tft.setTextColor(red); 
 +        } 
 +        tft.print("Alarm aus"); 
 +     
 +        tft.setCursor(84, 97); 
 +        if (alarmMode == 1) { 
 +          tft.fillCircle(89, 91, 20, red); 
 +          tft.setTextColor(white); 
 +        } 
 +        else { 
 +          tft.fillCircle(89, 91, 20, white); 
 +          tft.setTextColor(red); 
 +        }     
 +        tft.print("Alarmmodus 1"); 
 +     
 +        tft.setCursor(84, 153); 
 +        if (alarmMode == 2) { 
 +          tft.fillCircle(89, 147, 20, red); 
 +          tft.setTextColor(white); 
 +        } 
 +        else { 
 +          tft.fillCircle(89, 147, 20, white); 
 +          tft.setTextColor(red); 
 +        }     
 +        tft.print("Alarmmodus 2"); 
 +     
 +        tft.setCursor(84, 209); 
 +        if (alarmMode == 3) { 
 +          tft.fillCircle(89, 204, 20, red); 
 +          tft.setTextColor(white); 
 +        } 
 +        else { 
 +          tft.fillCircle(89, 204, 20, white); 
 +          tft.setTextColor(red); 
 +        }     
 +        tft.print("Alarmmodus 3"); 
 + 
 +        TFTrefresh = false; 
 +      } 
 + 
 +      // Untermenü "Wecker aus/Schlummern" 
 +      if (menuPage == 7 && TFTrefresh == true) { 
 +        tft.fillScreen(ILI9341_BLACK); 
 +     
 +        // Wecker aus 
 +        tft.fillRect(0, 0, 213, 240, red); 
 +        tft.setTextColor(black, red); 
 +        tft.setFont(&FreeSans18pt7b); 
 +        tft.setCursor(85, 125); 
 +        tft.print("aus"); 
 +     
 +        // Schlummern 
 +        tft.fillRect(214, 0, 106, 240, orange); 
 +        tft.setTextColor(black, orange); 
 +        tft.setFont(&FreeSans9pt7b); 
 +        tft.setCursor(220, 120); 
 +        tft.print("snooze"); 
 + 
 +        TFTrefresh = false; 
 +      } 
 +    } 
 + 
 +  touch = false;                         // Die Variable wird unwahr 
 +  touch2 = false;                        // Die Variable wird unwahr 
 +   
 +  //Speichere die aktuelle Zeit in die zughörige Variable 
 +   previousMillisTouchScreen = currentMillis; 
 +  } 
 + 
 +// Ausgabe an die serielle Schnittstelle 
 +  if ((unsigned long)(currentMillis - previousMillisSerialPrint) >= intervalSerialPrint) { 
 +/*     
 +    // Gibt die aktuelle Zeit aus 
 +    Serial.print(hour()); 
 +    printDigits(minute()); 
 +    printDigits(second()); 
 +    Serial.print(" "); 
 +    Serial.print(day()); 
 +    Serial.print("."); 
 +    Serial.print(month()); 
 +    Serial.print("."); 
 +    Serial.print(year()); 
 +    Serial.print(" "); 
 +    Serial.print(weekday()); 
 +    printDCFsyncTime(); 
 +     
 +    Serial.print(" MenuPage: "); 
 +    Serial.print(menuPage); 
 +    Serial.print("; TFT Helligkeit: "); 
 +    Serial.print(TFTbrightness); 
 + 
 +    Serial.print("; empf. DCF-Sig.: "); 
 +    Serial.print(receivedDCFsignals); 
 +*/ 
 +    // Display the results (acceleration is measured in m/s^2) 
 +    Serial.print("; X: "); Serial.print(accelX); Serial.print("  "); 
 +    Serial.print("Y: "); Serial.print(accelY); Serial.print("  "); 
 +    Serial.print("Z: "); Serial.print(accelZ); Serial.print("  ");Serial.print("m/s^2 "); 
 + 
 +    // 'orientation' should have valid .roll and .pitch fields 
 +    Serial.print(F("; Orientation: ")); 
 +    Serial.print(roll); 
 +    Serial.print(F(" ")); 
 +    Serial.print(pitch); 
 +    Serial.print(F(" ")); 
 +    Serial.print(heading); 
 +    Serial.print(F(""));     
 + 
 +    Serial.print("; filtered AccelZ: "); 
 +    Serial.print(filteredAccelZ); 
 +    Serial.print("; filtered Roll: "); 
 +    Serial.print(filteredRoll); 
 +    Serial.print("; filtered Pitch: "); 
 +    Serial.print(filteredPitch); 
 +         
 +    Serial.print("; EventAccelZ: "); 
 +    Serial.print(eventAccelZ); 
 +     Serial.print("; EventRoll: "); 
 +    Serial.print(eventRoll); 
 +        Serial.print("; EventPitch: "); 
 +    Serial.print(eventPitch);    
 +     
 +    Serial.println(); 
 +  //Speichere die aktuelle Zeit in die zughörige Variable 
 +  previousMillisSerialPrint = currentMillis; 
 +  } 
 + 
 +// Misst die Periode und Pusweite des vom DCF77-Modul empfangenen Signals in Millisekunden 
 +  if ((unsigned long)(currentMillis - previousMillisDCFPulseLength) >= intervalDCFPulseLength) { 
 + 
 +    int sensorValue = !digitalRead(DCF_PIN);  // Bei dem DCF77-Modul von ELV muss das Signal invertiert werden 
 +      if (sensorValue) { 
 +        if (!Up) { 
 +          flankUp=millis(); 
 +          Up = true; 
 +        } 
 +      } else { 
 +        if (Up) { 
 +          flankDown=millis(); 
 +          Serial.print("Periode: "); 
 +          Serial.print(flankUp-PreviousflankUp); 
 +          Serial.print(" Pulsweite :"); 
 +          Serial.println(flankDown - flankUp); 
 +          PreviousflankUp = flankUp; 
 +          Up = false; 
 +        }               
 +      } 
 +   
 +  //Speichere die aktuelle Zeit in die zughörige Variable 
 +  previousMillisDCFPulseLength = currentMillis; 
 +  } 
 + 
 + 
 + 
 +
 + 
 + 
 +time_t getTeensy3Time() 
 +
 +  return Teensy3Clock.get(); 
 +
 + 
 + 
 +/*  code to process time sync messages from the serial port   */ 
 +#define TIME_HEADER  "T"   // Header tag for serial time sync message 
 + 
 +unsigned long processSyncMessage() { 
 +  time_t pctime = 0L; 
 +  //unsigned long pctime = 0L; 
 + 
 +  if(Serial.find(TIME_HEADER)) { 
 +     pctime = Serial.parseInt(); 
 +     return pctime; 
 +     if( pctime < DefaultTime) { // check the value is a valid time (greater than Nov 1 2016) 
 +       pctime = 0L; // return 0 to indicate that the time is not valid 
 +     } 
 +  } 
 +  return pctime; 
 +
 + 
 + 
 +void tftprintDigits(int digits) { 
 +  // utility function for digital clock display: prints preceding colon and leading 0 
 +  tft.print(":"); 
 +  if(digits < 10) 
 +    tft.print('0'); 
 +  tft.print(digits); 
 +
 + 
 + 
 +void printDigits(int digits) { 
 +  // utility function for digital clock display: prints preceding colon and leading 0 
 +  Serial.print(":"); 
 +  if(digits < 10) 
 +    Serial.print('0'); 
 +  Serial.print(digits); 
 +
 + 
 + 
 +void tftprintDCFsyncTime() { 
 +  if (DCFtimesignalFound == false){ 
 +    tft.println("Kein Zeitsignal empfangen seit "); 
 +    tft.print(noDCFsignal); 
 +    tft.print(" Sek."); 
 +  } 
 +  else { 
 +    tft.println("Zeitsignal empfangen vor "); 
 +    tft.print(lastDCFsignal); 
 +    tft.print(" Sek."); 
 +  } 
 +
 + 
 + 
 +void printDCFsyncTime() { 
 +  if (DCFtimesignalFound == false){ 
 +    Serial.print(" no DCF77 sync since "); 
 +    Serial.print(noDCFsignal); 
 +    Serial.print(" sec."); 
 +  } 
 +  else { 
 +    Serial.print(" last DCF77 sync "); 
 +    Serial.print(lastDCFsignal); 
 +    Serial.print(" sec. ago"); 
 +  } 
 +
  
-Type '1' for SdFatSdioEX or '2' for SdFatSdio+void tftprintDCFsyncCycle() { 
 +  if (DCFtimesignalFound == false){ 
 +    tft.println("Kein Zeitsignal empfangen seit "); 
 +    tft.print(noDCFsignal / 60); 
 +    tft.print(" Zyklen"); 
 +  } 
 +  else { 
 +    tft.println("Zeitsignal empfangen vor "); 
 +    tft.print(lastDCFsignal /60); 
 +    tft.print(" Zyklen"); 
 +  } 
 +}
  
-size,write,read +/* 
-bytes,KB/sec,KB/sec +// Die Funktion alarmFunktion aktiviert einen Weckalarmwenn der alarmMode ungleich "0" (Alarm aus) ist 
-512,7354.11,18290.74 +void alarmFunction() { 
-1024,9666.89,18028.66 +  if (alarmMode != 0) { 
-2048,16196.98,18807.61 +    alarmRunning = true; 
-4096,16282.58,18902.37 +  } 
-8192,16432.82,18951.70 +} 
-16384,16378.37,18984.85 +*/
-32768,16415.77,18987.51+
  
-totalMicros  7715214 +void StartupScreen() { 
-yieldMicros  221922 +  // Zeigt einen Startup-Screen 
-yieldCalls   333 +  tft.println("Schlafphasenwecker"); 
-yieldMaxUsec 7896 +  tft.println("Version 0.2 alpha"); 
-kHzSdClk     45000 +}
-Done+
 </code> </code>
  
-Tags: #Arduino #Schlafphasenwecker+{{tag>Arduino Schlafphasenwecker Teensy}}
arduino/schlafphasenwecker/programmversion_0.5.1482851115.txt.gz · Zuletzt geändert: 18.05.2023 12:16 (Externe Bearbeitung)