Benutzer-Werkzeuge

Webseiten-Werkzeuge


arduino:schlafphasenwecker:programmversion_0.2

Schlafphasenwecker Programmversion 0.2

Achtung

Dies ist eine alte Programmversion.

Diese Programmversion behebt kleinere Fehler der 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 derNeoPixel-Beleuchtung für meinen PC wird die ausgewählte Aktion erst beim Loslassen des Touchscreens ausgeführt, um Fehlbedienungen zu vermeiden.

Hilfreiche Links:

// Schlafphasenwecker Version 0.2

// Bibliotheken einbinden
#include <TimeLib.h>               // Stellt verschiedene Zeitfunktionen zur Verfügung
#include "DCF77.h"                 // Bibliothek für das DCF77-Modul
#include <Adafruit_GFX.h>          // Core graphics library
#include <SPI.h>                   // this is needed for display
#include <Adafruit_ILI9341.h>      // TFT-Display
#include <Wire.h>                  // this is needed for FT6206
#include <Adafruit_FT6206.h>       // Kapazitiver Touchsensor
#include <Adafruit_Sensor.h>       // Adafruit Unified Sensor Driver
#include "Adafruit_TSL2591.h"      // Bibliothek für den 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.

arduino/schlafphasenwecker/programmversion_0.2.txt · Zuletzt geändert: 18.05.2023 12:34 von 127.0.0.1