====== Schlafphasenwecker Programmversion 0.2 ====== Dies ist eine alte Programmversion.Diese Programmversion behebt kleinere Fehler der [[arduino:schlafphasenwecker:programmversion_0.1|Programmversion 0.1]] und bindet den kapazitiven Touchscreen und den TSL2591 ein. Der Sketch enthält ein experimentelles Menü, das sich über den Touchsensor bedienen lässt. Wie bei dem Programmmodustaster der[[arduino:silentbase_neopixel|NeoPixel-Beleuchtung für meinen PC]] wird die ausgewählte Aktion erst beim Loslassen des Touchscreens ausgeführt, um Fehlbedienungen zu vermeiden. Hilfreiche Links: * https://learn.adafruit.com/adafruit-gfx-graphics-library * http://howtomechatronics.com/tutorials/arduino/arduino-tft-lcd-touch-screen-tutorial/ * http://henrysbench.capnfatz.com/henrys-bench/arduino-adafruit-gfx-library-user-guide/ * http://www.rinkydinkelectronics.com/calc_rgb565.php // Schlafphasenwecker Version 0.2 // Bibliotheken einbinden #include // Stellt verschiedene Zeitfunktionen zur Verfügung #include "DCF77.h" // Bibliothek für das DCF77-Modul #include // Core graphics library #include // this is needed for display #include // TFT-Display #include // this is needed for FT6206 #include // Kapazitiver Touchsensor #include // Adafruit Unified Sensor Driver #include "Adafruit_TSL2591.h" // Bibliothek für den TSL2591 // Definiert die Pins #define DCF_PIN 2 // Connection pin to DCF 77 device #define DCF_INTERRUPT 2 // Interrupt number associated with pin // Definiert die DCF77-Bibliothek DCF77 DCF = DCF77(DCF_PIN, DCF_INTERRUPT, false); // The FT6206 uses hardware I2C (SCL/SDA) Adafruit_FT6206 ctp = Adafruit_FT6206(); // The display also uses hardware SPI, plus #9 & #10 #define TFT_CS 10 #define TFT_DC 9 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); // pass in a number for the sensor identifier (for your use later) Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // Definiert die Variablen bool DCFTimeFound = false; // wurde ein gueltiges Signal gefunden time_t DCFtime = 0; time_t t = 0; const unsigned long DefaultTime = 1477958400; // Nov 1 2016 unsigned long lastDCFsignal; unsigned long noDCFsignal; unsigned long currentDCFsignal; uint16_t ir; uint16_t full; uint32_t lum; int menuePage = 0; // Nummer des Menüs. Das Menü mit der Nummer 0 soll zuerst aufgerufen werden. int touchtouched = 0; // Touchscreen gedrückt? int tx; int ty; int debouncetime = 50; // Zeit für Entprellung unsigned long touchtime = 0; // Definiert die Tracking-Variablen für die IF-Abfragen unsigned long previousMillisSetRTC = 0; unsigned long previousMillisTFTScreen = 0; unsigned long previousMillisTouchScreen = 0; unsigned long previousMillisSensorData = 0; unsigned long previousMillisSerialPrint = 0; // Definiert die Intervalle für die IF-Abfragen int intervalSetRTC = 1000; // Delay für Holen der Zeit int intervalTFTScreen = 50; // Delay für Anteuerung des TFT-Screens int intervalTouchScreen = 50; // Delay für Anteuerung des kapazitiven Touchsreens int intervalSensorData = 1000; // Delay für Auslesen der Sensoren int intervalSerialPrint = 1000; // Delay für serielle Ausgabe void setup() { // Initalisiert die Pins //pinMode(PIN_LED, OUTPUT); // On-board LED pinMode(DCF_PIN, INPUT_PULLUP); // DFC77-Modul // set the Time library to use Teensy 3.0's RTC to keep time setSyncProvider(getTeensy3Time); // Initialisiert den TFT-Bildschirm tft.begin(); tft.setRotation(1); tft.fillScreen(ILI9341_BLACK); // Initialisiert die serielle Schnittstelle Serial.begin(115200); delay(100); // Kurze Pause, weil sonst der serielle Monitor noch nicht bereit ist. Der soll aber auch keine Voraussetzung sein. if (timeStatus()!= timeSet) { Serial.println("Unable to sync with the RTC"); } else { Serial.println("RTC has set the system time"); } if (! ctp.begin(40)) { // Stellt u.a. die Sensitivität des Touchscreens ein Serial.println("Couldn't start FT6206 touchscreen controller"); //while (1); } else { Serial.println("Capacitive touchscreen started"); } // 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) // 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 den TSL2591 tsl.begin(); //Lichtsensor } void loop() { // Aktuelle Zeit abfragen unsigned long currentMillis = millis(); // Stelle die Real Time Clock (RTC) auf die aktuelle Zeit if ((unsigned long)(currentMillis - previousMillisSetRTC) >= intervalSetRTC) { DCFtime = DCF.getTime(); // Check if new DCF77 time is available // Wenn die serielle Schnittstelle verfügbar ist, setze die RTC auf diese Zeit if (Serial.available() && DCFtime < DefaultTime) { t = processSyncMessage(); if (t != 0) { Teensy3Clock.set(t); // set the RTC setTime(t); } } // Wenn ein Zeitsignal vom DCF77-Modul verfügbar ist, setze die RTC auf diese Zeit if (DCFtime > DefaultTime) { t = DCFtime; Serial.println("RTC has been updated to DCF77 time"); Teensy3Clock.set(t); // set the RTC setTime(t); DCFTimeFound = true; currentDCFsignal = millis(); } // Berechne die Zeit (in Sekunden) die seit dem Empfang des letzten gültigen DCF-Signals vergangen ist if (DCFTimeFound == false) { noDCFsignal = millis() /1000; } else { lastDCFsignal = (millis() - currentDCFsignal) / 1000; } //Speichere die aktuelle Zeit in die zughörige Variable previousMillisSetRTC = currentMillis; } // Sensoren /TSL 2591 if ((unsigned long)(currentMillis - previousMillisSensorData) >= intervalSensorData) { //Auslesen des Helligkeitssensors lum = tsl.getFullLuminosity(); ir = lum >> 16; full = lum & 0xFFFF; //Speichere die aktuelle Zeit in die zughörige Variable previousMillisSensorData = currentMillis; } // TFT-Screen if ((unsigned long)(currentMillis - previousMillisTFTScreen) >= intervalTFTScreen) { // Hauptmenü (weiß) if (menuePage == 0) { //tft.fillScreen(ILI9341_BLACK); tft.fillRect(0, 0, 106, 30, ILI9341_RED); tft.fillRect(107, 0, 106, 30, ILI9341_YELLOW); tft.fillRect(214, 0, 106, 30, ILI9341_GREEN); } // Untermenü 1 (rot) if (menuePage == 1) { //tft.fillScreen(ILI9341_BLACK); tft.fillRect(0, 0, 106, 30, ILI9341_WHITE); tft.fillRect(107, 0, 106, 30, ILI9341_YELLOW); tft.fillRect(214, 0, 106, 30, ILI9341_GREEN); } // Untermenü 2 (gelb) if (menuePage == 2) { //tft.fillScreen(ILI9341_BLACK); tft.fillRect(0, 0, 106, 30, ILI9341_WHITE); tft.fillRect(107, 0, 106, 30, ILI9341_RED); tft.fillRect(214, 0, 106, 30, ILI9341_GREEN); } // Untermenü 3 (grün) if (menuePage == 3) { //tft.fillScreen(ILI9341_BLACK); tft.fillRect(0, 0, 106, 30, ILI9341_WHITE); tft.fillRect(107, 0, 106, 30, ILI9341_RED); tft.fillRect(214, 0, 106, 30, ILI9341_YELLOW); } //Speichere die aktuelle Zeit in die zughörige Variable previousMillisTFTScreen = currentMillis; } // Touchscreen if ((unsigned long)(currentMillis - previousMillisTouchScreen) >= intervalTouchScreen) { // Wait for a touch if (ctp.touched()) { // Retrieve a point TS_Point p = ctp.getPoint(); touchtime = millis(); // aktualisiere Touchzeit touchtouched = 1; // 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; } if (menuePage == 0 && touchtouched == 1 && (millis() - touchtime > debouncetime)) { // Wenn Menüseite 0 ausgewählt und der Touchscreen berührt wird und die debouncetime verstrichen ist ... if ((tx >= 0) && (tx <= 106) && (ty >= 0) && (ty <= 30)) { // ... und der TouchScreen in dem angegebenen Bereich berührt wird ... tft.drawRect(0, 0, 106, 30, ILI9341_BLACK); menuePage = 1; // ... dann rufe Menüseite 1 auf. } else if ((tx >= 107) && (tx <= 213) && (ty >= 0) && (ty <= 30)) { tft.drawRect(107, 0, 106, 30, ILI9341_BLACK); menuePage = 2; } else if ((tx >= 214) && (tx <= 320) && (ty >= 0) && (ty <= 30)) { tft.drawRect(214, 0, 106, 30, ILI9341_BLACK); menuePage = 3; } touchtouched = 0; // Setze die Varibale auf 0, damit nicht die nächste if-Schleife aufgerufen wird } if (menuePage == 1 && touchtouched == 1 && (millis() - touchtime > debouncetime)) { if ((tx >= 0) && (tx <= 106) && (ty >= 0) && (ty <= 30)) { tft.drawRect(0, 0, 106, 30, ILI9341_BLACK); menuePage = 0; } else if ((tx >= 107) && (tx <= 213) && (ty >= 0) && (ty <= 30)) { tft.drawRect(107, 0, 106, 30, ILI9341_BLACK); menuePage = 2; } else if ((tx >= 214) && (tx <= 320) && (ty >= 0) && (ty <= 30)) { tft.drawRect(214, 0, 106, 30, ILI9341_BLACK); menuePage = 3; } touchtouched = 0; } if (menuePage == 2 && touchtouched == 1 && (millis() - touchtime > debouncetime)) { if ((tx >= 0) && (tx <= 106) && (ty >= 0) && (ty <= 30)) { tft.drawRect(0, 0, 106, 30, ILI9341_BLACK); menuePage = 0; } else if ((tx >= 107) && (tx <= 213) && (ty >= 0) && (ty <= 30)) { tft.drawRect(107, 0, 106, 30, ILI9341_BLACK); menuePage = 1; } else if ((tx >= 214) && (tx <= 320) && (ty >= 0) && (ty <= 30)) { tft.drawRect(214, 0, 106, 30, ILI9341_BLACK); menuePage = 3; } touchtouched = 0; } if (menuePage == 3 && touchtouched == 1 && (millis() - touchtime > debouncetime)) { if ((tx >= 0) && (tx <= 106) && (ty >= 0) && (ty <= 30)) { tft.drawRect(0, 0, 106, 30, ILI9341_BLACK); menuePage = 0; } else if ((tx >= 107) && (tx <= 213) && (ty >= 0) && (ty <= 30)) { tft.drawRect(107, 0, 106, 30, ILI9341_BLACK); menuePage = 1; } else if ((tx >= 214) && (tx <= 320) && (ty >= 0) && (ty <= 30)) { tft.drawRect(214, 0, 106, 30, ILI9341_BLACK); menuePage = 2; } touchtouched = 0; } //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()); printDCFsyncTime(); Serial.print(menuePage); Serial.println(); //Speichere die aktuelle Zeit in die zughörige Variable previousMillisSerialPrint = 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() { unsigned long pctime = 0L; if(Serial.find(TIME_HEADER)) { pctime = Serial.parseInt(); return pctime; if( pctime < DefaultTime) { // check the value is a valid time (greater than Nov 1 2016) pctime = 0L; // return 0 to indicate that the time is not valid } } return pctime; } void tftprintDigits(int digits) { // utility function for digital clock display: prints preceding colon and leading 0 tft.print(":"); if(digits < 10) tft.print('0'); tft.print(digits); } void printDigits(int digits) { // utility function for digital clock display: prints preceding colon and leading 0 Serial.print(":"); if(digits < 10) Serial.print('0'); Serial.print(digits); } void tftprintDCFsyncTime() { if (DCFTimeFound == 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 (DCFTimeFound == 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"); } } Der Sketch verwendet 42.108 Bytes (4%) des Programmspeicherplatzes. Das Maximum sind 1.048.576 Bytes. Globale Variablen verwenden 6.216 Bytes (2%) des dynamischen Speichers, 255.928 Bytes für lokale Variablen verbleiben. Das Maximum sind 262.144 Bytes. {{tag>Arduino Schlafphasenwecker Teensy}}