#include <RTClib.h>
#include <U8g2lib.h>
#include <Bounce2.h>
#include <DHT.h>
#include <SPI.h>
#include <Adafruit_ILI9341.h>
#include <Adafruit_GFX.h>
/*
Red Button (4) not used in this case!
TFT Display:
Arduino MEga:
SCK = D13
MISO = D12
MOSI = D11
https://i.stack.imgur.com/RxKaD.png
*/
/*
https://wokwi.com/projects/344892587898831442 DHT Sensor
https://iotdk.intel.com/docs/master/upm/classupm_1_1_i_l_i9341.html
https://www.youtube.com/watch?v=beyDkTBhpgs
Change Alarmtime reload time is slow af + does not work!(starting wrong sector)
evt use multiple arrays to make multiple alarms at the same time
*/
byte button_pins[] = { 23, 22, 24, 25 }; // button pins, 23,22 = up/down, 24 = select, 25 = Home
#define NUMBUTTONS sizeof(button_pins)
Bounce *buttons = new Bounce[NUMBUTTONS]; // Button Bounce
#define DHTPIN 2 // Pin Connected to the DHT sensor
#define DHTTYPE DHT22
#define TFT_DC 49 // TFT Display
#define TFT_CS 53
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); // Initialize TFT Display
RTC_DS1307 rtc; // Initialize RTC Module
DHT dht(DHTPIN, DHTTYPE); // Initialize DHT Sensor (DHT22 beeing the type of Sensor)
#define MENU_SIZE_1 5 // Menu 1
char *menu1[MENU_SIZE_1] = { "Home", "Change Time", "Option 3", "Option 4", "Option 5" };
#define MENU_SIZE_HOME 2 // Home
char *home[MENU_SIZE_HOME] = { "Menu 1", "Option 2" };
// Days and Months
char *monthsoftheyear[] = { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" }; // Array of Months in the year
char *daysOfTheWeek[] = { "Sonntag", "Montag", "Dienstag", "Mittowch", "Donnerstag", "Freitag", "Samstag" }; // Array of days in the week
char *diffrentTimesofDay[] = { "Guten Morgen", "Guten Mittag", "Guten Nachmittag", "Guten Abend" }; // Array of Greetings // maby add , at the end
int currentPartOfTimeDurringDay;
String OPEN_MENU = "Home";
int changeAlarmTimeStep = 0;
int cursor = 0;
int Acursor = 0;
int TFTheigt2 = 15;
int targethour = 9;
int targetminute = 48;
int targetsecond = 15;
bool AlarmON = true;
const int LOCKSCREEN_DELAY = 5; // Delay until the lockscreen comes back in in Minutes after last Button press
// Variables
int hour;
int minute;
int second;
int year;
int month;
int day;
int dayofweek;
int lastsecond;
int lastminute;
int lasthour;
int lastday;
int lastsecondtwo = -1;
long CurrentTimecodecooldown = 0;
long CurrentTimecode = 0;
long AlarmTimecode = 0;
float humidity;
float temperature;
void setup() {
Serial.begin(9600); // Start Serial Monitor
for (int i = 0; i < NUMBUTTONS; i++) {
buttons[i].attach(button_pins[i], INPUT_PULLUP); // setup the bounce instance for the current button
buttons[i].interval(25); // interval in ms
}
if (!rtc.begin()) { // Start Conection to RTC
Serial.println("Couldn't connect to RTC");
Serial.flush();
abort(); // Stop the Program
}
dht.begin();
tft.begin();
tft.setTextSize(2);
showLockScreen();
}
void loop() {
DateTime now = rtc.now(); // Setting up RTC
year = now.year();
month = now.month();
day = now.day();
hour = now.hour();
minute = now.minute();
second = now.second();
dayofweek = now.dayOfTheWeek();
dht_sensor();
if (lastminute != minute) {
// Update time sector
if (CurrentTimecode > 0 && CurrentTimecode < 43199) { //0 - 12
currentPartOfTimeDurringDay = 0;
} else if (CurrentTimecode >= 43200 && CurrentTimecode < 48599) { // 12 - 13.5
currentPartOfTimeDurringDay = 1;
} else if (CurrentTimecode >= 48600 && CurrentTimecode <= 64799) { // 13.5 - 18
currentPartOfTimeDurringDay = 2;
} else { // if (CurrentTimecode > 1079)
currentPartOfTimeDurringDay = 3;
}
if (OPEN_MENU == "Lockscreen") {
tft.fillRect(55, 75, 22, 15, ILI9341_ORANGE);
if (minute < 10) {
tft.setCursor(55, 75);
tft.print('0');
tft.setCursor(67, 75);
tft.print(minute);
} else {
tft.setCursor(55, 75);
tft.print(minute);
}
}
lastminute = minute;
}
if (lastsecond != second) {
CurrentTimecode = hour * 3600 + minute * 60 + second;
if (OPEN_MENU == "Lockscreen") {
tft.fillRect(85, 75, 22, 15, ILI9341_ORANGE);
if (second < 10) {
tft.setCursor(85, 75);
tft.print('0');
tft.setCursor(97, 75);
tft.print(second);
} else {
tft.setCursor(85, 75);
tft.print(second);
}
tft.setCursor(25, 100);
tft.print("Hum:");
tft.setCursor(25, 125);
tft.print("Temp:");
tft.fillRect(125, 100, 58, 15, ILI9341_ORANGE);
tft.setCursor(125, 100);
tft.print(humidity);
tft.print('%');
tft.fillRect(125, 125, 58, 15, ILI9341_ORANGE);
tft.setCursor(125, 125);
tft.print(temperature);
tft.print('C');
if (AlarmON) {
AlarmTimecode = targethour * 3600 + targetminute * 60 + targetsecond; // Time we are converting. This can be passed from another function.
long alarmtimecodedif = AlarmTimecode - CurrentTimecode;
int trgthr = alarmtimecodedif / 3600; // Number of seconds in an hour
int trgtmin = (alarmtimecodedif - trgthr * 3600) / 60; // Remove the number of hours and calculate the minutes.
int trgtsec = alarmtimecodedif - trgthr * 3600 - trgtmin * 60; // Remove the number of hours and minutes, leaving only seconds.
Serial.print("AlarmTimecode :");
Serial.println(AlarmTimecode);
Serial.print("Current time :");
Serial.println(CurrentTimecode);
Serial.print("alarm time dif :");
Serial.println(alarmtimecodedif);
Serial.println(trgthr);
Serial.println(trgtmin);
Serial.println(trgtsec);
}
}
lastsecond = second;
}
if (lastday != day) {
if (OPEN_MENU == "Lockscreen") {
tft.setCursor(25, 175);
tft.print(daysOfTheWeek[dayofweek]); // print Day
tft.setCursor(25, 200);
tft.print(monthsoftheyear[month - 1]); // print month
// print date like hours
if (day < 10) {
tft.setCursor(25, 225);
tft.print('0');
tft.setCursor(35, 225);
tft.print(day);
} else {
tft.setCursor(25, 225);
tft.print(day);
}
if (month < 10) {
tft.setCursor(55, 225);
tft.print('0');
tft.setCursor(65, 225);
tft.print(month);
} else {
tft.setCursor(55, 225);
tft.print(month);
}
tft.setCursor(85, 225);
tft.print(year);
tft.setCursor(45, 225);
tft.print(':');
tft.setCursor(75, 225);
tft.print(':');
}
lastday = day;
}
if (lasthour != hour) {
if (OPEN_MENU == "Lockscreen") {
tft.fillRect(25, 75, 22, 15, ILI9341_ORANGE);
if (hour < 10) {
tft.setCursor(25, 75);
tft.print('0');
tft.setCursor(37, 75);
tft.print(hour);
} else {
tft.setCursor(25, 75);
tft.print(hour);
}
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_BLUE);
tft.setTextSize(3);
tft.print(diffrentTimesofDay[currentPartOfTimeDurringDay]);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(25, 175);
tft.print(daysOfTheWeek[dayofweek]);
tft.setCursor(25, 200);
tft.print(monthsoftheyear[month - 1]);
tft.setCursor(45, 75);
tft.print(':');
tft.setCursor(75, 75);
tft.print(':');
}
lasthour = hour;
}
if (targethour == hour && targetminute == minute && targetsecond == second) { // check Alarm times
if (AlarmON) {
Alarm();
}
}
for (int i = 0; i < NUMBUTTONS; i++) {
buttons[i].update(); // Update the Bounce instance
if (buttons[i].fell()) { // If it fell
if (OPEN_MENU == "Lockscreen") {
showHome(); // show Home if last window was Lockscreen
CurrentTimecodecooldown = CurrentTimecode + LOCKSCREEN_DELAY; // Update Delay
} else { // Do not execute the buttons when the menu is not showen
CurrentTimecodecooldown = CurrentTimecode + LOCKSCREEN_DELAY; // Update Delay
if (i == 3) {
if (OPEN_MENU == "Lockscreen") {
showHome(); // show Home if it is not already open
} else {
showLockScreen();
}
} else if (i == 2) {
// goto select
button_select();
} else {
if (OPEN_MENU != "ChangeAlarmTime") {
// erase previous cursor:
Acursor = (cursor + 2) * 25;
tft.fillRect(5, Acursor, 10, 15, ILI9341_ORANGE); // Replace Cursor
}
if (i == 0) { // up
button_up();
} else { // down
button_down();
}
if (OPEN_MENU != "ChangeAlarmTime") {
// show cursor at new line:
Acursor = (cursor + 2) * 25;
tft.setCursor(5, Acursor);
tft.setTextColor(ILI9341_GREEN);
tft.print('>');
tft.setTextColor(ILI9341_WHITE);
}
}
}
} else if (CurrentTimecodecooldown <= CurrentTimecode && OPEN_MENU != "Lockscreen") {
showLockScreen(); // Show Lockscreen
}
}
}
void button_select() {
if (OPEN_MENU == "Home") {
//execute choise
if (cursor == 0) {
showMenu1();
}
//print selection
} else if (OPEN_MENU == "Menu_1") {
// execute choice
if (cursor == 0) {
showHome();
} else if (cursor == 1) {
ChangeAlarmTime();
}
} else if (OPEN_MENU == "ChangeAlarmTime") {
changeAlarmTimeStep++;
if (changeAlarmTimeStep == 3) {
changeAlarmTimeStep = 0;
showMenu1();
cursor = 0;
} else {
changeAlarmTimetime();
}
}
}
void button_up() {
if (OPEN_MENU == "Home") {
cursor++;
if (cursor > (MENU_SIZE_HOME - 1)) cursor = 0;
} else if (OPEN_MENU == "Menu_1") {
cursor++;
if (cursor > (MENU_SIZE_1 - 1)) cursor = 0;
} else if (OPEN_MENU == "ChangeAlarmTime") {
if (changeAlarmTimeStep == 0) {
targethour++;
if (targethour == 25) {
targethour = 0;
}
} else if (changeAlarmTimeStep == 1) {
targetminute++;
if (targetminute == 60) {
targetminute = 0;
}
} else if (changeAlarmTimeStep == 2) {
targetsecond++;
if (targetsecond == 60) {
targetsecond = 0;
}
}
changeAlarmTimetime();
}
}
void button_down() {
if (OPEN_MENU == "Home") {
cursor--;
if (cursor < 0) cursor = (MENU_SIZE_HOME - 1);
} else if (OPEN_MENU == "Menu_1") {
cursor--;
if (cursor < 0) cursor = (MENU_SIZE_1 - 1);
} else if (OPEN_MENU == "ChangeAlarmTime") {
if (changeAlarmTimeStep == 0) {
targethour--;
if (targethour == 0) {
targethour = 24;
}
} else if (changeAlarmTimeStep == 1) {
targetminute--;
if (targetminute == 0) {
targetminute = 60;
}
} else if (changeAlarmTimeStep == 2) {
targetsecond--;
if (targetsecond == 0) {
targetsecond = 60;
}
}
changeAlarmTimetime();
}
}
void dht_sensor() {
if (lastsecondtwo = second - 2) {
temperature = dht.readTemperature();
humidity = dht.readHumidity();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
lastsecondtwo = second;
}
}
// Menus
void showMenu1() {
cursor = 0;
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_BLUE);
tft.setTextSize(3);
tft.print("Menu 1");
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
Serial.println("Opening Menu1");
OPEN_MENU = "Menu_1";
// show menu items:
for (int i = 0; i < MENU_SIZE_1; i++) {
tft.setCursor(25, (i + 2) * 25);
tft.print(menu1[i]);
}
tft.setCursor(5, 50);
tft.setTextColor(ILI9341_GREEN);
tft.print('>');
tft.setTextColor(ILI9341_WHITE);
}
void showHome() {
cursor = 0;
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_BLUE);
tft.setTextSize(3);
tft.print("Home");
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
Serial.println("Opening Home");
OPEN_MENU = "Home";
// show menu items:
for (int i = 0; i < MENU_SIZE_HOME; i++) {
tft.setCursor(25, (i + 2) * 25);
tft.print(home[i]);
}
tft.setCursor(5, 50);
tft.setTextColor(ILI9341_GREEN);
tft.print('>');
tft.setTextColor(ILI9341_WHITE);
}
void showLockScreen() {
lasthour = -1;
lastminute = -1;
lastsecond = -1;
lastday = -1;
tft.fillScreen(ILI9341_BLACK);
Serial.println("Opening Lockscreen");
OPEN_MENU = "Lockscreen";
cursor = 0;
tft.setCursor(25, 300);
tft.setTextColor(ILI9341_WHITE);
if (AlarmON) {
tft.print("Alarm ON");
} else {
tft.print("Alarm OFF");
}
}
void Alarm() {
Serial.print("Alarm");
tft.fillScreen(ILI9341_BLACK);
OPEN_MENU = "Alarm";
}
void ChangeAlarmTime() {
Serial.println("Change Alarm Time");
OPEN_MENU = "ChangeAlarmTime";
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_BLUE);
tft.setTextSize(3);
tft.print("Change Alarm Time");
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(60, 100);
tft.println("hh:mm:ss");
tft.setCursor(80, 125);
tft.print(':');
tft.setCursor(110, 125);
tft.print(':');
changeAlarmTimetime();
}
void changeAlarmTimetime() {
if (changeAlarmTimeStep == 0) {
tft.fillRect(60, 125, 22, 15, ILI9341_ORANGE);
tft.setTextColor(ILI9341_YELLOW);
} else {
tft.setTextColor(ILI9341_WHITE);
}
if (targethour < 10) {
tft.setCursor(60, 125);
tft.print('0');
tft.setCursor(70, 125);
tft.print(targethour);
} else {
tft.setCursor(60, 125);
tft.print(targethour);
}
if (changeAlarmTimeStep == 1) {
tft.fillRect(90, 125, 22, 15, ILI9341_ORANGE);
tft.setTextColor(ILI9341_YELLOW);
} else {
tft.setTextColor(ILI9341_WHITE);
}
if (targetminute < 10) {
tft.setCursor(90, 125);
tft.print('0');
tft.setCursor(100, 125);
tft.print(targetminute);
} else {
tft.setCursor(90, 125);
tft.print(targetminute);
}
if (changeAlarmTimeStep == 2) {
tft.fillRect(120, 125, 22, 15, ILI9341_ORANGE);
tft.setTextColor(ILI9341_YELLOW);
} else {
tft.setTextColor(ILI9341_WHITE);
}
if (targetsecond < 10) {
tft.setCursor(120, 125);
tft.print('0');
tft.setCursor(130, 125);
tft.print(targetsecond);
} else {
tft.setCursor(120, 125);
tft.print(targetsecond);
}
}