275 lines
7.3 KiB
C++
275 lines
7.3 KiB
C++
// Including the ESP8266 WiFi library and other dependencies
|
|
#include <ESP8266HTTPClient.h>
|
|
#include <ESP8266WiFi.h>
|
|
#include <WiFiClient.h>
|
|
#include <DNSServer.h> //Local DNS Server used for redirecting all requests to the configuration portal
|
|
#include <ESP8266WebServer.h> //Local WebServer used to serve the configuration portal
|
|
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
|
|
#include <math.h>
|
|
#include <SPI.h>
|
|
#include <DS3231.h>
|
|
#include <WiFiUdp.h>
|
|
#include <ESP8266HTTPUpdateServer.h>;
|
|
#include <Wire.h>
|
|
#include <LiquidCrystal_I2C.h> //https://github.com/agnunez/ESP8266-I2C-LCD1602
|
|
#include <NTPtimeESP.h> //https://github.com/SensorsIot/NTPtimeESP
|
|
#include <EEPROM.h>
|
|
|
|
//Default Settings
|
|
String Hardware = "0.12";
|
|
String Software = "0.14";
|
|
|
|
String ntp_server = "ntp2.uni-augsburg.de";
|
|
bool ntp_update = true;
|
|
int wakeup_time = 10;
|
|
String message_text = "";
|
|
//ConfigData (WiFi Name and Pin-Numbers)
|
|
const String NodeName = "LichtWecker";
|
|
|
|
//Pin Taster
|
|
const int pinTime = 3; //Pin fuer Toggle_Power und Einstellen der Uhrzeit (Lang)
|
|
const int pinSet = 0; //Pin fuer Sleep und Zeit_Einstellung im Alarm/Time Set Mode
|
|
const int pinAlarm = 2; //Pin fuer Alarm An/Aus und setzen der Alarmzeiten (Lang)
|
|
//Pin Relay
|
|
const int outBeep = 9;
|
|
|
|
|
|
// Set web server port number to 80
|
|
ESP8266WebServer server(80);
|
|
ESP8266HTTPUpdateServer httpUpdater;
|
|
//LED Band Setup
|
|
#define FASTLED_ESP8266_RAW_PIN_ORDER
|
|
#include "FastLED.h"
|
|
#define NUM_LEDS 38
|
|
// Data pin that led data will be written out over
|
|
#define DATA_PIN 14
|
|
// Clock pin only needed for SPI based chipsets when not using hardware SPI
|
|
#define CLOCK_PIN 13
|
|
// This is an array of leds. One item for each led in your strip.
|
|
CRGB leds[NUM_LEDS];
|
|
//RealTimeClock
|
|
RTClib RTC;
|
|
DS3231 Clock;
|
|
//NTP Setup
|
|
NTPtime NTPch(ntp_server); // Choose server pool as required
|
|
//Display
|
|
LiquidCrystal_I2C lcd(0x3f, 16, 2);
|
|
|
|
//Helpers
|
|
//To know if connected to wifi or not:
|
|
bool wifi_connected = false;
|
|
//For Summertime change notification (change alarmtime) this should be saved in the EEPROM!
|
|
bool summer = false;
|
|
//Alarm Started?
|
|
bool alarm_started = false;
|
|
long startTime = 0;
|
|
bool lamp_on = false;
|
|
//Alarm 1 Time
|
|
int al1h = 0;
|
|
int al1m = 0;
|
|
//Alarm 2 Time
|
|
int al2h = 0;
|
|
int al2m = 0;
|
|
//Alarm run Counter
|
|
long time_on = -1;
|
|
int minutes_sleep = -1;
|
|
//Current Date and Time from RTC
|
|
int h = 0;
|
|
int m = 0;
|
|
int s = 0;
|
|
int d = 0;
|
|
int M = 0;
|
|
int y = 0;
|
|
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
|
|
String dow = "-";
|
|
//Current Menu Item
|
|
int setItem = 0;
|
|
//Display is not updated (for block_gui Secondes)
|
|
long block_gui = -1;
|
|
//Counting Mills
|
|
long previousMillis = 0;
|
|
|
|
//If not Connected to Wifi
|
|
void configModeCallback (WiFiManager *myWiFiManager) {
|
|
//if you used auto generated SSID, print it
|
|
//write_log(myWiFiManager->getConfigPortalSSID());
|
|
display_text("Wifi: Licht","PW: Wecker");
|
|
}
|
|
|
|
//Initial Code
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
delay(10);
|
|
//Setup Display
|
|
// Initialise the LCD
|
|
lcd.begin(4,5); // sda=0, scl=2
|
|
// Turn on the backlight
|
|
lcd.backlight();
|
|
|
|
Wire.begin();
|
|
|
|
display_text("Not for Sale","Prototyp by CHM");
|
|
delay(2000);
|
|
display_text("L","");
|
|
delay(200);
|
|
display_text("Li","");
|
|
delay(200);
|
|
display_text("Lic","");
|
|
delay(200);
|
|
display_text("Lich","");
|
|
delay(200);
|
|
display_text("Licht","");
|
|
delay(200);
|
|
display_text("Licht W","");
|
|
delay(200);
|
|
display_text("Licht We","");
|
|
delay(200);
|
|
display_text("Licht Wec","");
|
|
delay(200);
|
|
display_text("Licht Weck","");
|
|
delay(200);
|
|
display_text("Licht Wecke","");
|
|
delay(200);
|
|
display_text("Licht Wecker","Connecting...");
|
|
delay(200);
|
|
|
|
|
|
//Pin Setup
|
|
pinMode(pinTime, INPUT); // set pin to input
|
|
digitalWrite(pinTime, HIGH); // turn on pullup resistors
|
|
|
|
pinMode(pinSet, INPUT); // set pin to input
|
|
digitalWrite(pinSet, HIGH); // turn on pullup resistors
|
|
|
|
pinMode(pinAlarm, INPUT); // set pin to input
|
|
digitalWrite(pinAlarm, HIGH); // turn on pullup resistors
|
|
|
|
pinMode(outBeep, OUTPUT); // set pin to input
|
|
digitalWrite(outBeep, LOW); // turn on pullup resistors
|
|
|
|
//restore data
|
|
get_eeprom();
|
|
|
|
WiFi.hostname(NodeName);
|
|
//WiFiManager intialisation. Once completed there is no need to repeat the process on the current board
|
|
WiFiManager wifiManager;
|
|
wifiManager.setAPCallback(configModeCallback);
|
|
//sets timeout until configuration portal gets turned off
|
|
//useful to make it all retry or go to sleep
|
|
//in seconds
|
|
wifiManager.setTimeout(120);
|
|
//reset saved settings
|
|
if(digitalRead(pinSet) == LOW && digitalRead(pinTime) == LOW){
|
|
display_text("WiFi","Reset...");
|
|
wifiManager.resetSettings();
|
|
delay(1000);
|
|
ESP.reset();
|
|
delay(5000);
|
|
}
|
|
if (wifiManager.autoConnect("Licht", "Wecker")){
|
|
write_log("WiFi connected");
|
|
write_log("IP address: ");
|
|
write_log(WiFi.localIP().toString());
|
|
wifi_connected = true;
|
|
display_text("IP address",WiFi.localIP().toString());
|
|
delay(5000);
|
|
}
|
|
else{
|
|
WiFi.mode(WIFI_OFF);
|
|
}
|
|
display_text("Licht Wecker","SW: " + Software);
|
|
delay(1000);
|
|
display_text("Licht Wecker","HW: " + Hardware);
|
|
delay(1000);
|
|
display_text("Licht Wecker","");
|
|
|
|
//Set Alarm Times
|
|
DateTime now = RTC.now();
|
|
d = now.day();
|
|
M = now.month();
|
|
y = now.year();
|
|
h = now.hour(); //24-hr
|
|
|
|
byte A1Day, A1Hour, A1Minute, A1Second, AlarmBits;
|
|
bool A1Dy, A1h12, A1PM;
|
|
Clock.getA1Time(A1Day, A1Hour, A1Minute, A1Second, AlarmBits, A1Dy, A1h12, A1PM);
|
|
if (summer)
|
|
{
|
|
al1h = A1Hour + 1;
|
|
}
|
|
else{
|
|
al1h = A1Hour;
|
|
}
|
|
al1m = A1Minute;
|
|
write_log("Alarm1 Set:" + String(A1Day) + ", " + String(A1Hour) + ", " + String(A1Minute) + ", " + String(AlarmBits) + ", " + String(A1Dy) + ", " + String(A1h12) + ", ");
|
|
|
|
Clock.getA2Time(A1Day, A1Hour, A1Minute, AlarmBits, A1Dy, A1h12, A1PM);
|
|
if (summer)
|
|
{
|
|
al2h = A1Hour + 1;
|
|
}
|
|
else{
|
|
al2h = A1Hour;
|
|
}
|
|
al2m = A1Minute;
|
|
write_log("Alarm2 Set:" + String(A1Day) + ", " + String(A1Hour) + ", " + String(A1Minute) + ", " + String(AlarmBits) + ", " + String(A1Dy) + ", " + String(A1h12) + ", ");
|
|
|
|
show_green();
|
|
update_time_from_web();
|
|
delay(1000);
|
|
show_black();
|
|
|
|
previousMillis = millis();
|
|
|
|
update_time_from_web();
|
|
|
|
setup_webserver();
|
|
}
|
|
|
|
|
|
void loop() {
|
|
//Handle web requests
|
|
handle_webserver();
|
|
unsigned long currentMillis = millis();
|
|
unsigned long intervall = currentMillis - previousMillis;
|
|
|
|
update_display(currentMillis,intervall);
|
|
|
|
//Test Input-Pin pressed
|
|
test_pin();
|
|
//Handle Sleep Timer timeout
|
|
handleSleep(intervall, currentMillis);
|
|
//Test time every hour
|
|
if(m == 1 && s == 30)
|
|
{
|
|
update_time_from_web();
|
|
}
|
|
//Delay for Wifi Tasks
|
|
delay(100);
|
|
}
|
|
|
|
void update_display(){
|
|
unsigned long currentMillis = millis();
|
|
unsigned long intervall = currentMillis - previousMillis;
|
|
update_display(currentMillis,intervall);
|
|
}
|
|
|
|
void update_display(unsigned long currentMillis, unsigned long intervall){
|
|
//Unblock Display (if block_gui was set)
|
|
release_gui(currentMillis);
|
|
|
|
if(setItem == 0){
|
|
//Run normal
|
|
update_Time();
|
|
run_alarm(currentMillis);
|
|
if (block_gui < 0)
|
|
show_current_time(intervall,currentMillis);
|
|
}
|
|
else{
|
|
//Show Menu
|
|
show_time_infos(intervall,currentMillis);
|
|
previousMillis = currentMillis;
|
|
}
|
|
}
|
|
|