====== Schlafphasenwecker Programmversion 0.6 ====== Dies ist eine alte Programmversion.Der Schlafphasenwecker soll nicht nur durch Licht wecken können, sondern auch akustisch. Es soll aber kein hässlicher Alarmsound abgespielt werden, sondern sanfte Naturgeräusche. In dieser Programmversion sollen daher die Audiofunktionen des Weckers an den Start gebracht werden. Das Teensy Audio Board muss direkt auf dem Teensy montiert werden, da eine Verbindung mit Kabeln nicht stabil funktioniert. (Das Audio Board gibt dann anstatt Musik ein nerviges Rauschen von sich.) Weil damit die Pin-Belegung durch das Audio Board vorgegeben wird, muss das TFT-Display anders angeschlossen werden. Um das Display zu beschleunigen muss die Bibliothek //Adafruit_ILI9341.h// durch die Teensy-optimierte Bibliothek //ILI9341_t3.h// ersetzt werden (siehe dazu [[https://forum.pjrc.com/threads/26305-Highly-optimized-ILI9341-(320x240-TFT-color-display)-library|diesen Diskussionsstrang]] im PJRC-Forum). Die Bibliothek //Adafruit_GFX.h// entfällt. Neben der deutlich verbesserten Geschwindigkeit der optimierten Bibliothek sprechen auch die unzähligen Fonts für //ILI9341_t3.h// (siehe dazu [[https://github.com/PaulStoffregen/ILI9341_fonts|Fonts]]). Wie Fonts eingebunden werden wird [[https://forum.pjrc.com/threads/26305-Highly-optimized-ILI9341-(320x240-TFT-color-display)-library?p=79950&viewfull=1#post79950|in diesem Beitrag erklärt]]. In der Bibliothek ILI9341_t3.h werden die folgenden Farben definiert: #define ILI9341_BLACK 0x0000 /* 0, 0, 0 */ #define ILI9341_NAVY 0x000F /* 0, 0, 128 */ #define ILI9341_DARKGREEN 0x03E0 /* 0, 128, 0 */ #define ILI9341_DARKCYAN 0x03EF /* 0, 128, 128 */ #define ILI9341_MAROON 0x7800 /* 128, 0, 0 */ #define ILI9341_PURPLE 0x780F /* 128, 0, 128 */ #define ILI9341_OLIVE 0x7BE0 /* 128, 128, 0 */ #define ILI9341_LIGHTGREY 0xC618 /* 192, 192, 192 */ #define ILI9341_DARKGREY 0x7BEF /* 128, 128, 128 */ #define ILI9341_BLUE 0x001F /* 0, 0, 255 */ #define ILI9341_GREEN 0x07E0 /* 0, 255, 0 */ #define ILI9341_CYAN 0x07FF /* 0, 255, 255 */ #define ILI9341_RED 0xF800 /* 255, 0, 0 */ #define ILI9341_MAGENTA 0xF81F /* 255, 0, 255 */ #define ILI9341_YELLOW 0xFFE0 /* 255, 255, 0 */ #define ILI9341_WHITE 0xFFFF /* 255, 255, 255 */ #define ILI9341_ORANGE 0xFD20 /* 255, 165, 0 */ #define ILI9341_GREENYELLOW 0xAFE5 /* 173, 255, 47 */ #define ILI9341_PINK 0xF81F // Schlafphasenwecker Version 0.6.3 // Umstellung von Adafruit_ILI9341.h auf ILI9341_t3.h // Snoozle-Funktion // Erweiterung und Überarbeitung des Menüs // Bibliotheken einbinden #include // Stellt verschiedene Zeitfunktionen zur Verfügung #include // Ermöglicht den Zugriff auf den EEPROM #include // Bibliothek für das DCF77-Modul #include #include // #include // this is needed for display #include #include #include // Teensy-optimierte Bibliothek für das TFT-Display #include // Kapazitiver Touchsensor #include // Stereo 2.8W Class D Audio Amplifier TPA2016 #include // Adafruit Unified Sensor Driver #include // Bibliothek für den Lichtsensor TSL2591 #include // Bibliothek für den Beschleunigungssensor LSM303 #include #include #include "font_DroidSans.h" // Font Droid Sans Regular #include "font_DroidSans_Bold.h" // Font Droid Sans Bold #include "font_AwesomeF000.h" // Font AwesomeF000 (Symbole) #include "font_AwesomeF100.h" // Font AwesomeF100 (Symbole) #include "font_AwesomeF180.h" // Font AwesomeF180 (Symbole) // Definiert Adressen im EEPROM int addrAlarmHour = 0; int addrAlarmMinute = 1; int addrAlarmMode = 2; int addrDisplayedAlarmHour = 3; int addrDisplayedAlarmMinute = 4; int addrAlarmAdvancetime = 5; int addrAlarmFile = 6; int addrSnoozleFile = 7; // Definiert die Pins #define DCF_PIN 2 // Connection pin to DCF 77 device #define DCF_INTERRUPT 2 // Interrupt number associated with pin #define TFTbacklightPin 4 // 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 #define darkyellow 0xFB20 // Falsche Farbe eingesetzt - nur Test #define darkblue 0xFB20 // Falsche Farbe eingesetzt - nur Test // 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 #define TFT_DC 20 #define TFT_CS 21 #define TFT_RST 255 // Set to 255 when reset is not used #define TFT_MOSI 7 #define TFT_SCLK 14 #define TFT_MISO 12 ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO); // 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); // Konfiguriert die Audio-Funktionen AudioPlaySdWav playSdWav1; //xy=154,239 AudioPlaySdWav playSdWav2; //xy=171,302 AudioMixer4 mixer2; //xy=389,332 AudioMixer4 mixer1; //xy=391,236 AudioOutputI2S i2s1; //xy=532,299 AudioConnection patchCord1(playSdWav1, 0, mixer1, 0); AudioConnection patchCord2(playSdWav1, 1, mixer2, 0); AudioConnection patchCord3(playSdWav2, 0, mixer1, 1); AudioConnection patchCord4(playSdWav2, 1, mixer2, 1); AudioConnection patchCord5(mixer2, 0, i2s1, 1); AudioConnection patchCord6(mixer1, 0, i2s1, 0); AudioControlSGTL5000 sgtl5000_1; //xy=381,690 // Stereo 2.8W Class D Audio Amplifier TPA2016 Adafruit_TPA2016 audioamp = Adafruit_TPA2016(); // 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) byte alarmFile = 1; // Legt die WAV-Datei fest, die bei einem Alarm abgespielt wird boolean alarmOn = false; // Wird wahr, so lange ein Alarm läuft boolean snoozeOn = false; // Wird wahr, wenn derSchlummeralarm aktiv ist int snoozeDelay = 600; // Schlummerzeit in Sekunden int snoozeTime = 1477958400; // Die Zeit, zu der ein neuer Alarm ausgelöst werden soll boolean snoozleOn = false; // Wird wahr, wenn die Snoozle-Funktion aktiv ist byte snoozleFile = 1; // Legt die WAV-Datei fest, die zum Snoozlen abgespielt wird time_t snoozleTime = 1477958400; // Die Zeit, bis zu der Snoozle-Musik abgespielt werden soll float snoozleGain = 0.3; // Verstärkung/Lautstärke 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 previousMillisSnoozleTime = 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 const unsigned long intervalSnoozleTime = 1000; // konstanter Delay für die Snoozlefunktion 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 // Initialisiert die serielle Schnittstelle Serial.begin(115200); // set the Time library to use Teensy 3.0's RTC to keep time setSyncProvider(getTeensy3Time); delay(2000); // 2000 Millisekunden Pause, damit der serielle Monitor verfügbar ist, das Programm aber auch ohne läuft if (timeStatus()!= timeSet) { Serial.println("Unable to sync with the RTC"); } else { Serial.println("RTC has set the system time"); } //Initialisiert den Touchscrenn 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"); } //Initialisiert 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); } // Initialisiert den TFT-Bildschirm tft.begin(); tft.setRotation(1); tft.fillScreen(ILI9341_BLACK); // read diagnostics (optional but can help debug problems) uint8_t x = tft.readcommand8(ILI9341_RDMODE); Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDMADCTL); Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDPIXFMT); Serial.print("Pixel Format: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDIMGFMT); Serial.print("Image Format: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDSELFDIAG); Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); // 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."); // Initialisiert das Audio Board und die SD-Karte AudioMemory(100); sgtl5000_1.enable(); sgtl5000_1.volume(0.8); sgtl5000_1.enhanceBassEnable(); SPI.setMOSI(7); SPI.setSCK(14); if (!(SD.begin(10))) { Serial.println("Unable to access the SD card"); } // Initialisiert den Class D Amplifier audioamp.begin(); // Turn off AGC for the gain test audioamp.setAGCCompression(TPA2016_AGC_OFF); // we also have to turn off the release to really turn off AGC audioamp.setReleaseControl(0); audioamp.setLimitLevelOn(); audioamp.setLimitLevel(5); // Lese die abgespeicherten Werte für die angezeigte Alarmzeit, die schlafphasenabhängige Alarmzeit und den Alarmmmodus alarmHour = EEPROM.read(addrAlarmHour); // die aus der angezeigten Alarmwit und der Vorlaufzeit berechnete Alarmzeit (Stunde) alarmMinute = EEPROM.read(addrAlarmMinute); // die aus der angezeigten Alarmwit und der Vorlaufzeit berechnete Alarmzeit (Minute) alarmMode = EEPROM.read(addrAlarmMode); // der ausgewählte Alarmmodus displayedAlarmMinute = EEPROM.read(addrDisplayedAlarmMinute); // die angezeigte Alarmzeit (Minute) displayedAlarmHour = EEPROM.read(addrDisplayedAlarmHour); // die angezeigte Alarmzeit (Stunde) alarmAdvancetime = EEPROM.read(addrAlarmAdvancetime); // die ausgewählte Vorlaufzeit für den Alarm (in Minuten) alarmFile = EEPROM.read(addrAlarmFile); // die ausgewählte WAV-Datei snoozleFile = EEPROM.read(addrSnoozleFile); // die ausgewählte WAV-Datei // 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()) { 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; } // Snoozle-Funktion if ((unsigned long)(currentMillis - previousMillisSnoozleTime) >= intervalSnoozleTime) { /*/ Ausgabe an serielle Schnittstelle für Debugging Serial.print("current time: "); Serial.print(now()); Serial.print("; snoozleTime: "); Serial.print(snoozleTime); Serial.print("; snoozleOn: "); Serial.println(snoozleOn); */ // Wenn die aktuelle Zeit kleiner ist als die eingestellte Snoozle-Zeit, dann ... if (snoozleOn == true) { audioamp.enableChannel(true, true); // Schaltet den Verstärker ein if (playSdWav1.isPlaying() == false) { Serial.println("Start playing"); if (snoozleFile == 1) { playSdWav1.play("MEER01.WAV"); } else if (snoozleFile == 2) { playSdWav1.play("MEER02.WAV"); } else if (snoozleFile == 3) { playSdWav1.play("REGEN01.WAV"); } else if (snoozleFile == 4) { playSdWav1.play("REGEN02.WAV"); } } //TFTbacklightOn = true; // Das Backlight bleibt eingeschaltet, so lange die Snoozle-Funktion aktiv ist if (menuPage != 8) { // Das Menü "Snoozle aus/Lautstärke" soll nur einmal aufgerufen werden. menuPage = 8; TFTrefresh = true; } } if (now() >= snoozleTime && snoozleOn == true) { if (menuPage == 8) { // Wenn Menü "8" angezeigt wird ... menuPage = 0; // ... rufe das Hauptmenü auf. TFTrefresh = true; } snoozleOn = false; playSdWav1.stop(); audioamp.enableChannel(false, false); // Schaltet den Verstärker aus } //Speichere die aktuelle Zeit in die zughörige Variable previousMillisSnoozleTime = 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; } // Wecken mit Licht if (alarmMode == 1) { Serial.println("Alarmphase 1 aktiv!"); if (eventTotal >= 100) { Serial.print("ALARM 1!!!!"); } } // Wecken mit Musik else if (alarmMode == 2) { Serial.println("Alarmphase 2 aktiv!"); if (eventTotal >= 100) { Serial.print("ALARM 2!!!!"); if (playSdWav2.isPlaying() == false) { Serial.println("Start playing"); if (alarmFile == 1) { playSdWav2.play("MEER01.WAV"); } else if (alarmFile == 2) { playSdWav2.play("MEER02.WAV"); } else if (alarmFile == 3) { playSdWav2.play("REGEN01.WAV"); } else if (alarmFile == 4) { playSdWav2.play("REGEN02.WAV"); } } } } // Wecken mit Licht und Musik else if (alarmMode == 3) { Serial.println("Alarmphase 3 aktiv!"); if (eventTotal >= 100) { Serial.print("ALARM 3!!!!"); } } // Schlummeralarm if (snoozeOn == true && now() >= snoozeTime) { Serial.print("Schlummerlarm!"); if (playSdWav2.isPlaying() == false) { Serial.println("Start playing"); if (alarmFile == 1) { playSdWav2.play("MEER01.WAV"); } else if (alarmFile == 2) { playSdWav2.play("MEER02.WAV"); } else if (alarmFile == 3) { playSdWav2.play("REGEN01.WAV"); } else if (alarmFile == 4) { playSdWav2.play("REGEN02.WAV"); } } } // Anzeige des Menüs "Wecker aus"/"Schlummern" TFTbrightness = 255; analogWrite(TFTbacklightPin, TFTbrightness); TFTbacklightOn = true; // Das Backlight bleibt eingeschaltet, so lange die Alarm-Funktion aktiv ist 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; logSDcard(); } 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); /* // Daten auf SD-Karte loggen // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. File dataFile = SD.open("datalog.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.print(currentMillis); dataFile.print(","); dataFile.println(lux); dataFile.close(); // print to the serial port too: Serial.print(currentMillis); Serial.print(","); Serial.print(lux); } // if the file isn't open, pop up an error: else { Serial.println("error opening datalog.txt"); } */ //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 a 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 a) keine Alarmfunktion oder b) keine Snoozlemusik läuft. if (alarmOn == false && snoozleOn == 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 <= 49) && (ty >= 0) && (ty <= 240)) { menuPage = 0; } // Snoozle 15 Minuten else if ((tx >= 50) && (tx <= 268) && (ty >= 0) && (ty <= 59)) { snoozleOn = true; snoozleTime = now() + 900; } // Snoozle 30 Minuten else if ((tx >= 50) && (tx <= 268) && (ty >= 60) && (ty <= 119)) { snoozleOn = true; snoozleTime = now() + 1800; } // Snoozle 45 Minuten else if ((tx >= 50) && (tx <= 268) && (ty >= 120) && (ty <= 179)) { snoozleOn = true; snoozleTime = now() + 2700; } // Snoozle 60 Minuten else if ((tx >= 50) && (tx <= 268) && (ty >= 180) && (ty <= 239)) { snoozleOn = true; snoozleTime = now() + 3600; } // Zum Unteruntermenü Snoozle-Musik auswählen else if ((tx >= 269) && (tx <= 319) && (ty >= 0) && (ty <= 239)) { menuPage = 11; } TFTrefresh = true; prevtouch2 = false; } // Unteruntermenü Auswahl Snoozlemusik if (menuPage == 11 && touch2 == false && prevtouch2 == true) { // Zurück zum Untermenü Snoozle if ((tx >= 0) && (tx <= 40) && (ty >= 0) && (ty <= 240)) { menuPage = 1; } // Auswahl Musik 1 else if ((tx >= 51) && (tx <= 184) && (ty >= 0) && (ty <= 59)) { snoozleFile = 1; EEPROM.write(addrSnoozleFile, snoozleFile); } // Auswahl Musik 2 else if ((tx >= 51) && (tx <= 184) && (ty >= 60) && (ty <= 120)) { snoozleFile = 2; EEPROM.write(addrSnoozleFile, snoozleFile); } // Auswahl Musik 3 else if ((tx >= 51) && (tx <= 184) && (ty >= 121) && (ty <= 180)) { snoozleFile = 3; EEPROM.write(addrSnoozleFile, snoozleFile); } // Auswahl Musik 4 else if ((tx >= 51) && (tx <= 184) && (ty >= 181) && (ty <= 240)) { snoozleFile = 4; EEPROM.write(addrSnoozleFile, snoozleFile); } /* // Auswahl Musik 5 else if ((tx >= 186) && (tx <= 319) && (ty >= 0) && (ty <= 59)) { snoozleFile = 5; EEPROM.write(addrSnoozleFile, snoozleFile); } // Auswahl Musik 6 else if ((tx >= 186) && (tx <= 319) && (ty >= 60) && (ty <= 120)) { snoozleFile = 6; EEPROM.write(addrSnoozleFile, snoozleFile); } // Auswahl Musik 7 else if ((tx >= 186) && (tx <= 319) && (ty >= 121) && (ty <= 180)) { snoozleFile = 7; EEPROM.write(addrSnoozleFile, snoozleFile); } // Auswahl Musik 8 else if ((tx >= 186) && (tx <= 319) && (ty >= 181) && (ty <= 240)) { snoozleFile = 8; EEPROM.write(addrSnoozleFile, snoozleFile); } */ 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; } // Zum Untermenü Weckzeitvorlauf else if ((tx >= 51) && (tx <= 184) && (ty >= 0) && (ty <= 59)) { menuPage = 31; } // Zum Untermenü Weckmusik else if ((tx >= 51) && (tx <= 184) && (ty >= 60) && (ty <= 120)) { menuPage = 32; } /* // Zum Untermenü "frei" else if ((tx >= 51) && (tx <= 184) && (ty >= 121) && (ty <= 180)) { menuPage = 33; } // Zum Untermenü "frei" else if ((tx >= 51) && (tx <= 184) && (ty >= 181) && (ty <= 240)) { menuPage = 34; } // Zum Untermenü "frei" else if ((tx >= 186) && (tx <= 319) && (ty >= 0) && (ty <= 59)) { menuPage = 35; } // Zum Untermenü "frei" else if ((tx >= 186) && (tx <= 319) && (ty >= 60) && (ty <= 120)) { menuPage = 36; } // Zum Untermenü "frei" else if ((tx >= 186) && (tx <= 319) && (ty >= 121) && (ty <= 180)) { menuPage = 37; } // Zum Untermenü "frei" else if ((tx >= 186) && (tx <= 319) && (ty >= 181) && (ty <= 240)) { menuPage = 38; } */ TFTrefresh = true; prevtouch2 = false; } // Untermenü Weckzeitvorlauf einstellen if (menuPage == 31 && touch2 == false && prevtouch2 == true) { // Zurück zum Untermenü Einstellungen if ((tx >= 0) && (tx <= 49) && (ty >= 0) && (ty <= 240)) { menuPage = 3; } else if ((tx >= 50) && (tx <= 320) && (ty >= 0) && (ty <= 79)) { alarmAdvancetime = 15; EEPROM.write(addrAlarmAdvancetime, alarmAdvancetime); } else if ((tx >= 50) && (tx <= 320) && (ty >= 80) && (ty <= 159)) { alarmAdvancetime = 30; EEPROM.write(addrAlarmAdvancetime, alarmAdvancetime); } else if ((tx >= 50) && (tx <= 320) && (ty >= 160) && (ty <= 239)) { alarmAdvancetime = 45; EEPROM.write(addrAlarmAdvancetime, alarmAdvancetime); } TFTrefresh = true; prevtouch2 = false; } // Untermenü Weckmusikauswahl if (menuPage == 32 && touch2 == false && prevtouch2 == true) { // Zurück zum Untermenü Einstellungen if ((tx >= 0) && (tx <= 40) && (ty >= 0) && (ty <= 240)) { menuPage = 3; } // Auswahl Musik 1 else if ((tx >= 51) && (tx <= 184) && (ty >= 0) && (ty <= 59)) { alarmFile = 1; EEPROM.write(addrAlarmFile, alarmFile); } // Auswahl Musik 2 else if ((tx >= 51) && (tx <= 184) && (ty >= 60) && (ty <= 120)) { alarmFile = 2; EEPROM.write(addrAlarmFile, alarmFile); } // Auswahl Musik 3 else if ((tx >= 51) && (tx <= 184) && (ty >= 121) && (ty <= 180)) { alarmFile = 3; EEPROM.write(addrAlarmFile, alarmFile); } // Auswahl Musik 4 else if ((tx >= 51) && (tx <= 184) && (ty >= 181) && (ty <= 240)) { alarmFile = 4; EEPROM.write(addrAlarmFile, alarmFile); } /* // Auswahl Musik 5 else if ((tx >= 186) && (tx <= 319) && (ty >= 0) && (ty <= 59)) { alarmFile = 5; EEPROM.write(addrAlarmFile, alarmFile); } // Auswahl Musik 6 else if ((tx >= 186) && (tx <= 319) && (ty >= 60) && (ty <= 120)) { alarmFile = 6; EEPROM.write(addrAlarmFile, alarmFile); } // Auswahl Musik 7 else if ((tx >= 186) && (tx <= 319) && (ty >= 121) && (ty <= 180)) { alarmFile = 7; EEPROM.write(addrAlarmFile, alarmFile); } // Auswahl Musik 8 else if ((tx >= 186) && (tx <= 319) && (ty >= 181) && (ty <= 240)) { alarmFile = 8; EEPROM.write(addrAlarmFile, alarmFile); } */ 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)) { menuPage = 41; } // 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)) { menuPage = 45; } /* // 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) { // Wecker aus if ((tx >= 0) && (tx <= 213) && (ty >= 0) && (ty <= 239)) { menuPage = 0; alarmOn = false; snoozeOn = false; playSdWav2.stop(); } // Schlummern else if ((tx >= 214) && (tx <= 319) && (ty >= 0) && (ty <= 239)) { snoozeOn = true; playSdWav2.stop(); snoozeTime = now() + snoozeDelay; } TFTrefresh = true; prevtouch2 = false; } // Untermenü "Snoozle aus"/"Lautstärke" if (menuPage == 8 && touch2 == false && prevtouch2 == true) { // Zurück zum Untermenü Informationen if ((tx >= 0) && (tx <= 213) && (ty >= 0) && (ty <= 239)) { menuPage = 0; snoozleOn = false; playSdWav1.stop(); audioamp.enableChannel(false, false); } else if ((tx >= 214) && (tx <= 319) && (ty >= 0) && (ty <= 119)) { // Lautstärke erhöhen snoozleGain = snoozleGain + 0.1; if (snoozleGain >= 0.8) { snoozleGain = 0.8; } //audioamp.setGain(snoozleGain); mixer1.gain(0, snoozleGain); mixer2.gain(0, snoozleGain); } else if ((tx >= 214) && (tx <= 319) && (ty >= 120) && (ty <= 239)) { // Lautstärke verringern snoozleGain = snoozleGain - 0.1; if (snoozleGain <= 0.0) { snoozleGain = 0.0; } //audioamp.setGain(snoozleGain); mixer1.gain(0, snoozleGain); mixer2.gain(0, snoozleGain); } Serial.print("Gain = "); Serial.println(snoozleGain); 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(DroidSans_12_Bold); tft.setCursor(15, 31); tft.print("Snoozle"); tft.setCursor(15, 87); tft.print("Ziffernblatt"); tft.setCursor(15, 143); tft.print("Einstellung"); tft.setCursor(15, 199); tft.print("Information"); // Anzeige Uhrzeit tft.setTextColor(white, black); tft.setFont(DroidSans_13); tft.setCursor(190, 15); tft.print("Uhrzeit"); if (DCFtimesignalFound == true) { tft.setTextColor(red, black); tft.setFont(DroidSans_8); tft.print(" (DCF77)"); tft.setTextColor(white, black); } /* // Anzeige Sonnenaufgang und Sonnenuntergang tft.setTextColor(darkyellow); tft.setFont(AwesomeF180_13); tft.setCursor(140, 95); tft.print((char)5); tft.setTextColor(white); tft.setFont(DroidSans_13); tft.print(AufgangStunden); tft.print(":"); if (AufgangMinuten<10.0) tft.print("0"); tft.print(AufgangMinuten); tft.setTextColor(darkblue); tft.setFont(AwesomeF180_13); tft.setCursor(140, 95); tft.print((char)6); tft.setTextColor(white); tft.setFont(DroidSans_13); tft.print(UntergangStunden); tft.print(":"); if (UntergangMinuten<10.0) tft.print("0"); tft.print(UntergangMinuten); */ // 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(DroidSans_24); tft.setCursor(140, 170); tft.print("Alarm aus"); } else { tft.setFont(DroidSans_13); tft.setCursor(180, 135); tft.print("Alarmzeit"); tft.setFont(DroidSans_24); tft.setCursor(165, 170); if(alarmHour < 10) { tft.print('0'); } tft.print(displayedAlarmHour); tft.print(" : "); if(displayedAlarmMinute < 10) { tft.print('0'); } tft.print(displayedAlarmMinute); tft.setFont(DroidSans_13); tft.setCursor(155, 220); 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, 50); tft.setFont(DroidSans_24); if(hour() < 10) { tft.print('0'); } tft.print(hour()); tftprintDigits(minute()); tftprintDigits(second()); tft.setFont(DroidSans_13); tft.setCursor(180, 95); 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); // Optionen tft.fillCircle(89, 35, 20, red); tft.fillCircle(89, 91, 20, red); tft.fillCircle(89, 147, 20, red); tft.fillCircle(89, 204, 20, red); tft.setTextColor(white); tft.setFont(DroidSans_12_Bold); tft.setCursor(84, 31); tft.print("15 Minuten"); tft.setCursor(84, 87); tft.print("30 Minuten"); tft.setCursor(84, 143); tft.print("45 Minuten"); tft.setCursor(84, 199); tft.print("60 Minuten"); // Weiter zur Auswahl der WAV-Datei tft.fillCircle(299, 120, 20, white); TFTrefresh = false; } // Unteruntermenü "Snoozlemusik auswählen" if (menuPage == 11 && TFTrefresh == true) { tft.fillScreen(ILI9341_BLACK); // Zurück zum Snoozlemenü 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(DroidSans_12_Bold); tft.setCursor(64, 31); tft.print("Meeresrauschen 1"); tft.setCursor(64, 87); tft.print("Meeresrauschen 2"); tft.setCursor(64, 143); tft.print("Regen"); tft.setCursor(64, 199); tft.print("Regen mit Donner"); // 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(DroidSans_12_Bold); tft.setCursor(194, 31); tft.print("frei"); tft.setCursor(194, 87); tft.print("frei"); tft.setCursor(194, 143); tft.print("frei"); tft.setCursor(194, 199); tft.print("frei"); 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(DroidSans_8); 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); // 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(DroidSans_12_Bold); tft.setCursor(64, 31); tft.print("Weckzeitvorlauf"); tft.setCursor(64, 87); tft.print("Weckmusik"); tft.setCursor(64, 143); tft.print("frei"); tft.setCursor(64, 199); 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(DroidSans_12_Bold); tft.setCursor(194, 31); tft.print("frei"); tft.setCursor(194, 87); tft.print("frei"); tft.setCursor(194, 143); tft.print("frei"); tft.setCursor(194, 199); tft.print("frei"); TFTrefresh = false; } // Unteruntermenü "Weckzeitvorlauf" if (menuPage == 31 && TFTrefresh == true) { tft.fillScreen(ILI9341_BLACK); // Zurück zum "Einstellungen" tft.fillCircle(20, 120, 20, white); // Optionen tft.setFont(DroidSans_12_Bold); tft.setCursor(84, 34); if (alarmAdvancetime == 15) { tft.fillCircle(89, 40, 20, red); tft.setTextColor(white); } else { tft.fillCircle(89, 40, 20, white); tft.setTextColor(red); } tft.print("15 Minuten Vorlauf"); tft.setCursor(84, 114); if (alarmAdvancetime == 30) { tft.fillCircle(89, 120, 20, red); tft.setTextColor(white); } else { tft.fillCircle(89, 120, 20, white); tft.setTextColor(red); } tft.print("30 Minuten Vorlauf"); tft.setCursor(84, 194); if (alarmAdvancetime == 45) { tft.fillCircle(89, 200, 20, red); tft.setTextColor(white); } else { tft.fillCircle(89, 200, 20, white); tft.setTextColor(red); } tft.print("45 Minuten Vorlauf"); TFTrefresh = false; } // Unteruntermenü "Weckmusik auswählen" if (menuPage == 32 && 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(DroidSans_12_Bold); tft.setCursor(64, 31); tft.print("Meeresrauschen 1"); tft.setCursor(64, 87); tft.print("Meeresrauschen 2"); tft.setCursor(64, 143); tft.print("Regen"); tft.setCursor(64, 199); tft.print("Regen mit Donner"); // 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(DroidSans_12_Bold); tft.setCursor(194, 31); tft.print("frei"); tft.setCursor(194, 87); tft.print("frei"); tft.setCursor(194, 143); tft.print("frei"); tft.setCursor(194, 199); tft.print("frei"); 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(DroidSans_12_Bold); tft.setCursor(64, 31); tft.print("Zeitsignal"); tft.setCursor(64, 87); tft.print("LSM303"); tft.setCursor(64, 143); tft.print("frei"); tft.setCursor(64, 199); 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(DroidSans_12_Bold); tft.setCursor(194, 31); tft.print("TSL2591"); tft.setCursor(194, 87); tft.print("frei"); tft.setCursor(194, 143); tft.print("frei"); tft.setCursor(194, 199); 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.setFontAdafruit(); tft.setTextSize(1); // Datenausgabe tft.setFontAdafruit(); 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.setFontAdafruit(); 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.setFontAdafruit(); 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(DroidSans_13); tft.setTextColor(white, black); tft.setCursor(125, 15); tft.print("Weckzeit"); tft.fillRect(80,90, 50, 50, black); tft.setFont(DroidSans_24); tft.setTextColor(red, black); tft.setCursor(90, 108); if(displayedAlarmHour < 10) { tft.print('0'); } tft.print(displayedAlarmHour); tft.setCursor(159, 108); tft.print(":"); tft.fillRect(185,90, 50, 50, black); tft.setCursor(195, 108); if(displayedAlarmMinute < 10) { tft.print('0'); } tft.print(displayedAlarmMinute); tft.setFont(DroidSans_13); tft.setTextColor(white, black); tft.setCursor(125, 220); 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(DroidSans_12_Bold); tft.setCursor(84, 31); 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, 87); 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, 143); 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, 199); 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/Schlummern aus tft.setTextColor(white); tft.setFont(DroidSans_18_Bold); if (snoozeOn == false) { tft.setCursor(60, 95); tft.print("Wecker"); } else if (snoozeOn == true) { tft.setCursor(50, 95); tft.print("Schlummern"); } tft.setCursor(85, 135); tft.print("aus"); tft.fillRect(213, 20, 2, 200, white); // Schlummern tft.setFont(DroidSans_10); tft.setCursor(225, 120); tft.print("Schlummern"); TFTrefresh = false; } // Untermenü "Snoozle aus/Lautstärke" if (menuPage == 8 && TFTrefresh == true) { tft.fillScreen(ILI9341_BLACK); // Snoozle aus tft.setTextColor(white); tft.setFont(DroidSans_18_Bold); tft.setCursor(60, 95); tft.print("Snoozle"); tft.setCursor(85, 135); tft.print("aus"); // Lautstärke tft.fillRect(213, 20, 2, 200, white); tft.setFont(AwesomeF000_28); tft.setCursor(250, 40); tft.print((char)40); tft.setFont(DroidSans_10); tft.setCursor(225, 120); tft.print("lauter / leiser"); tft.setFont(AwesomeF000_28); tft.setCursor(255, 160); tft.print((char)39); 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; Serial.print("pctime: "); Serial.print(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"); } } 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"); } } void logSDcard() { // Daten auf SD-Karte loggen // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. File dataFile = SD.open("datalog.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.print(millis()); dataFile.print(","); dataFile.println(accelZ); dataFile.close(); // print to the serial port too: Serial.print(millis()); Serial.print(","); Serial.println(lux); } // if the file isn't open, pop up an error: else { Serial.println("error opening datalog.txt"); } } Der Sketch verwendet 119.152 Bytes (11%) des Programmspeicherplatzes. Das Maximum sind 1.048.576 Bytes. Globale Variablen verwenden 35.556 Bytes (13%) des dynamischen Speichers, 226.588 Bytes für lokale Variablen verbleiben. Das Maximum sind 262.144 Bytes. {{tag>Arduino Schlafphasenwecker Teensy}}