====== Schlafphasenwecker Programmversion 0.7 ====== Nachdem in [[arduino:schlafphasenwecker:programmversion_0.6|Programmversion 0.6]] vor allem das Teensy Audio Adaptor Board eingebunden wurde, werden in Programmversion 0.7 der Temperatur- und Luftfeuchtigkeitssensor DHT22 und die NeoPixel für das Ziffernblatt integriert. Weitere Änderungen: * Die Uhrzeit wird auf dem NeoPixel-Ring angezeigt. * Die Helligkeit des Ziffernblatts wird abhängig von der Umgebungsbeleuchtung geregelt. * Die Lautstärke des akustischen Weckalarms kann eingestellt werden. * Im Snoozle-Modus nach Ablauf der vorausgewählten Zeit die Lautstärke langsam reduziert. * Jeder Alarm kann abgebrochen oder in einen Schlummermodus überführt werden. Im Schlummermodus wird nach einer vorausgewählten Schlummerzeit der akustische Alarm aktiviert. * Das Menü wurde an verschiedenen Stellen aufgehübst und erweitert. * Es kann ein visueller Weckalarm ausgewählt werden. * kleinere Optimierungen des Programmcodes * Fehlerbeseitigungen * Der Snoozle-Modus behält jetzt die zuletzt eingestellte Lautstärke korrekt. * Die Rate erfolgreich empfangener Zeitsignale wird jetzt korrekt berechnet. ToDos: * Die Helligkeit des Ziffernblatts muss in dunklen Lichtsituationen stärker reduziert werden. * Die Menüs müssen aufgehübscht werden. * Die Funktion zum Einstellen der Alarmzeit berechnet unter bestimmten Bedingungen die Startzeit für den Vorlauf falsch. * Der Verstärker macht bei den Dateien "VOEGEL01.WVA" und "RELAX02.WVA" eigenartige Knattergeräusche. * DIE Datei "REGEN03.WAV" wird nicht abgespielt. * Die Farbtemperatur des Ziffernblatts sollte abhängig von Sonnenauf- und Untergangszeit sein. Hilfreiche Links: * https://learn.adafruit.com/neopixel-60-ring-clock/code // Schlafphasenwecker Version 0.7.3 // 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 // NeoPixel #include // DHT22-Sensor #include // Fonts einbinden #include "font_DroidSans.h" // Droid Sans Regular #include "font_DroidSans_Bold.h" // Droid Sans Bold #include "font_AwesomeF000.h" // AwesomeF000 (Symbole) #include "font_AwesomeF080.h" // AwesomeF080 (Symbole) #include "font_AwesomeF100.h" // AwesomeF100 (Symbole) #include "font_AwesomeF180.h" // AwesomeF180 (Symbole) #include "font_AwesomeF200.h" // AwesomeF200 (Symbole) // Definiert Adressen im EEPROM int addrAlarmHour = 0; int addrAlarmMinute = 1; int addrAlarmMode = 2; int addrDisplayedAlarmHour = 3; int addrDisplayedAlarmMinute = 4; int addrAlarmAdvancetime = 5; // Vorlauf für die Alarmfunktion int addrAlarmFile = 6; // Musikdatei für die Alarmfunktion int addrSnoozleFile = 7; // Musikdatei für die Einschalffunktion (Snoozle) int addrSnoozleGain = 8; // Lautstärke der Einschlaffunkion (Snoozle) int addrAlarmGain = 9; // Lautstärke der Alarmfunktion // Definiert die Pins #define DCF_PIN 2 // DCF77-Modul #define DCF_INTERRUPT 2 // Interrupt number associated with pin #define DHTPIN 3 #define TFTbacklightPin 4 // PWM Backlight TFT #define NEOPIXELPIN 33 // NeoPixel // 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); // Parameter 1 = number of pixels in strip // Parameter 2 = Arduino pin number (most are valid) // Parameter 3 = pixel type flags, add together as needed: // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products) Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, NEOPIXELPIN, NEO_GRBW + NEO_KHZ800); // IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across // pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input // and minimize distance between Arduino and first pixel. Avoid connecting // on a live circuit...if you must, connect GND first. int numPixels = 60; // Anzahl der NeoPixel // 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(); // Initialisiert den DHT22-Sensor #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); // 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. //time_t startTime; // Zeit, zu der die Uhr zuletzt gestartet wurde unsigned long timesinceDCFsignal; // Zeit im Format time_t, die seit dem letzten vollstänig empfangenen DCF77-Zeitzeichen vergangen ist. unsigned long noDCFsignal; // Zeit in Sekunden, die seit dem Systemstart bis zum ersten erfolgreich empfangenen DCF-Zeitzeichen vergangen ist. (Läuft nach ca. 52 Tagen über.) time_t timestampDCFsignal; // Zeitstempel im Format time_t, für das zuletzt vollständig empfangene Zeitsignal. 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. boolean clockfaceOn = true; // Kann auf falsch gesetzt werden, om das Ziffernblatt zugunsten anderer Effekte zu deaktivieren. int8_t intensity = 1; // Wert für die Helligkeit des Ziffernblatts float x = 4.712388980; // Start- und Zählwert für verschiedene Beleuchtungseffekte int i; // Zählwert für verschiedene Beleuchtungseffekte int j; // Zählwert für verschiedene Beleuchtungseffekte int k; // Zählwert für verschiedene Beleuchtungseffekte int l; // Zählwert für verschiedene Beleuchtungseffekte // Definiert die globalen RGBW-Werte für das NeoPixel-Ziffernblatt byte r = 0; byte g = 0; byte b = 0; byte w = 0; 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 int16_t alarmGain = 30; // Lautstärke der Alarmfunktion (wird mit 0.004 multipliziert). Wird als Integer definiert, damit sie theoretisch negativ weden kann. boolean alarmOn = false; // Wird wahr, sobald ein Schlafphasenalarm aktiviert wird 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 int16_t snoozleGain = 70; // Lautstärke der Einschlaffunktion (wird mit 0.004 multipliziert). Wird als Integer definiert, damit sie theoretisch negativ weden kann. int16_t sg; // Variable für das Fade out der Snoozle-Musik 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; uint16_t filteredLux; 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 Kalman luxFilter(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; float h; // Wert für die Luftfeuchtigkeit float c; // Wert für Temperatur in Grad Celsius float f; // Wert für Temperatur in Fahrenheit float taupunkt; // Wert für den Taupunkt 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; // Real time Clock unsigned long previousMillisAlarmClock = 0; // Alarm-Funktion unsigned long previousMillisSnoozleTime = 0; // Einschlaf-Funktion unsigned long previousMillisClockFace = 0; // Ziffernblatt unsigned long previousMillisTFTScreen = 0; // TFT-Screen unsigned long previousMillisTouchScreen = 0; // Touch-Sensor unsigned long previousMillisSensorData = 0; // IMU und TSL2591 unsigned long previousMillisDHTSensor = 0; // DHT22 unsigned long previousMillisSerialPrint = 0; // Serielle Ausgabe unsigned long previousMillisDCFPulseLength = 0; // Pulsweitenmessung // 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 const unsigned long intervalClockFace = 20; // konstanter Delay für das Ziffernblatt 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 intervalDHTSensor = 60000; // konstanter Delay für Auslesen ded Temperatursensors 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(DHTPIN, INPUT_PULLUP); // DHT22-Sensor 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 // Intitialisiert den DHT22 dht.begin(); // 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(12); sgtl5000_1.enable(); sgtl5000_1.muteHeadphone(); sgtl5000_1.volume(0.8); sgtl5000_1.audioPostProcessorEnable(); sgtl5000_1.enhanceBassEnable(); SPI.setMOSI(7); SPI.setSCK(14); if (!(SD.begin(10))) { Serial.println("Unable to access the SD card"); } Serial.println("Teensy Audio Adaptor initialisiert"); // Initialisiert den Class D Amplifier audioamp.begin(); audioamp.setAGCCompression(TPA2016_AGC_OFF); // Turn off AGC // audioamp.setAGCCompression(TPA2016_AGC_2); // Set compression to 1:2 audioamp.setLimitLevelOn(); audioamp.setLimitLevel(10); // Initialisiert den NeoPixel-Teststrip strip.begin(); strip.show(); // Initialize all pixels to 'off' // 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 alarmGain = EEPROM.read(addrAlarmGain); // die Lautstärke für die Alarmfunktion snoozleFile = EEPROM.read(addrSnoozleFile); // die ausgewählte WAV-Datei snoozleGain = EEPROM.read(addrSnoozleGain); // die Lautstärke für die Einschlaffunktion (Snoozle) Serial.println("Werte werden aus dem EEPROM ausgelesen:"); Serial.print("alarmAdvancetime: "); Serial.println(alarmAdvancetime); Serial.print("alarmFile: "); Serial.println(alarmFile); Serial.print("alarmGain: "); Serial.println(alarmGain); Serial.print("snoozleFile: "); Serial.println(snoozleFile); Serial.print("snoozleGain: "); Serial.println(snoozleGain); // 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; // die Variable wird wahr receivedDCFsignals = receivedDCFsignals + 1; timestampDCFsignal = now(); } // Berechne die Zeit die seit dem Empfang des letzten vollständig empfangenen Zeitsignals vergangen ist if (DCFtimesignalFound == false) { noDCFsignal = currentMillis / 1000; // in Sekunden } else { timesinceDCFsignal = now() - timestampDCFsignal; // im Format time_t } // Berechnet die Quote erfolgreich empfangener DCF77-Signale seit dem letzten Systemstart DCFsuccessRate = (float(receivedDCFsignals) / ((millis() / 60000))) * 100; //Speichere die aktuelle Zeit in die zughörige Variable previousMillisSetRTC = currentMillis; } // Ziffernblatt if ((unsigned long)(currentMillis - previousMillisClockFace) >= intervalClockFace) { // Berechnung der Helligkeit des Ziffernblatts /* if (filteredLux <= 20) {intensity = 10;} else if (filteredLux > 20 && filteredLux <= 100) {intensity = 5;} else if (filteredLux > 100 && filteredLux <= 10000) {intensity = 4;} else if (filteredLux > 10000 && filteredLux <= 20000) {intensity = 3;} else if (filteredLux > 20000 && filteredLux <= 40000) {intensity = 2;} else if (filteredLux > 40000) {intensity = 1;} Serial.print("Intensitaet: "); Serial.println(intensity); */ intensity = round(10 - (log(filteredLux/5))); Serial.print("Intensitaet: "); Serial.println(intensity); if (intensity > 10) { intensity = 10; } if (intensity < 0) { intensity = 0; } // Anmerkung: // Wenn bei 7 NeoPixelen eine Farbe mit einem Wert von 32 (1/8 der max. Intensität) angesteuert wird, ist das für einen dunklen Raum zu hell. // Je mehr NeoPixel von einem Ziffernblatteffekt verwendet werden, desto besser muss die Anzahl der aktiven NeoPixel berücksichtigt werden. if (clockfaceOn == true) { // Das Ziffernblatt wird angezeit, wenn die Variable wahr ist strip.clear(); /* // Stundenskaka for (int i = 0; i < 60; i = i + 5) { strip.setPixelColor(i, r, g, b, 32); } */ // Stundenanzeige if (hour() < 12) { for (int j = (hour() * 5); j < ((hour() * 5) + 6); j++) { strip.setPixelColor(j, r, g, (250 / (intensity *2)), (250 / intensity)); } } else if (hour() >= 12) { for (int j = ((hour() - 12) * 5); j < (((hour() - 12) * 5) + 6); j++) { strip.setPixelColor(j, r, g, (250 / (intensity *2)), (250 / intensity)); } } // Minutenanzeige k = minute(); strip.setPixelColor(k, r, g, (250 / intensity), (250 / (intensity *4))); // Sekundenanzeige l = second(); strip.setPixelColor(l, r, g, (250 / intensity), (250 / (intensity *4))); strip.show(); } //Speichere die aktuelle Zeit in die zughörige Variable previousMillisClockFace = 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.print(snoozleOn); Serial.print("; snoozleFile: "); Serial.println(snoozleFile); */ // Wenn die aktuelle Zeit kleiner ist als die eingestellte Snoozle-Zeit, dann ... if (snoozleOn == true) { if (now() < snoozleTime) { audioamp.enableChannel(true, true); // Schaltet beide Ausgänge des Verstärkers online snoozleGain = EEPROM.read(addrSnoozleGain); // Ließt die Lautstärke für die Einschlaffunktion aus dem EEPROM mixer1.gain(0, (snoozleGain * 0.005)); // Stellt die Lautstärke ein mixer2.gain(0, (snoozleGain * 0.005)); } if (playSdWav1.isPlaying() == false) { Serial.println("Start playing"); if (snoozleFile == 1) { playSdWav1.play("MEER01.WAV"); } else if (snoozleFile == 2) { playSdWav1.play("REGEN01.WAV"); } else if (snoozleFile == 3) { playSdWav1.play("REGEN02.WAV"); } else if (snoozleFile == 4) { playSdWav1.play("REGEN03.WAV"); } if (snoozleFile == 5) { playSdWav1.play("REGEN04.WAV"); } else if (snoozleFile == 6) { playSdWav1.play("REGEN05.WAV"); } else if (snoozleFile == 7) { playSdWav1.play("VOEGEL01.WAV"); } else if (snoozleFile == 8) { playSdWav1.play("RELAX02.WAV"); } } if (menuPage != 8) { // Das Menü "Snoozle aus/Lautstärke" soll nur einmal aufgerufen werden. menuPage = 8; TFTrefresh = true; } } if (now() >= snoozleTime && snoozleOn == true) { Serial.println("Snoozletime expired"); // Reduziere langsam die Lautstärke snoozleGain = snoozleGain - 1; // Verringert die Lautstärke mixer1.gain(0, (snoozleGain * 0.005)); // Stellt die Lautstärke ein mixer2.gain(0, (snoozleGain * 0.005)); Serial.print("Reducing volume"); Serial.print(", snoozleGain: "); Serial.println(snoozleGain); // Wenn die Lautstärke null ist, wird die Wiedergabe gestoppt und in das Hauptmenü gewechselt if (snoozleGain <= 0) { snoozleOn = false; playSdWav1.stop(); Serial.println("Stop playing"); audioamp.enableChannel(false, false); // Schaltet den Verstärker aus if (menuPage == 8) { // Wenn Menü "8" angezeigt wird ... menuPage = 0; // ... rufe das Hauptmenü auf. TFTrefresh = true; } } } //Speichere die aktuelle Zeit in die zughörige Variable previousMillisSnoozleTime = currentMillis; } // Alarm-Funktionen (alarm und Snooze) 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 >= 10) { // Weil dieser Alarm sehr schonend ist, kann er früh gestartet werden clockfaceOn = false; Serial.print("ALARM 1!!!!"); // Ansteuerung der NeoPixel if (r < 255) { r = r + 1; // r wird in jeder Schleife etwas erhöht } if (r == 255 && g < 120) { g = g + 1; } //if (g == 255 && b < 255) { // b = b + 1; //} if (g == 120 && w < 255) { w = w + 1; } Serial.print("; r = "); Serial.print(r); Serial.print("; g = "); Serial.print(g); Serial.print("; b = "); Serial.print(b); Serial.print("; w = "); Serial.println(w); for (int i = 0; i < numPixels; i++) { strip.setPixelColor(i, r, g, b, w); } strip.show(); } } // Wecken mit Musik else if (alarmMode == 2) { Serial.println("Alarmphase 2 aktiv!"); if (eventTotal >= 100) { audioamp.enableChannel(true, true); // Schaltet beide Ausgänge des Verstärkers online alarmGain = EEPROM.read(addrAlarmGain); // Ließt die Lautstärke für die Alarmfunktion aus dem EEPROM mixer1.gain(1, (alarmGain * 0.005)); // Stellt die Lautstärke ein mixer2.gain(1, (alarmGain * 0.005)); 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) { audioamp.enableChannel(true, true); // Schaltet beide Ausgänge des Verstärkers online alarmGain = EEPROM.read(addrAlarmGain); // Ließt die Lautstärke für die Alarmfunktion aus dem EEPROM mixer1.gain(1, (alarmGain * 0.005)); // Stellt die Lautstärke ein mixer2.gain(1, (alarmGain * 0.005)); Serial.print("ALARM 3!!!!"); } } // 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; } } // Schlummeralarm if (snoozeOn == true && now() >= snoozeTime) { Serial.println("Schlummerlarm!"); if (playSdWav2.isPlaying() == false) { audioamp.enableChannel(true, true); // Schaltet beide Ausgänge des Verstärkers online alarmGain = EEPROM.read(addrAlarmGain); // Ließt die Lautstärke für die Alarmfunktion aus dem EEPROM mixer1.gain(1, (alarmGain * 0.005)); // Stellt die Lautstärke ein mixer2.gain(1, (alarmGain * 0.005)); 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 Snooze-Funktion aktiv ist snoozeOn = 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); // Der Wert für Lux wird geglättet, weil er bei schnellen Änderungen des Umgebungslichts über das Ziel hinausschießt filteredLux = luxFilter.getFilteredValue(lux); Serial.print("lum: "); Serial.print(lum); Serial.print(", ir: "); Serial.print(ir); Serial.print(", full: "); Serial.print(full); Serial.print(", lux: "); Serial.print(lux); Serial.print(", filtered lux: "); Serial.println(filteredLux); /* // 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; } // Abfrage des Temperatur- und Luftfeuchtigkeitssensors DHT22 if ((unsigned long)(currentMillis - previousMillisDHTSensor) >= intervalDHTSensor) { // Auslesen des Temperatursensors DHT22 // Reading temperature or humidity takes about 250 milliseconds! // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) h = dht.readHumidity(); // Read temperature as Celsius (the default) c = dht.readTemperature(); // Read temperature as Fahrenheit (isFahrenheit = true) f = dht.readTemperature(true); // Check if any reads failed and exit early (to try again). if (isnan(h) || isnan(c) || isnan(f)) { Serial.println("Failed to read from DHT sensor!"); return; } // Compute heat index in Fahrenheit (the default) float hif = dht.computeHeatIndex(f, h); // Compute heat index in Celsius (isFahreheit = false) float hic = dht.computeHeatIndex(c, h, false); // Taupunkt berechnen float a = 17.271; float b = 237.7; float taupunktTmp = (a * c) / (b + c) + log(h/100); taupunkt = (b * taupunktTmp) / (a - taupunktTmp); Serial.print("Relative Luftfeuchtigkeit: "); Serial.print(h); Serial.print(" %\t"); Serial.print("Temperatur: "); Serial.print(c); Serial.print(" *C "); Serial.print(f); Serial.print(" *F\t"); Serial.print("Hitzeindex: "); Serial.print(hic); Serial.print(" *C "); Serial.print(hif); Serial.print(" *F\t"); Serial.print("Taupunkt: "); Serial.print(taupunkt); Serial.println(" *C"); //Speichere die aktuelle Zeit in die zughörige Variable previousMillisDHTSensor = 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, b) keine Schlummerfunktion oder c) keine Snoozlemusik läuft. if (alarmOn == false && snoozeOn == 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; } tft.fillScreen(ILI9341_BLACK); 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; } // Debugging Serial.print("Aktueller Zeitindex: "); Serial.print(now()); Serial.print(", berechnete SnoozleTime: "); Serial.println(snoozleTime); tft.fillScreen(ILI9341_BLACK); 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; tft.fillScreen(ILI9341_BLACK); } // Auswahl Musik 1 else if ((tx >= 51) && (tx <= 184) && (ty >= 0) && (ty <= 59)) { snoozleFile = 1; EEPROM.update(addrSnoozleFile, snoozleFile); } // Auswahl Musik 2 else if ((tx >= 51) && (tx <= 184) && (ty >= 60) && (ty <= 120)) { snoozleFile = 2; EEPROM.update(addrSnoozleFile, snoozleFile); } // Auswahl Musik 3 else if ((tx >= 51) && (tx <= 184) && (ty >= 121) && (ty <= 180)) { snoozleFile = 3; EEPROM.update(addrSnoozleFile, snoozleFile); } // Auswahl Musik 4 else if ((tx >= 51) && (tx <= 184) && (ty >= 181) && (ty <= 240)) { snoozleFile = 4; EEPROM.update(addrSnoozleFile, snoozleFile); } // Auswahl Musik 5 else if ((tx >= 186) && (tx <= 319) && (ty >= 0) && (ty <= 59)) { snoozleFile = 5; EEPROM.update(addrSnoozleFile, snoozleFile); } // Auswahl Musik 6 else if ((tx >= 186) && (tx <= 319) && (ty >= 60) && (ty <= 120)) { snoozleFile = 6; EEPROM.update(addrSnoozleFile, snoozleFile); } // Auswahl Musik 7 else if ((tx >= 186) && (tx <= 319) && (ty >= 121) && (ty <= 180)) { snoozleFile = 7; EEPROM.update(addrSnoozleFile, snoozleFile); } // Auswahl Musik 8 else if ((tx >= 186) && (tx <= 319) && (ty >= 181) && (ty <= 240)) { snoozleFile = 8; EEPROM.update(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ü Wecklautstärke 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; } */ tft.fillScreen(ILI9341_BLACK); 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.update(addrAlarmAdvancetime, alarmAdvancetime); } else if ((tx >= 50) && (tx <= 320) && (ty >= 80) && (ty <= 159)) { alarmAdvancetime = 30; EEPROM.update(addrAlarmAdvancetime, alarmAdvancetime); } else if ((tx >= 50) && (tx <= 320) && (ty >= 160) && (ty <= 239)) { alarmAdvancetime = 45; EEPROM.update(addrAlarmAdvancetime, alarmAdvancetime); } tft.fillScreen(ILI9341_BLACK); 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.update(addrAlarmFile, alarmFile); } // Auswahl Musik 2 else if ((tx >= 51) && (tx <= 184) && (ty >= 60) && (ty <= 120)) { alarmFile = 2; EEPROM.update(addrAlarmFile, alarmFile); } // Auswahl Musik 3 else if ((tx >= 51) && (tx <= 184) && (ty >= 121) && (ty <= 180)) { alarmFile = 3; EEPROM.update(addrAlarmFile, alarmFile); } // Auswahl Musik 4 else if ((tx >= 51) && (tx <= 184) && (ty >= 181) && (ty <= 240)) { alarmFile = 4; EEPROM.update(addrAlarmFile, alarmFile); } /* // Auswahl Musik 5 else if ((tx >= 186) && (tx <= 319) && (ty >= 0) && (ty <= 59)) { alarmFile = 5; EEPROM.update(addrAlarmFile, alarmFile); } // Auswahl Musik 6 else if ((tx >= 186) && (tx <= 319) && (ty >= 60) && (ty <= 120)) { alarmFile = 6; EEPROM.update(addrAlarmFile, alarmFile); } // Auswahl Musik 7 else if ((tx >= 186) && (tx <= 319) && (ty >= 121) && (ty <= 180)) { alarmFile = 7; EEPROM.update(addrAlarmFile, alarmFile); } // Auswahl Musik 8 else if ((tx >= 186) && (tx <= 319) && (ty >= 181) && (ty <= 240)) { alarmFile = 8; EEPROM.update(addrAlarmFile, alarmFile); } */ tft.fillScreen(ILI9341_BLACK); 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 Unteruntermenü DCF Zeitsignal else if ((tx >= 51) && (tx <= 184) && (ty >= 0) && (ty <= 59)) { menuPage = 41; } // Zum Unteruntermenü LSM303 else if ((tx >= 51) && (tx <= 184) && (ty >= 60) && (ty <= 120)) { menuPage = 42; } /* // Zum Unteruntermenü "frei" else if ((tx >= 51) && (tx <= 184) && (ty >= 121) && (ty <= 180)) { menuPage = 43; } // Zum Unteruntermenü "frei" else if ((tx >= 51) && (tx <= 184) && (ty >= 181) && (ty <= 240)) { menuPage = 44; } */ // Zum Unteruntermenü TSL2591-Sensor else if ((tx >= 186) && (tx <= 319) && (ty >= 0) && (ty <= 59)) { menuPage = 45; } // Zum Unteruntermenü DHT22 Sensor else if ((tx >= 186) && (tx <= 319) && (ty >= 60) && (ty <= 120)) { menuPage = 46; } /* // Zum Unteruntermenü "frei" else if ((tx >= 186) && (tx <= 319) && (ty >= 121) && (ty <= 180)) { menuPage = 47; } // Zum Unteruntermenü "frei" else if ((tx >= 186) && (tx <= 319) && (ty >= 181) && (ty <= 240)) { menuPage = 48; } */ tft.fillScreen(ILI9341_BLACK); TFTrefresh = true; prevtouch2 = false; } // Unteruntermenü 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; } tft.fillScreen(ILI9341_BLACK); TFTrefresh = true; prevtouch2 = false; } // Unteruntermenü 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; } tft.fillScreen(ILI9341_BLACK); TFTrefresh = true; prevtouch2 = false; } // Unteruntermenü 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; } tft.fillScreen(ILI9341_BLACK); TFTrefresh = true; prevtouch2 = false; } // Unteruntermenü DHT22 Sensor if (menuPage == 46 && 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; } tft.fillScreen(ILI9341_BLACK); 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.update(addrDisplayedAlarmHour, int8_t(displayedAlarmHour)); EEPROM.update(addrDisplayedAlarmMinute, int8_t(displayedAlarmMinute)); EEPROM.update(addrAlarmHour, int8_t(alarmHour)); EEPROM.update(addrAlarmMinute, int8_t(alarmMinute)); EEPROM.update(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; tft.fillScreen(ILI9341_BLACK); } else if ((tx >= 50) && (tx <= 268) && (ty >= 0) && (ty <= 59)) { alarmMode = 0; } else if ((tx >= 50) && (tx <= 268) && (ty >= 60) && (ty <= 119)) { alarmMode = 1; } else if ((tx >= 50) && (tx <= 268) && (ty >= 120) && (ty <= 179)) { alarmMode = 2; } else if ((tx >= 50) && (tx <= 268) && (ty >= 180) && (ty <= 239)) { alarmMode = 3; } // Zum Menü Wecklautstärke stellen else if ((tx >= 269) && (tx <= 319) && (ty >= 0) && (ty <= 239)) { menuPage = 52; tft.fillScreen(ILI9341_BLACK); // Um die Wecklautstärke einstellen zu können, muss die in den EInstellungen ausgewählte Datei mit der eingestellten Lautstärke abgespielt werden audioamp.enableChannel(true, true); // Schaltet beide Ausgänge des Verstärkers online alarmGain = EEPROM.read(addrAlarmGain); // Ließt die Lautstärke für die Alarmfunktion aus dem EEPROM mixer1.gain(1, (alarmGain * 0.005)); // Stellt die Lautstärke ein mixer2.gain(1, (alarmGain * 0.005)); 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"); } } } TFTrefresh = true; prevtouch2 = false; } // Untermenü Wecklautstärke stellen if (menuPage == 52 && touch2 == false && prevtouch2 == true) { // Zurück zum Untermenü Informationen if ((tx >= 0) && (tx <= 49) && (ty >= 0) && (ty <= 240)) { menuPage = 51; tft.fillScreen(ILI9341_BLACK); playSdWav2.stop(); // Die Wiedergabe der Musik wird gestoppt Serial.println("Stop playing"); audioamp.enableChannel(false, false); // Der Verstärker wird deaktiviert } // Lautstärke einstellen else if ((tx >= 214) && (tx <= 319) && (ty >= 0) && (ty <= 119)) { // Lautstärke erhöhen alarmGain = alarmGain + 10; if (alarmGain >= 200) { alarmGain = 200; } EEPROM.update(addrAlarmGain, int8_t(alarmGain)); // schreibt den Wert in das EEPROM mixer1.gain(1, (alarmGain * 0.005)); mixer2.gain(1, (alarmGain * 0.005)); } else if ((tx >= 214) && (tx <= 319) && (ty >= 120) && (ty <= 239)) { // Lautstärke verringern alarmGain = alarmGain - 10; if (alarmGain <= 0) { alarmGain = 0; } EEPROM.update(addrAlarmGain, int8_t(alarmGain)); // schreibt den Wert in das EEPROM mixer1.gain(1, (alarmGain * 0.005)); mixer2.gain(1, (alarmGain * 0.005)); } Serial.print("Gain = "); Serial.println(alarmGain); 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; // Das Hauptmenü wird aufgerufen. alarmOn = false; // Der Alarm wird ggf. beendet. snoozeOn = false; // Der Schlummeralarm wird ggf. beendet. clockfaceOn = true; // Das Ziffernblatt wirg ggf. aktiviert. playSdWav2.stop(); // Die Musikwiedergabe wird ggf. gestoppt. Serial.println("Stop playing"); audioamp.enableChannel(false, false); // Der Verstärker wird ausgeschaltet r = 0; // setzt den globalen Farbwert zurück g = 0; // setzt den globalen Farbwert zurück b = 0; // setzt den globalen Farbwert zurück w = 0; // setzt den globalen Farbwert zurück for (int i = 0; i < numPixels; i++) { strip.setPixelColor(i, r, g, b, w); } strip.show(); } // Schlummern else if ((tx >= 214) && (tx <= 319) && (ty >= 0) && (ty <= 239)) { alarmOn = false; // Der Alarm wird ggf. beendet. snoozeOn = true; // Der Schlummerlarm wird aktiviert. clockfaceOn = true; // Das Ziffernblatt wirg ggf. aktiviert. playSdWav2.stop(); // Die Musikwiedergabe wird ggf. gestoppt. Serial.println("Stop playing"); audioamp.enableChannel(false, false); // Der Verstärker wird ausgeschaltet r = 0; // setzt den globalen Farbwert zurück g = 0; // setzt den globalen Farbwert zurück b = 0; // setzt den globalen Farbwert zurück w = 0; // setzt den globalen Farbwert zurück for (int i = 0; i < numPixels; i++) { strip.setPixelColor(i, r, g, b, w); } strip.show(); snoozeTime = now() + snoozeDelay; // Der Countdown für den Schlummeralarm wird berechnet. // Debugging Serial.print("Zeitstempel: "); Serial.print(now()); Serial.print(", snoozeTime: "); Serial.println(snoozeTime); } 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(); Serial.println("Stop playing"); audioamp.enableChannel(false, false); } else if ((tx >= 214) && (tx <= 319) && (ty >= 0) && (ty <= 119)) { // Lautstärke erhöhen snoozleGain = snoozleGain + 10; if (snoozleGain >= 200) { snoozleGain = 200; } EEPROM.update(addrSnoozleGain, int8_t(snoozleGain)); // schreibt den Wert in das EEPROM mixer1.gain(0, (snoozleGain * 0.005)); mixer2.gain(0, (snoozleGain * 0.005)); } else if ((tx >= 214) && (tx <= 319) && (ty >= 120) && (ty <= 239)) { // Lautstärke verringern snoozleGain = snoozleGain - 10; if (snoozleGain <= 0) { snoozleGain = 0; } EEPROM.update(addrSnoozleGain, int8_t(snoozleGain)); // schreibt den Wert in das EEPROM mixer1.gain(0, (snoozleGain * 0.005)); mixer2.gain(0, (snoozleGain * 0.005)); } 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.drawRoundRect(1, 17, 120, 40, 20, ILI9341_WHITE); tft.drawRoundRect(1, 73, 120, 40, 20, ILI9341_WHITE); tft.drawRoundRect(1, 129, 120, 40, 20, ILI9341_WHITE); tft.drawRoundRect(1, 185, 120, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_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(ILI9341_WHITE); tft.setFont(DroidSans_13); tft.setCursor(190, 15); tft.print("Uhrzeit"); if (DCFtimesignalFound == true) { tft.setCursor(300, 5); tft.setFont(AwesomeF180_10); if (timesinceDCFsignal >= 86400) { // Die Farbe des Symbols hängt vom Alter des zuletzt erfolgreich empfangenen Zeitsignals ab tft.setTextColor(ILI9341_BLACK); } else if (timesinceDCFsignal < 86400 && timesinceDCFsignal >= 43200) { tft.setTextColor(ILI9341_DARKGREY); } else if (timesinceDCFsignal < 43200 && timesinceDCFsignal >= 3600) { tft.setTextColor(ILI9341_LIGHTGREY); } else if (timesinceDCFsignal < 3600) { tft.setTextColor(ILI9341_WHITE); } tft.print((char)107); tft.setTextColor(ILI9341_WHITE); } /* // Anzeige Sonnenaufgang und Sonnenuntergang tft.setTextColor(ILI9341_YELLOW); tft.setFont(AwesomeF180_13); tft.setCursor(140, 95); tft.print((char)5); tft.setTextColor(ILI9341_WHITE); tft.setFont(DroidSans_13); tft.print(AufgangStunden); tft.print(":"); if (AufgangMinuten<10.0) tft.print("0"); tft.print(AufgangMinuten); tft.setTextColor(ILI9341_BLUE); tft.setFont(AwesomeF180_13); tft.setCursor(140, 95); tft.print((char)6); tft.setTextColor(ILI9341_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, ILI9341_WHITE); //Anzeige Alarmzeit tft.setTextColor(ILI9341_WHITE); 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("Modus: "); if (alarmMode == 1) { tft.setFont(AwesomeF080_14); tft.print((char)35); } else if (alarmMode == 2) { tft.setFont(AwesomeF000_14); tft.print((char)38); } else if (alarmMode == 3) { tft.setFont(AwesomeF000_14); tft.print((char)38); tft.setFont(DroidSans_13); tft.print(" & "); tft.setFont(AwesomeF080_14); tft.print((char)35); } } TFTrefresh = false; } if (menuPage == 0 && ((unsigned long)(currentMillis - previousMillisTFTScreen) >= intervalTFTScreen)) { intervalTFTScreen = 1000; tft.fillRect(140,40, 160, 40, ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE); 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.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Optionen tft.drawRoundRect(69, 17, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(69, 73, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(69, 129, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(69, 185, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_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.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(290, 100); tft.print((char)1); TFTrefresh = false; } // Unteruntermenü "Snoozlemusik auswählen" if (menuPage == 11 && TFTrefresh == true) { //tft.fillScreen(ILI9341_BLACK); // Zurück zum Snoozlemenü tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Optionen tft.setFont(DroidSans_9_Bold); if (snoozleFile == 1) { tft.fillRect(49, 17, 130, 40, ILI9341_BLACK); tft.fillRoundRect(49, 17, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_BLACK); tft.setCursor(64, 32); tft.print("Meeresbrandung"); } else { tft.fillRect(49, 17, 130, 40, ILI9341_BLACK); tft.drawRoundRect(49, 17, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_WHITE); tft.setCursor(64, 32); tft.print("Meeresbrandung"); } if (snoozleFile == 2) { tft.fillRect(49, 73, 130, 40, ILI9341_BLACK); tft.fillRoundRect(49, 73, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_BLACK); tft.setCursor(64, 88); tft.print("Regenschauer"); } else { tft.fillRect(49, 73, 130, 40, ILI9341_BLACK); tft.drawRoundRect(49, 73, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_WHITE); tft.setCursor(64, 88); tft.print("Regenschauer"); } if (snoozleFile == 3) { tft.fillRect(49, 129, 130, 40, ILI9341_BLACK); tft.fillRoundRect(49, 129, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_BLACK); tft.setCursor(64, 144); tft.print("Gewitterschauer"); } else { tft.fillRect(49, 129, 130, 40, ILI9341_BLACK); tft.drawRoundRect(49, 129, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_WHITE); tft.setCursor(64, 144); tft.print("Gewitterschauer"); } if (snoozleFile == 4) { tft.fillRect(49, 185, 130, 40, ILI9341_BLACK); tft.fillRoundRect(49, 185, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_BLACK); tft.setCursor(64, 200); tft.print("geschl. Fenster"); } else { tft.fillRect(49, 185, 130, 40, ILI9341_BLACK); tft.drawRoundRect(49, 185, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_WHITE); tft.setCursor(64, 200); tft.print("geschl. Fenster"); } if (snoozleFile == 5) { tft.fillRect(184, 17, 130, 40, ILI9341_BLACK); tft.fillRoundRect(184, 17, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_BLACK); tft.setCursor(199, 32); tft.print("offenes Fenster"); } else { tft.fillRect(184, 17, 130, 40, ILI9341_BLACK); tft.drawRoundRect(184, 17, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_WHITE); tft.setCursor(199, 32); tft.print("offenes Fenster"); } if (snoozleFile == 6) { tft.fillRect(184, 73, 130, 40, ILI9341_BLACK); tft.fillRoundRect(184, 73, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_BLACK); tft.setCursor(199, 88); tft.print("leichter Regen"); } else { tft.fillRect(184, 73, 130, 40, ILI9341_BLACK); tft.drawRoundRect(184, 73, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_WHITE); tft.setCursor(199, 88); tft.print("leichter Regen"); } if (snoozleFile == 7) { tft.fillRect(184, 129, 130, 40, ILI9341_BLACK); tft.fillRoundRect(184, 129, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_BLACK); tft.setCursor(199, 144); tft.print("Voegel im Wald"); } else { tft.fillRect(184, 129, 130, 40, ILI9341_BLACK); tft.drawRoundRect(184, 129, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_WHITE); tft.setCursor(199, 144); tft.print("Voegel im Wald"); } if (snoozleFile == 8) { tft.fillRect(184, 185, 130, 40, ILI9341_BLACK); tft.fillRoundRect(184, 185, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_BLACK); tft.setCursor(199, 200); tft.print("Entspannung"); } else { tft.fillRect(184, 185, 130, 40, ILI9341_BLACK); tft.drawRoundRect(184, 185, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_WHITE); tft.setCursor(199, 200); tft.print("Entspannung"); } TFTrefresh = false; } // Untermenü "Ziffernblatteffekte" if (menuPage == 2 && TFTrefresh == true) { //tft.fillScreen(ILI9341_BLACK); // Zurück zum Hauptmenü tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Effekte einstellen tft.setTextColor(ILI9341_WHITE); 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.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Optionen tft.setFont(DroidSans_9_Bold); // Linke Spalte tft.drawRoundRect(49, 17, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(49, 73, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(49, 129, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(49, 185, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_WHITE); tft.setCursor(64, 32); tft.print("Weckzeitvorlauf"); tft.setCursor(64, 88); tft.print("Weckmusik"); tft.setCursor(64, 144); tft.print("Wecklautstaerke"); tft.setCursor(64, 200); tft.print("frei"); // Rechte Spalte tft.drawRoundRect(184, 17, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(184, 73, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(184, 129, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(184, 185, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_WHITE); tft.setCursor(199, 32); tft.print("frei"); tft.setCursor(199, 88); tft.print("frei"); tft.setCursor(199, 144); tft.print("frei"); tft.setCursor(199, 200); tft.print("frei"); TFTrefresh = false; } // Unteruntermenü "Weckzeitvorlauf" if (menuPage == 31 && TFTrefresh == true) { //tft.fillScreen(ILI9341_BLACK); // Zurück zum "Einstellungen" tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Optionen tft.setFont(DroidSans_12_Bold); tft.setCursor(84, 34); if (alarmAdvancetime == 15) { tft.fillCircle(89, 40, 20, ILI9341_RED); tft.setTextColor(ILI9341_WHITE); } else { tft.fillCircle(89, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_RED); } tft.print("15 Minuten Vorlauf"); tft.setCursor(84, 114); if (alarmAdvancetime == 30) { tft.fillCircle(89, 120, 20, ILI9341_RED); tft.setTextColor(ILI9341_WHITE); } else { tft.fillCircle(89, 120, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_RED); } tft.print("30 Minuten Vorlauf"); tft.setCursor(84, 194); if (alarmAdvancetime == 45) { tft.fillCircle(89, 200, 20, ILI9341_RED); tft.setTextColor(ILI9341_WHITE); } else { tft.fillCircle(89, 200, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_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.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Linke Spalte tft.fillCircle(69, 35, 20, ILI9341_RED); tft.fillCircle(69, 91, 20, ILI9341_RED); tft.fillCircle(69, 147, 20, ILI9341_RED); tft.fillCircle(69, 204, 20, ILI9341_RED); tft.setTextColor(ILI9341_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, ILI9341_RED); tft.fillCircle(199, 91, 20, ILI9341_RED); tft.fillCircle(199, 147, 20, ILI9341_RED); tft.fillCircle(199, 204, 20, ILI9341_RED); tft.setTextColor(ILI9341_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.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Linke Spalte tft.drawRoundRect(49, 17, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(49, 73, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(49, 129, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(49, 185, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_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.drawRoundRect(184, 17, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(184, 73, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(184, 129, 130, 40, 20, ILI9341_WHITE); tft.drawRoundRect(184, 185, 130, 40, 20, ILI9341_WHITE); tft.setTextColor(ILI9341_WHITE); tft.setFont(DroidSans_12_Bold); tft.setCursor(194, 31); tft.print("TSL2591"); tft.setCursor(194, 87); tft.print("DHT22"); 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.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); 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(ILI9341_WHITE, ILI9341_BLACK); tft.print("Kein Zeitzeichen erfolgreich empfangen"); tft.setCursor(60, 20); tft.print("seit: "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); int seconds = noDCFsignal % 60; int minutes = (noDCFsignal /60) % 60; int hours = (noDCFsignal / 3600) % 24; int days = (noDCFsignal / 86400) % 1; tft.print(days); tft.print(":"); tft.print(hours); tft.print(":"); tft.print(minutes); tft.print(":"); tft.print(seconds); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print(" (d:h:m:s) "); } else { tft.setCursor(60, 10); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.println("Letztes Zeitsignal erfolgreich empfangen"); tft.setCursor(60, 20); tft.print("vor: "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); int seconds = timesinceDCFsignal % 60; int minutes = (timesinceDCFsignal /60) % 60; int hours = (timesinceDCFsignal / 3600) % 24; int days = (timesinceDCFsignal / 86400) % 1; tft.print(days); tft.print(":"); tft.print(hours); tft.print(":"); tft.print(minutes); tft.print(":"); tft.print(seconds); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print(" (d:h:m:s) "); } tft.setCursor(60, 40); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print("Anzahl erfolgreich empfangener Zeitzeichen"); tft.setCursor(60, 50); tft.print("seit dem letzten Systemstart: "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); tft.print(receivedDCFsignals); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print("."); tft.setCursor(60, 70); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print("Anteil erfolgreich empfangener Zeitzeichen"); tft.setCursor(60, 80); tft.print("seit dem letzten Systemstart: "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); tft.print(DCFsuccessRate); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print(" %"); tft.setCursor(60, 100); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print("(System ist seit "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); tft.print(millis()/60000); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print(" Minuten in Betrieb.)"); tft.fillRect(60,120, 250, 50, ILI9341_BLACK); tft.setCursor(60, 130); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print("Periode: "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); tft.print(flankUp-PreviousflankUp); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print(" Pulsweite :"); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); tft.print(flankDown - flankUp); previousMillisTFTScreen = currentMillis; } // Unteruntermenü "LSM303" if (menuPage == 42 && TFTrefresh == true) { //tft.fillScreen(ILI9341_BLACK); // Zurück zum Untermenü Informationen tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); TFTrefresh = false; } if (menuPage == 42 && ((unsigned long)(currentMillis - previousMillisTFTScreen) >= intervalTFTScreen)) { intervalTFTScreen = 50; // Datenausgabe tft.setFontAdafruit(); tft.setTextSize(1); tft.setCursor(60, 10); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print("Beschleunigungswerte: "); tft.setCursor(60, 20); tft.print("X: "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); tft.print(accelX); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print(" Y: "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); tft.print(accelY); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print(" Z: "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); tft.print(accelZ); tft.setCursor(60, 40); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print("Orientierung: "); tft.setCursor(60, 50); tft.print("Roll: "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); tft.print(roll); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print(" Pitch: "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); tft.print(pitch); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.print(" Heading: "); tft.setTextColor(ILI9341_RED, ILI9341_BLACK); tft.print(heading); previousMillisTFTScreen = currentMillis; } // Unteruntermenü "TSL2591" if (menuPage == 45 && TFTrefresh == true) { //tft.fillScreen(ILI9341_BLACK); // Zurück zum Untermenü Informationen tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); TFTrefresh = false; } if (menuPage == 45 && ((unsigned long)(currentMillis - previousMillisTFTScreen) >= intervalTFTScreen)) { intervalTFTScreen = 500; // Datenausgabe tft.setTextColor(ILI9341_WHITE); tft.setFont(DroidSans_9); tft.setCursor(60, 10); tft.setTextColor(ILI9341_WHITE); tft.print("Infrarot: "); tft.setTextColor(ILI9341_RED); tft.print(ir); tft.print(" "); tft.setCursor(60, 30); tft.setTextColor(ILI9341_WHITE); tft.print("Full: "); tft.setTextColor(ILI9341_RED); tft.print(full); tft.print(" "); tft.setCursor(60, 50); tft.setTextColor(ILI9341_WHITE); tft.print("Visible: "); tft.setTextColor(ILI9341_RED); tft.print(full - ir); tft.print(" "); tft.setCursor(60, 70); tft.setTextColor(ILI9341_WHITE); tft.print("Lux: "); tft.setTextColor(ILI9341_RED); tft.print(lux); tft.print(" "); tft.setCursor(60, 90); tft.setTextColor(ILI9341_WHITE); tft.print("Lux, geglaettet: "); tft.setTextColor(ILI9341_RED); tft.print(filteredLux); tft.print(" "); previousMillisTFTScreen = currentMillis; } // Unteruntermenü "DHT22" if (menuPage == 46 && TFTrefresh == true) { //tft.fillScreen(ILI9341_BLACK); // Zurück zum Untermenü Informationen tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Datenausgabe tft.setTextColor(ILI9341_WHITE); tft.setFont(DroidSans_9); tft.setCursor(60, 10); tft.print("Temperatur: "); tft.setTextColor(ILI9341_RED); tft.print(c); tft.print(" "); tft.print(char(247)); tft.print("C; "); tft.print(f); tft.print(" "); tft.print(char(247)); tft.print("F "); tft.setCursor(60, 30); tft.setTextColor(ILI9341_WHITE); tft.print("Relative Luftfeuchtigkeit: "); tft.setTextColor(ILI9341_RED); tft.print(h); tft.print(" % "); tft.setCursor(60, 50); tft.setTextColor(ILI9341_WHITE); tft.print("Taupunkt: "); tft.setTextColor(ILI9341_RED); tft.print(taupunkt); tft.print(" "); tft.print(char(247)); tft.print("C "); TFTrefresh = false; } // Unteruntermenü "Systeminformationen" if (menuPage == 48 && TFTrefresh == true) { //tft.fillScreen(ILI9341_BLACK); // Zurück zum Untermenü Informationen tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Obere Reihe des Menüs tft.setTextSize(1); tft.setTextColor(ILI9341_BLACK, ILI9341_WHITE); tft.setCursor(35, 12); tft.print("Hauptmenü"); tft.setCursor(145, 12); tft.print("Informationen"); tft.setTextColor(ILI9341_WHITE, ILI9341_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.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Wecker stellen tft.setFont(DroidSans_13); tft.setTextColor(ILI9341_WHITE); tft.setCursor(75, 15); tft.print("Angestrebte Weckzeit"); // Stunden auf tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(100, 50); tft.print((char)6); // Stunde anzeigen tft.fillRect(90, 95, 50, 50, ILI9341_BLACK); tft.setFont(DroidSans_24); tft.setCursor(95, 108); if(displayedAlarmHour < 10) { tft.print('0'); } tft.print(displayedAlarmHour); // Stunde ab tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(100, 150); tft.print((char)7); // Doppelpunkt tft.setCursor(159, 108); tft.setFont(DroidSans_24); tft.print(":"); // Minuten auf tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(195, 50); tft.print((char)6); // Minuten anzeigen tft.fillRect(185, 95, 50, 50, ILI9341_BLACK); tft.setFont(DroidSans_24); tft.setCursor(192, 108); if(displayedAlarmMinute < 10) { tft.print('0'); } tft.print(displayedAlarmMinute); // Minuten ab tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(195, 150); tft.print((char)7); // Alarmmodus anzeigen tft.setFont(DroidSans_13); tft.setTextColor(ILI9341_WHITE); if (alarmMode == 0) { tft.setCursor(125, 215); tft.print("Alarm aus"); } else if (alarmMode == 1) { tft.setCursor(95, 215); tft.print("visueller Modus"); } else if (alarmMode == 2) { tft.setCursor(95, 215); tft.print("auditiver Modus"); } else if (alarmMode == 3) { tft.setCursor(75, 215); tft.print("audiovisueller Modus"); } // Weiter zur Auswahl des Programmmodus tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(290, 100); tft.print((char)1); TFTrefresh = false; } // Unteruntermenü "Alarmmodus einstellen" if (menuPage == 51 && TFTrefresh == true) { // Zurück zum "Alarmzeit einstellen" tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Optionen if (alarmMode == 0) { tft.fillRect(60, 17, 30, 29, ILI9341_BLACK); tft.setFont(AwesomeF000_24); tft.setCursor(60, 15); tft.print((char)88); } else { tft.fillRect(60, 17, 30, 29, ILI9341_BLACK); tft.setFont(AwesomeF000_24); tft.setCursor(60, 15); tft.print((char)87); } tft.setFont(DroidSans_13); tft.setCursor(100, 25); tft.print("Alarm aus"); if (alarmMode == 1) { tft.fillRect(60, 73, 30, 29, ILI9341_BLACK); tft.setFont(AwesomeF000_24); tft.setCursor(60, 71); tft.print((char)88); } else { tft.fillRect(60, 73, 30, 29, ILI9341_BLACK); tft.setFont(AwesomeF000_24); tft.setCursor(60, 71); tft.print((char)87); } tft.setFont(DroidSans_13); tft.setCursor(100, 81); tft.print("visueller Modus"); if (alarmMode == 2) { tft.fillRect(60, 135, 30, 29, ILI9341_BLACK); tft.setFont(AwesomeF000_24); tft.setCursor(60, 133); tft.print((char)88); } else { tft.fillRect(60, 135, 30, 29, ILI9341_BLACK); tft.setFont(AwesomeF000_24); tft.setCursor(60, 133); tft.print((char)87); } tft.setFont(DroidSans_13); tft.setCursor(100, 143); tft.print("auditiver Modus"); if (alarmMode == 3) { tft.fillRect(60, 196, 30, 29, ILI9341_BLACK); tft.setFont(AwesomeF000_24); tft.setCursor(60, 194); tft.print((char)88); } else { tft.fillRect(60, 196, 30, 29, ILI9341_BLACK); tft.setFont(AwesomeF000_24); tft.setCursor(60, 194); tft.print((char)87); } tft.setFont(DroidSans_13); tft.setCursor(100, 204); tft.print("audiovisueller Modus"); // Weiter zur Auswahl der Wecklautstärke tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(290, 100); tft.print((char)1); TFTrefresh = false; } // Untermenü "Wecklautstärke einstellen" if (menuPage == 52 && TFTrefresh == true) { // Zurück zu "Alarmmodus einstelle" tft.setFont(AwesomeF100_32); tft.setTextColor(ILI9341_WHITE); tft.setCursor(6, 100); tft.print((char)0); // Lautstärke tft.fillRect(213, 20, 2, 200, ILI9341_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; } // Untermenü "Wecker aus/Schlummern" if (menuPage == 7 && TFTrefresh == true) { tft.fillScreen(ILI9341_BLACK); // Dieses Menü wird automatisch aufgerufen. Daher muss der Bildschirm an dieser Stelle gelöscht werden. // Wecker/Schlummern aus tft.setTextColor(ILI9341_WHITE); tft.setFont(DroidSans_18_Bold); if (snoozeOn == false) { tft.setCursor(60, 95); tft.print("Wecker"); } else if (snoozeOn == true) { tft.setCursor(30, 95); tft.print("Schlummern"); } tft.setCursor(85, 135); tft.print("aus"); tft.fillRect(213, 20, 2, 200, ILI9341_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); // Dieses Menü wird automatisch aufgerufen. Daher muss der Bildschirm an dieser Stelle gelöscht werden. // Snoozle aus tft.setTextColor(ILI9341_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, ILI9341_WHITE); tft.setFont(AwesomeF000_28); tft.setCursor(250, 40); tft.print((char)40); tft.setFont(DroidSans_10); tft.setCursor(225, 120); tft.print("Volume: "); tft.print(snoozleGain / 2); tft.print("%"); 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(timesinceDCFsignal); 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(timesinceDCFsignal); 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(timesinceDCFsignal /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 170.088 Bytes (16%) des Programmspeicherplatzes. Das Maximum sind 1.048.576 Bytes. Globale Variablen verwenden 13.180 Bytes (5%) des dynamischen Speichers, 248.964 Bytes für lokale Variablen verbleiben. Das Maximum sind 262.144 Bytes. {{tag>Arduino Schlafphasenwecker Teensy}}