====== 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}}