/*********
©Adrian Zilly
@Tueroeffner
Hardware Lib: ESP8622 NodeMCU 1.0 (ESP12E-Module)
Script v3.1
Letzte Aenderung 2021-01-19
*********/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoOTA.h>
#include <WiFiUdp.h>
#include <ESP8266mDNS.h>
//--------------------------------------------------
//Define Variables
int Digits = 0;
int BattVolt = 0;
int BattPerc = 0;
int valA0 = 0;
int StartMerker = 0;
int Start = 0;
int Start2 = 0;
int Start3 = 0;
unsigned long sleepMillis = 10, Sendertime = 10, previousMillis = 10, currentMillis = 10;
const long intervalon = 1000;
const long intervaloff = 1000;
int SendeDelay = 5000;
int WLANTimeout = 30;
int WLANCounts = 0;
int SetSleep = 0;
//--------------------------------------------------
//PARAMETER EINSTELLUNGEN
//Parameter Analogwertauslesen (Digit Korrektur)
int DigitsCor = 0;
//Sleep Delay Parameter
unsigned long currentSleep, SenderSleep;
const long gosleepdelay = 120000; //Verzoegerung Schlafen gehen 1000ms = 1s - Set to 100000 (2min.)
//WLAN Setup
const char* SSID = "MYSUPERWLANISTHEBESTOFTHEPLANET"; //WLAN Name
const char* PSK = "LOLOLOLOLOLOHOHOHOHOHOHOHOHO"; //Passwort WLAN
//Pin Setup
#define BattVoltIn A0 //Analog Input
int Rot = 4; //GPIO LED Rot
int Gelb = 5; //GPIO Bereitschaft
int Gruen = 12; //GPIO Klingelgedrueckt/Reserve
int Tueroeffner = 15; //GPIO 15 Tueroeffner --- HIGH
bool TueroeffnerRelais = HIGH; //Relaisboard HIGH or LOW Trigger
bool TueroeffnerRelaisOpen, TueroeffnerRelaisClose;
//--------------------------------------------------
//---------------
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
int wifi_retry;
//---------------
/*Unterprogramm Akkulevel auslesen
ggf. Kalibrieren mit Hilfe von "DigitsCor = Digits + 0;" hier hinter dem + entsprechende Korrektur eintragen
Messgeraet an Akku direkt anschließen. Spannung messen und entsprechenden Korrekturwert ermitteln.
Weitere Moeglichkeit, direkt die Punkte definieren.
BattVolt = map(DigitsCor, 0, 282, 0, 4089); - map(Analogwert, LowDigit, HighDigit, LowValue, HighValue);
Folglich dann die zwei Werte anpassen: map(DigitsCor, 0, !!hier Ausgegebener Digitwert bei gleichzeitiger Akkumessung eintragen!!, 0, !!hier gemessener Messwert eintragen!!);
Nicht vergessen die gleichen Werte bei Battperc einzutragen.
*/
void AkkuStand() {
//Volt auslesen
Digits = analogRead(BattVoltIn);
DigitsCor = Digits + 0; // + 0 mit Korrektur versehen.
BattVolt = map(DigitsCor, 0, 282, 0, 4089);
// 1d = 14,4mV / 230d = 3312mV / 284d = 4089mV
BattPerc = map(DigitsCor, 230, 282, 0, 100);
if (BattPerc == 0) {
AkkuStand();
}
Serial.print("AkkuStand\nDigit: ");
Serial.print(Digits);
Serial.print("Batt Volt");
Serial.print(BattVolt);
}
//---------------
void Klingel() {
//Unterprogramm Klingelsignal senden
digitalWrite(Gruen, HIGH);
client.publish("Klingelgedrueckt", "1");
Serial.println("It ringed for you!");
delay(1000);
digitalWrite(Gruen, LOW);
client.publish("Klingelgedrueckt", "0");
}
//---------------
void Close() {
//Unterprogramm Tuer schließen
Serial.println("I close it for you!");
client.publish("Haustuerstatuslaueft", "gesichert");
digitalWrite(Tueroeffner, TueroeffnerRelaisClose);
//delay(500);
client.publish("Haustuerstatusist", "gesichert");
client.publish("Haustuer", "Sicherung durchgefuehrt!");
}
//---------------
void Open() {
//Unterprogramm Tuer oeffnen
Serial.println("I open it for you!");
client.publish("Haustuerstatuslaueft", "offen");
client.publish("Haustuerstatuslaueft", "offen");
//delay(500);
digitalWrite(Tueroeffner, TueroeffnerRelaisOpen);
client.publish("Haustuerstatusist", "offen");
client.publish("Haustuerstatusist", "offen");
Serial.println("Haustuer wurde geoeffnet!");
delay(3000);
digitalWrite(Tueroeffner, TueroeffnerRelaisClose);
client.publish("Haustuerstatuslaueft", "gesichert");
client.publish("Haustuerstatuslaueft", "gesichert");
Serial.println("Haustuer wird geschlossen!");
//delay(500);
client.publish("Haustuerstatusist", "gesichert");
client.publish("Haustuerstatusist", "gesichert");
Serial.println("Haustuer wurde gesichert!");
//delay(500);
}
void SendAkku() {
//Unterprogramm Akkulevel uebertragen
client.publish("BatterieLevelTuer", String(BattPerc).c_str(), true);
client.publish("HaustuerAkkuDigit", String(Digits).c_str(), true);
String mV = ("mV: " + String(BattVolt));
client.publish("HaustuerAkku", String(mV).c_str(), true);
String Perc = ("Perc: " + String(BattPerc));
client.publish("HaustuerAkku", String(Perc).c_str(), true);
Serial.print("\nHaustuerAkku:");
Serial.print(BattPerc);
Start3++;
}
//---------------
//Unterprogramm Callback MQTT
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Received message [");
Serial.print(topic);
Serial.print("] ");
char msg[length + 1];
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
msg[i] = (char)payload[i];
}
msg[length] = '\0';
Serial.println(msg);
client.publish("Haustuer", "I got an Order!");
if (strcmp(msg, "gesichert") == 0) {
Close();
}
else if (strcmp(msg, "offen") == 0) {
Open();
}
else {
Serial.print("Nichts kam an");
}
}
//---------------
void setup() {
//Cleanup
ESP.eraseConfig();
WiFi.disconnect();
Serial.begin(115200);
//PIN Setup
pinMode(Tueroeffner, OUTPUT); //Relais Tueroeffner
pinMode(Gelb, OUTPUT); //Bereitschaft
pinMode(Rot , OUTPUT); //LED Tueroeffner
pinMode(Gruen, OUTPUT); //Klingelsignal
if (TueroeffnerRelais == HIGH){
TueroeffnerRelaisOpen = HIGH;
TueroeffnerRelaisClose = LOW;
}
else if (TueroeffnerRelais == LOW){
TueroeffnerRelaisOpen = LOW;
TueroeffnerRelaisClose = HIGH;
}
else{
Serial.print("Error Set TueroeffnerRelais Output");
}
digitalWrite(Tueroeffner, TueroeffnerRelaisClose); //
//------- END Pin Setup ---------
delay(100);
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, PSK);
while (WiFi.status() != WL_CONNECTED && WLANTimeout > WLANCounts) {
delay(500);
WLANCounts++;
Serial.print("\n Wifi Connecting..");
Serial.print("\n Trys:");
Serial.print(WLANCounts);
Serial.print("/");
Serial.print(WLANTimeout);
}
if (WLANCounts >= WLANTimeout) {
ESP.restart();
}
else {
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
WLANCounts = 0;
}
client.setServer("192.167.1.15", 1883);
client.setCallback(callback);
AkkuStand();
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch";
} else { // U_FS
type = "filesystem";
}
Serial.println("Start updating " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) {
Serial.println("Auth Failed");
} else if (error == OTA_BEGIN_ERROR) {
Serial.println("Begin Failed");
} else if (error == OTA_CONNECT_ERROR) {
Serial.println("Connect Failed");
} else if (error == OTA_RECEIVE_ERROR) {
Serial.println("Receive Failed");
} else if (error == OTA_END_ERROR) {
Serial.println("End Failed");
}
});
ArduinoOTA.setHostname("ESP-Haustuere");
ArduinoOTA.setPassword("nimda");
ArduinoOTA.begin();
}
//---------------
//Unterprogramm Neu Verbinden MQTT
void reconnect() {
while (!client.connected()) {
Serial.println("\nReconnecting MQTT...");
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
if (!client.connect(clientId.c_str())) {
Serial.print("failed, rc=");
Serial.print(client.state());
delay(1000);
}
else {
client.subscribe("Haustueroeffnen");
client.publish("HaustuerStatus", "MQTT Connected");
char buf[16];
sprintf(buf, "%d", StartMerker);
const char* SendMerker = buf;
client.publish("HaustuerStatus", SendMerker);
Serial.println("MQTT Connected...");
Close();
}
}
}
//----------------------------------------
void loop() {
//WLAN noch verbunden? Andernfalls neu verbinden
if (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("WLAN not connected, reconnecting...");
wifi_retry = 0;
while (WiFi.status() != WL_CONNECTED && wifi_retry < 30) {
Serial.println(wifi_retry);
wifi_retry++;
Serial.println("WiFi not connected. Try to reconnect");
delay(500);
}
//Falls zu oft Verbindungsversuch durchgefuehrt wurde, ESP neu starten
if (wifi_retry >= 30) {
Serial.println("\nReboot");
ESP.restart();
}
}
//MQTT noch verbunden? Andernfalls neu verbinden
if (!client.connected()) {
reconnect();
}
client.loop();
//Over Air Programmierung
ArduinoOTA.handle();
delay(100);
//Unterprogramme abrufen
AkkuStand();
SendAkku();
//Bereitschaftsanzeige
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= intervaloff) {
previousMillis = currentMillis;
digitalWrite(Gelb, HIGH);
}
else if (currentMillis - previousMillis >= intervalon) {
digitalWrite(Gelb, LOW);
}
//Variable ablegen mit der aktuellen Zeit fuer Ueberpruefung Schlafengehen
currentSleep = millis();
//Ueberpruefen ob zeit zum schlafen ist
if (currentSleep - sleepMillis >= gosleepdelay && client.connected() && WiFi.status() == WL_CONNECTED) {
//WLAN und MQTT noch verbunden? Andernfalls neu verbinden
if (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("WLAN not connected, reconnecting...");
while (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi not connected. Try to reconnect");
delay(500);
}
}
if (!client.connected()) {
reconnect();
}
//Ausgaenge für Schlafen vorbereiten
sleepMillis = currentSleep;
//Ausgaenge für Schlafen vorbereiten
digitalWrite(Tueroeffner, TueroeffnerRelaisClose);
digitalWrite(Gruen, LOW);
digitalWrite(Gelb, LOW);
digitalWrite(Rot, LOW);
//Mitteliung dass Deepsleep gestartet wird.
client.publish("Haustuer", "END WIFI NOW and go Sleep...");
client.publish("Haustuer", "go sleeping...");
//ESP schlafen legen
delay(1000);
Serial.println("END WIFI");
WiFi.mode(WIFI_OFF);
delay(1000);
Serial.println("Deepsleep Now..");
delay(500);
ESP.deepSleep(0);
delay(200000);
}
}
//--------------------------------------------------
Alles anzeigen