Hallo,
ich bin dabei, meinen Wasserzähler mit einem Wemos D1 mini auslesen zu lassen und den Verbrauch zu meiner Homematic senden zu lassen. Das auslesen funktioniert soweit zuverlässig.
Nur verliert er mehrmals pro Stunde die WLAN-Verbindung, wobei ähnliche Projekte bei mir zu Hause seit Jahren zuverlässig funken.
Die Stromversorung läuft über ein 1A 5V-Netzteil, zusätzlich ein 100 uf-Kondensator zwischen 5V-Pin und GND. Selbst bei zusätzlichem Anschluss über USB tritt der Fehler auf.
Auch habe ich es schon mit einem anderen Wemos D1 mini probiert, keine Verbesserung.
Ansonsten hängt nur eine Photodiode an A0.
Er steht nur 2m neben meinem Router, die Fritzbox zeigt ein kräftiges Signal an.
Softwareseitig diente ein anderer Sketch als Vorlage, der schon Jahre zuverlässig Daten sendet.
#include <ESP8266WiFi.h>
// #include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
int PhotoPin = A0;
unsigned long vergangeneZeit = 0; // Zeitzähler Zählerauslesen 100ms
unsigned long aktuelleZeit = 0;
int Scheibe = 2; //Zählscheibe hell 1 /dunkel 0
int Sensitiv = 15;
int Helligkeit[100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
float HelligkeitMin = 0;
float HelligkeitMittel = 0;
float HelligkeitMax = 0;
int Durchlauf = 0;
int onlinezeittage = 0; // Onlinezeit
int onlinezeittagegesamt = 0;
int onlinezeit = millis();
int rebootscounter = 0; // Neustart WLAN
unsigned long vergangeneZeitHM = 0; // Homematic stündlich kontaktieren
unsigned long aktuelleZeitHM = 0;
unsigned long vergangeneZeitWLAN = 0; // Intervall zum Wifi-check
unsigned long Verbrauchh = 0; // Verbrauchszählung
unsigned long Verbrauchd = 0;
unsigned long Verbrauchw = 0;
String Tag = ""; //Zeitübertragung Homematic
String Tagalt = "";
unsigned long timeout = 0; // timeout beim warten auf Homematic
String url = ""; // url zum Daten senden an Homematic
const int httpPort = 80; // Port der Homematic
const char* ssid = "****";
const char* password = "****";
const char* HomematicIP = "****";
String webString = ""; // Server-String
ESP8266WebServer server(80);
void setup() {
EEPROM.begin(502);
Serial.begin(115200);
initWifi();
EEPROM.get(15, Verbrauchw);
EEPROM.get(25, onlinezeittagegesamt);
pinMode(PhotoPin, INPUT);
delay(300);
for (int i = 0; i < 100; i++) {
Helligkeit[i] = analogRead(PhotoPin) * 10;
delay(5);
}
server.on("/", SchleifeServerRoot);
server.begin();
Serial.println("HTTP Server gestartet");
}
void loop() {
server.handleClient();
if ((millis() - onlinezeit) > (1000 * 60 * 60 * 24)) {
onlinezeit = millis();
++onlinezeittage;
++onlinezeittagegesamt;
EEPROM.put(25, onlinezeittagegesamt);
EEPROM.commit();
}
aktuelleZeitHM = millis();
if (aktuelleZeitHM - vergangeneZeitHM >= 3600000) { //einmal stündlich Zählerstand melden
vergangeneZeitHM = aktuelleZeitHM;
Verbindung();
}
aktuelleZeit = millis();
if (aktuelleZeit - vergangeneZeit >= 1) {
vergangeneZeit = aktuelleZeit;
Durchlauf++;
if (Durchlauf == 100) { Durchlauf = 0; }
Helligkeit[Durchlauf] = analogRead(PhotoPin);
if (Durchlauf == 0) {
HelligkeitMittel = 0;
for (int i = 0; i < 100; i++) {
HelligkeitMittel = HelligkeitMittel + Helligkeit[i];
}
HelligkeitMittel = HelligkeitMittel / 100;
checkWifi(); // Kontrolle WLAN
if (WiFi.status() == WL_CONNECTED) {
rebootscounter = 0;
}
// Serial.print(Helligkeit[Durchlauf]); //zum Fehler ermitteln einschalten
// Serial.print(" "); //zum Fehler ermitteln einschalten
// Serial.print(HelligkeitMittel);
// Serial.println();
if (Scheibe == 2) {
if (HelligkeitMittel < HelligkeitMin) { HelligkeitMin = HelligkeitMittel; }
if (HelligkeitMittel > HelligkeitMax) { HelligkeitMax = HelligkeitMittel; }
if (HelligkeitMittel > HelligkeitMin + Sensitiv) { Scheibe = 1; }
if (HelligkeitMittel < HelligkeitMax - Sensitiv) { Scheibe = 0; }
}
if (Scheibe == 1) {
if (HelligkeitMittel > HelligkeitMax) {
HelligkeitMax = HelligkeitMittel;
if (HelligkeitMittel > HelligkeitMin + Sensitiv) {
HelligkeitMin = HelligkeitMittel - Sensitiv;
}
}
if (HelligkeitMittel < HelligkeitMin) {
HelligkeitMin = HelligkeitMittel;
if (HelligkeitMittel < HelligkeitMax - Sensitiv) {
HelligkeitMax = HelligkeitMittel + Sensitiv;
}
Scheibe = 0;
Serial.println();
Serial.println("Wechsel auf Dunkel!");
Serial.println();
}
}
if (Scheibe == 0) {
if (HelligkeitMittel < HelligkeitMin) {
HelligkeitMin = HelligkeitMittel;
if (HelligkeitMittel < HelligkeitMax - Sensitiv) {
HelligkeitMax = HelligkeitMittel + Sensitiv;
}
}
if (HelligkeitMittel > HelligkeitMax) {
HelligkeitMax = HelligkeitMittel;
if (HelligkeitMittel > HelligkeitMin + Sensitiv) {
HelligkeitMin = HelligkeitMittel - Sensitiv;
}
Scheibe = 1;
Wasser();
Serial.println();
Serial.println("Wechsel auf Hell!");
Serial.println();
}
}
}
}
}
void Wasser() {
Verbrauchh++;
Verbrauchd++;
Verbrauchw++;
}
void initWifi() {
Serial.print("Connecting to "); // Verbindung mit WLAN
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
uint8_t VersucheCount = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(F("."));
VersucheCount++;
if (VersucheCount >= 6 && WiFi.status() == WL_CONNECT_FAILED) {
WiFi.begin(ssid, password);
VersucheCount = 0; // ESP32-workaround (otherwise WiFi-connection sometimes fails)
}
}
Serial.println(""); // Die IP vom Webserver auf dem seriellen Monitor ausgeben
Serial.println("WLAN verbunden.");
Serial.println("IP Adresse: ");
Serial.println(WiFi.localIP());
}
void checkWifi() {
aktuelleZeit = millis();
if ((WiFi.status() != WL_CONNECTED) && (aktuelleZeit - vergangeneZeitWLAN >= 30000)) { // check Wifi-Verbindung alle 30 Sekunden
Serial.print(millis());
Serial.println("Reconnecting to WiFi...");
WiFi.disconnect();
delay(50);
WiFi.reconnect();
delay(50);
vergangeneZeitWLAN = aktuelleZeit;
rebootscounter++;
}
if (rebootscounter == 10) { // speichern, Auszeit, neues WLAN
rebootscounter = 0,
EEPROM.put(15, Verbrauchw);
EEPROM.put(25, onlinezeittagegesamt);
EEPROM.commit();
Serial.println();
Serial.println("WLAN reagiert nicht !!!!");
Serial.println("10 Sekunden Wartezeit...");
Serial.println();
delay(5000);
WiFi.disconnect();
delay(5000);
initWifi();
}
}
void Verbindung() {
checkWifi();
WiFiClient client; //Datenübertragung Verbrauch Stunde
if (!client.connect(HomematicIP, httpPort)) {
Serial.println("Verbindungsaufbau zu Homematic fehlgeschlagen");
return;
} else {
Serial.println("Verbindung zu Homematic hergestellt");
}
// jetzt setzen wir die URL für die Datenübermittlung zusammen
url = "/config/xmlapi/statechange.cgi?ise_id=18741&new_value=";
url += Verbrauchh;
// jetzt senden wir die Anfrage an die Homematic
client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + HomematicIP + "\r\n" + "Connection: close\r\n\r\n");
timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Homematic Timeout !");
client.stop();
return;
}
}
// lese die Antwort von Homematic und gibt sie seriell aus
while (client.available()) {
String line = client.readStringUntil('\r');
Serial.print(line);
if (line.substring(1, 5) == "Date") { // auslesen Tag
Tag = line.substring(7, 10);
Serial.println();
Serial.print("lese Wochentag: ");
Serial.println(Tag);
}
}
Serial.println();
Serial.println("closing connection");
Verbrauchh = 0;
if (Tagalt == "") { Tagalt = Tag; }
if (Tag != Tagalt) { VerbindungTag(); }
}
void VerbindungTag() {
if (Tag == "Mon") { VerbindungWoche(); }
Tagalt = Tag;
checkWifi();
WiFiClient client; //Datenübertragung Verbrauch Tag
if (!client.connect(HomematicIP, httpPort)) {
Serial.println("Verbindungsaufbau zu Homematic fehlgeschlagen");
return;
} else {
Serial.println("Verbindung zu Homematic hergestellt");
}
// jetzt setzen wir die URL für die Datenübermittlung zusammen
url = "/config/xmlapi/statechange.cgi?ise_id=18742&new_value=";
// jetzt senden wir die Anfrage an die Homematic
client.print(String("GET ") + url + Verbrauchd + " HTTP/1.1\r\n" + "Host: " + HomematicIP + "\r\n" + "Connection: close\r\n\r\n");
timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Homematic Timeout !");
client.stop();
return;
}
}
// lese die Antwort von Homematic und gibt sie seriell aus
while (client.available()) {
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");
Verbrauchd = 0;
EEPROM.put(15, Verbrauchw);
EEPROM.commit();
}
void VerbindungWoche() {
checkWifi();
WiFiClient client; //Datenübertragung Verbrauch Woche
if (!client.connect(HomematicIP, httpPort)) {
Serial.println("Verbindungsaufbau zu Homematic fehlgeschlagen");
return;
} else {
Serial.println("Verbindung zu Homematic hergestellt");
}
// jetzt setzen wir die URL für die Datenübermittlung zusammen
url = "/config/xmlapi/statechange.cgi?ise_id=18743&new_value=";
// jetzt senden wir die Anfrage an die Homematic
client.print(String("GET ") + url + Verbrauchw + " HTTP/1.1\r\n" + "Host: " + HomematicIP + "\r\n" + "Connection: close\r\n\r\n");
timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Homematic Timeout !");
client.stop();
return;
}
}
// lese die Antwort von Homematic und gibt sie seriell aus
while (client.available()) {
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");
Verbrauchw = 0;
}
void SchleifeServerRoot() {
webString = "<!DOCTYPE html> <html>\n";
webString += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
// webString +="<meta http-equiv=\"refresh\" content=\"2\">\n"; //Automatische Seitenaktualisierung verursacht Absturz
webString += "<title>Kaltwasserzaehler</title>\n";
webString += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
webString += "h1 {color: #0000FF;}\n"; //
webString += "body{margin-top: 50px;} h1 {color: #0000FF;margin: 50px auto 30px;}\n";
webString += "p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
webString += "</style>\n";
webString += "</head>\n";
webString += "<body>\n";
webString += "<div id=\"webpage\">\n";
webString += "<h1>Hallo von der Erfassung Kaltwasser!</h1>\n";
webString += "<p>aktueller Verbrauch Stunde: ";
webString += String((int)Verbrauchh);
webString += " Liter</p>";
webString += "<p>aktueller Verbrauch Tag: ";
webString += String((int)Verbrauchd);
webString += " Liter</p>";
webString += "<p>aktueller Verbrauch Woche: ";
webString += String((int)Verbrauchw);
webString += " Liter</p>";
webString += "<p>Online seit: ";
webString += String((int)onlinezeittage);
webString += " Tagen</p>";
webString += "<p>Gesamtlaufzeit: ";
webString += String((int)onlinezeittagegesamt);
webString += " Tage</p>";
webString += "</div>\n";
webString += "</body>\n";
webString += "</html>\n";
server.send(200, "text/html", webString);
delay(100);
Serial.println("------------Webseite aufgebaut------------");
}
Interessant sind wohl hauptsächlich "void initWifi()" und "void checkWifi()".
Was sind noch Fehlerquellen, was kann ich probieren?
Vielen Dank und schon mal schöne Feiertage!