// Code mit Einstellmöglichkeiten
// Wi-Fi Settings
#include "WiFi.h"
// ___________________________________________
// Wifi Zugangsdaten
const char *wifi_ssid = "Wokwi-GUESTaaa";
const char *wifi_password = "";
// ___________________________________________
const char* NTP_SERVER = "pool.ntp.org";
const char* TZ_INFO = "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00";
// LED-Basis-Werte
int R = 230;
int G = 80;
int B = 0;
int nachtlichdauer = 10;
// Display
#include "U8g2lib.h"
// Displaytyp
// ___________________________________________
// Wokwi: normales 1306 Display (einzig verfügbares in Wokwi)
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);
// ___________________________________________
// ODER
// ___________________________________________
// Real-Aufbau: relativ großes LCD-Display bei dem man das Backlight entfernen kann
//U8G2_ST7565_ERC12864_ALT_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18, /* data=*/ 19, /* cs=*/ 15, /* dc=*/ 17, /* reset=*/ 16);
// ___________________________________________
// __________________________________________________________________________________
// Fester Code
// Globale Variablen definieren
// Taster
#define Button_PinR_down 33
#define Button_PinR_up 32
#define Button_PinG_down 14
#define Button_PinG_up 25
#define Button_PinB_down 26
#define Button_PinB_up 27
#define Button_Pin_Nachtlicht 5
// LED
#include <Adafruit_NeoPixel.h>
//#include <avr/power.h>
#define PIN 12
#define NUMPIXELS 4
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int delayval = 200;
int nachtlichtimer = 10000000;
char temp[6];
int tempausgabe;
int N = 0;
// Uhr
#include <Wire.h>
#include <uRTCLib.h>
// Zeitserver Lib
#include <time.h>
time_t now;
tm tm;
// Uhr ID
uRTCLib rtc(0x68);
// Datumsformatierungen
char wochentage[7][12] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
String monat[12] = {"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"};
char tag[7][4] = {"So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"};
char monatuhr[12][4] = {"JAN", "FEB", "MAR", "APR", "MAI", "JUN", "JUL", "AUG", "SEP", "OKT", "NOV", "DEZ"};
void setup() {
// i2s Kanal öffnen
Serial.begin(112500); // Öffnet die serielle Schnittstelle bei 9600 Bit/s:
// Knöpfe
pinMode(Button_PinR_down, INPUT_PULLUP);
pinMode(Button_PinR_up, INPUT_PULLUP);
pinMode(Button_PinG_down, INPUT_PULLUP);
pinMode(Button_PinG_up, INPUT_PULLUP);
pinMode(Button_PinB_down, INPUT_PULLUP);
pinMode(Button_PinB_up, INPUT_PULLUP);
pinMode(Button_Pin_Nachtlicht, INPUT_PULLUP);
// Uhr
URTCLIB_WIRE.begin();
// LED
pixels.begin();
pixels.setPixelColor(0, pixels.Color(R,G,B));
pixels.setPixelColor(1, pixels.Color(R,G,B));
pixels.setPixelColor(2, pixels.Color(0,0,0));
pixels.setPixelColor(3, pixels.Color(0,0,0));
pixels.show(); // This sends the updated pixel color to the hardware.
// Display
u8g2.setColorIndex(1);
u8g2.begin();
u8g2.setContrast(60); // Für LCD Display wichtig
// Display Anzeige WIFI
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_spleen32x64_mf);
u8g2.drawStr(0, 55, "WIFI");
u8g2.sendBuffer();
// Wifi und NTP
setup_wifi();
}
void loop() {
// Uhrzeit aus Uhrenmodul holen
rtc.refresh();
// Display-Puffer leeren
u8g2.clearBuffer();
// LED-Buttons
u8g2.setFont(u8g2_font_spleen5x8_mr); // Zeichensatz für Änderungsanzeige
if(digitalRead(Button_PinR_down) == LOW){
if(R >= 20) R = R - 20;
sprintf(temp, "%s R:%02d","v", R);
u8g2.drawStr(75, 64, temp); // Ausgabe einer Änderung auf Display
}
if(digitalRead(Button_PinR_up) == LOW){
if(R <= 230) R = R + 20;
sprintf(temp, "%s R:%02d","^", R);
u8g2.drawStr(75, 64, temp); // Ausgabe einer Änderung auf Display
}
if(digitalRead(Button_PinG_down) == LOW){
if(G >= 20) G = G - 20;
sprintf(temp, "%s G:%02d","v", G);
u8g2.drawStr(75, 64, temp); // Ausgabe einer Änderung auf Display
}
if(digitalRead(Button_PinG_up) == LOW){
if(G <= 230) G = G + 20;
sprintf(temp, "%s G:%02d","^", G);
u8g2.drawStr(75, 64, temp); // Ausgabe einer Änderung auf Display
}
if(digitalRead(Button_PinB_down) == LOW){
if(B >= 20) B = B - 20;
sprintf(temp, "%s B:%02d","v",B);
u8g2.drawStr(75, 64, temp); // Ausgabe einer Änderung auf Display
}
if(digitalRead(Button_PinB_up) == LOW){
if(B <= 230) B = B + 20;
sprintf(temp, "%s B:%02d","^", B);
u8g2.drawStr(75, 64, temp); // Ausgabe einer Änderung auf Display
}
// LED - Set
pixels.setPixelColor(0, pixels.Color(R,G,B));
pixels.setPixelColor(1, pixels.Color(R,G,B));
// Nachtlicht mit Timer
if(digitalRead(Button_Pin_Nachtlicht) == LOW){
nachtlichtimer = 0;
pixels.setPixelColor(2, pixels.Color(250,250,250));
pixels.setPixelColor(3, pixels.Color(250,250,250));
//sprintf(temp, "%s B:%02d","^", B);
//u8g2.drawStr(75, 64, temp); // Ausgabe einer Änderung auf Display
}
else
{
// Nach einer bestimmten Dauer Nachtlicht erst wieder abschalten
if(nachtlichtimer < nachtlichdauer)
{
nachtlichtimer++;
}
else
{
pixels.setPixelColor(2, pixels.Color(0,0,0));
pixels.setPixelColor(3, pixels.Color(0,0,0));
}
}
pixels.show(); // This sends the updated pixel color to the hardware.
//delay(delayval); // Delay for a period of time (in milliseconds).
// Testausgabe auf Serial-Monitor
char bufferClock1[20],bufferClock2[20],bufferClock3[20],bufferClock4[20], Datum[30], bufferVoltage[10], bufferTemp[10];
sprintf(bufferClock1, "%02d", rtc.hour());
sprintf(bufferClock2, "%02d", rtc.minute());
// Korrektur des Wochentages auf echtem ESP nicht nötig (führt zu Fehler)
sprintf(Datum, "%s %02d%s%02d%s%02d",tag[rtc.dayOfWeek()], rtc.day(),".", rtc.month(),".", rtc.year()+1900);
// Display füllen
u8g2.setFont(u8g2_font_7Segments_26x42_mn);
u8g2.drawStr(0, 42, bufferClock1);
u8g2.drawStr(58, 42, ":");
u8g2.drawStr(70, 42, bufferClock2);
u8g2.setFont(u8g2_font_8x13_mf);
u8g2.drawStr(0, 55, Datum);
//u8g2.drawStr(0, 55, "uhu67");
u8g2.sendBuffer();
delay(100);
}
// Wifi verbinden
void setup_wifi() {
// Wifi verbinden
delay(10);
WiFi.begin(wifi_ssid, wifi_password);
int counter = 0;
while (WiFi.status() != WL_CONNECTED and counter < 20) {
delay(500);
Serial.print(".");
counter++;
}
// Verbunden ja/nein
if(WiFi.status() == WL_CONNECTED)
{
Serial.println("WiFi connected");
// Uhr nur stellen, wenn Wifi verbunden
set_RTC();
}
else
{
Serial.println("WiFi Verbindung nicht moegliech!");
}
}
// RTC mit NTP synchronisieren
void set_RTC() {
configTime(0, 0, NTP_SERVER);
setenv("TZ", TZ_INFO, 1);
// Uhr vom NTP stellen
time(&now); // Liest die aktuelle Zeit
localtime_r(&now, &tm); // Beschreibt tm mit der aktuelle Zeit
// Check ob Datum gefunden wurde (Server liefert oft nicht ... wenn Jahr = 70, dann nichts geliefert)
int counter = 0;
while (tm.tm_year == 70 and counter < 50)
{
time(&now); // Liest die aktuelle Zeit
localtime_r(&now, &tm); // Beschreibt tm mit der aktuelle Zeit
Serial.printf("%02d-%02d-%04d \t", tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
Serial.printf(" \tUhrzeit: %02d:%02d:%02d \n", tm.tm_hour, tm.tm_min, tm.tm_sec);
delay(300);
counter++;
}
// RTC setzen wenn Zeit übergeben wurde (Counter-Überlauf Check)
if(counter < 50)
{
// rtc.set(second, minute, hour, dayOfWeek, dayOfMonth, month, year)
// set day of week (1=Sunday, 7=Saturday)
rtc.set(tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_wday, tm.tm_mday, tm.tm_mon + 1, tm.tm_year);
Serial.printf(" \t Zeit in RTC gespeichert: %02d %02d %02d %02d %02d %02d %02d \n",tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_wday, tm.tm_mday, tm.tm_mon + 1, tm.tm_year);
}
}