Steuerung Pumpenvorlage mittels Füllstandskontrolle

Programmierung der HomeMatic CCU mittels contronics homeputer CL

Moderator: Co-Administratoren

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 14.07.2017, 17:23

Hi,

die Zusammensetzung des Strings hat funktioniert und eine Meldung wird abgesetzt bzw. in HPCL übernommen, die weiteren abgesetzten Meldungen werden in HPCL nicht mehr übernommen. Gehe ich in den Browser und setze mehrere Meldungen ab verändert sich die Anzeige in HPCL, somit gehe ich davon aus, dass das Problem in C im Arduino ist.

Hier nochmal den Code

Code: Alles auswählen

/*
    WeMos LevelControl

    verbindet sich mit dem vorhandenen WLAN als Server
    und der EE (HPCL) Client

    Getesteter Aufbau:
       AZDelivery D1 Mini NodeMcu Lua ESP8266 ESP-12E WLAN WIFI Internet Module Entwicklungsboard für Arduino, 100% kompatibel mit WeMos D1 Mini

       Pin-Belegung:
          A0 = analoger Eingang

    9.Februar 2016 —m.yoda
    14. Juli 2017 -AFi
    Version 2.0
*/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WebServer.h>

// ******* Netzwerkeinstellungen, bitte anpassen! *******
const char* ssid = "........."; // SSID des vorhandenen WLANs
const char* password = "....."; // Passwort für das vorhandene WLAN
IPAddress gateway(999, 999, 999, 9); // IP-Adresse des WLAN-Gateways
IPAddress subnet(999, 999, 999, 9); // Subnetzmaske
IPAddress ip(999, 999, 999, 99); // feste IP-Adresse für den WeMos
const char* host = "999.999.999.99"; // IP-Adresse der CCU (mit Punkten!)
ESP8266WebServer server(80); // Webserver initialisieren auf Port 80
String completeURI = "";
float sensorPin = A0;
unsigned long deltaMessungSekunden = 10; //Zeitintervall (Sekunden) nach dem eine Messung erfolgt
float korrLevel = 0; // Korrekturwert fuer die Level Messung


// ******* Einstellungen fuer Meldungen an die HPCL, bitte anpassen! *******
unsigned long deltaMeldungSekunden = 300; // Zeitintervall (Sekunden) nach dem eine CCU-Meldung erfolgt (0 bedeutet nie)
float deltaLevel = 5; // Levelaenderung (*mmWS) bei der eine CCU-Meldung erfolgt (0 bedeutet nie)

float levelMessung = 0, levelHPCL = 0;

unsigned long jetztMillis = 0;
unsigned long deltaMessungMillis = deltaMessungSekunden * 1000, letzteMessungMillis = 0;
unsigned long deltaMeldungMillis = deltaMeldungSekunden * 1000, letzteMeldungMillis = 0;
String requestResult;

String zeitstempel() { // Betriebszeit als Stunde:Minute:Sekunde
  char stempel[10];
  int lfdStunden = millis() / 3600000;
  int lfdMinuten = millis() / 60000 - lfdStunden * 60;
  int lfdSekunden = millis() / 1000 - lfdStunden * 3600 - lfdMinuten * 60;
  sprintf (stempel, "%03d:%02d:%02d", lfdStunden, lfdMinuten, lfdSekunden);
  return stempel;
}

void messung() { // Sensor abfragen
  levelMessung = analogRead(sensorPin) + korrLevel;
  if (isnan(levelMessung)) {
    Serial.println(zeitstempel() + "  Fehler: Sensor konnte nicht abgefragt werden");
    delay(100);
    return;
  }
  letzteMessungMillis = jetztMillis;
  Serial.println(zeitstempel() + "  Messung LEVEL: " + levelMessung + " mmWS ");
}

void melde_HPCL() { // Werte an EE HPCL melden
  HTTPClient http;
  completeURI += "http://999.999.999.99/addons/contronics/CLWebI.ccc?SETVARBYNAME&P_004LEVELTONNEARDUINO=";
  completeURI += levelMessung;
  http.begin(completeURI); 
  int httpCode = http.GET();
  if (httpCode == HTTP_CODE_OK) {
    requestResult = http.getString();
    Serial.println(requestResult);
    levelHPCL = levelMessung;
  }
  else
  {
    Serial.print("Result-Code");
    Serial.println(httpCode);
  }
  http.end();
}

void setup() {
  // Seriellen Monitor für Kontrollausgaben öffnen
  Serial.begin(57600);
  Serial.println("");
  Serial.println("WeMos Levelsensor");

  // WLAN-Verbindung herstellen
  WiFi.config(ip, gateway, subnet); // auskommentieren, falls eine dynamische IP bezogen werden soll
  WiFi.begin(ssid, password);
  Serial.print("Verbindungsaufbau");

  // Verbindungsaufbau abwarten
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" erfolgreich!");
  Serial.println("");
  Serial.print("Verbunden mit: ");
  Serial.println(ssid);
  Serial.print("Signalstaerke: ");
  int rssi = WiFi.RSSI();
  Serial.print(rssi);
  Serial.println(" dBm");
  Serial.print("IP-Adresse: ");
  Serial.println(WiFi.localIP());
  Serial.println("");

  // HTTP-Server starten
  server.begin();
  Serial.println(zeitstempel() + "  HTTP-Server gestartet");

  // Startwerte fuer Zeittrigger
  letzteMessungMillis = millis();
  letzteMeldungMillis = millis();
}

void loop() {
  // auf HTTP-Anfragen warten
  server.handleClient();

  jetztMillis = millis();

  // neue Messung falls Zeitintervall erreicht
  if (jetztMillis - letzteMessungMillis > deltaMessungMillis) {
    messung();
  }

  // neue Meldung an HPCL falls Zeitintervall erreicht
  if (!deltaMeldungMillis == 0 && jetztMillis - letzteMeldungMillis > deltaMeldungMillis) {
    Serial.println(zeitstempel() + "  Zeitintervall erreicht: ");
    letzteMeldungMillis = jetztMillis;
    melde_HPCL();
  }

  // neue Meldung an HPCL falls Level den Schwellwert erreicht
  if (!deltaLevel == 0 && abs(levelMessung - levelHPCL) >= deltaLevel) {
    Serial.println(zeitstempel() + "  Leveländerung: ");
    levelHPCL = levelMessung;
    melde_HPCL();
  }
}

Hier auch die Meldungen im IDE Fenster.
Unbenannt.PNG
Unbenannt.PNG (10.99 KiB) 3788 mal betrachtet
Gruß Axel

Familienvater
Beiträge: 7151
Registriert: 31.12.2006, 15:18
System: Alternative CCU (auf Basis OCCU)
Wohnort: Rhein-Main
Danksagung erhalten: 34 Mal

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von Familienvater » 14.07.2017, 23:28

Hi,

ich finde die Bedingung !deltaMeldungMillis == 0 befremdlich und weiß nicht genau, wie der Compiler das interpretiert, ich würde es mit deltaMeldungMillis != 0 probieren, weil die Bindung von ! an die Variable höher sein könnte als die Umkehrung, dann wäre !(deltaMeldungMillis == 0) die sicherere Variante, aber immer noch schwer zu lesen.

Ich weiß aber nicht, in welchem Dialektraum Du groß geworden bist, ob dort die doppelte Verneinung zum täglichen Sprachgebrauch gehört. Um die Wikipedia zu zitieren:
Bei binären Begriffen ist eine doppelte Verneinung dagegen nicht sinnvoll:
Statt Ich bin nicht unschwanger ist allein Ich bin schwanger gebräuchlich.
https://de.wikipedia.org/wiki/Doppelte_Verneinung

Der Familienvater

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 22.07.2017, 08:28

HiFamilienvater,

groß geworden bin ich, jedoch nicht in C. Ich wollte es zwar vor vielen Jahren mal lernen aber mit fehlte die entsprechende Anwendung. Meine Heimat ist eher VisualBasic.

Ich habe Deine Anregung umgesetzt und noch etwas den Code geglättet. Leider funktioniert die dauerhafte Übertragung nicht, nur beim Start des Wemos ein mal.

Des weiteren hänge ich noch am Messwertverstärker (bin leider kein Elektroniker), du hast es ja schon umgesetzt, wärst du bereit eine Handskizze vom Schaltplan einzustellen.

Anbei nochmals den Code.

Gruß Axel

Code: Alles auswählen

/*
    WeMos LevelControl

    verbindet sich mit dem vorhandenen WLAN als Server
    und der EE (HPCL) Client

    Getesteter Aufbau:
         WeMos D1 Mini
  MPX2010GP (Füllstandsmesser)
  A0 = analoger Eingang

    14. Juli 2017 -AFi
    Version 3.0
*/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>                      //ev. entfernen
#include <ESP8266WebServer.h>

// ******* Netzwerkeinstellungen, bitte anpassen! *******
const char* ssid = "MeinHeimAFi";                   // SSID des vorhandenen WLANs
const char* password = "Gr85za36Pg48sT18";          // Passwort für das vorhandene WLAN
IPAddress gateway(192, 168, 188, 1);                // IP-Adresse des WLAN-Gateways
IPAddress subnet(255, 255, 255, 0);                 // Subnetzmaske
IPAddress ip(192, 168, 188, 60);                    // feste IP-Adresse für den WeMos
const char* host = "192.168.188.49";                // IP-Adresse der CCU (mit Punkten!)
ESP8266WebServer server(80);                        // Webserver initialisieren auf Port 80
String completeURI = "";
float sensorPin = A0;                               //Analogpin am Wemos D1 mini
unsigned long deltaMessungSekunden = 10;            //Zeitintervall (Sekunden) nach dem eine Messung erfolgt
float korrLevel = 101.9744289/0.0025;               //Korrekturwert fuer die Level Messung Umrechnung mV in kPa bzw. mmWS
String requestResult;                               //Antworttext bei Datenübergabe

// ******* Einstellungen fuer Meldungen an die HPCL *******
unsigned long deltaMeldungSekunden = 120;           // Zeitintervall (Sekunden) nach dem eine CCU-Meldung erfolgt (0 bedeutet nie)
float deltaLevel = 5;                               // Levelaenderung (*mmWS) bei der eine CCU-Meldung erfolgt (0 bedeutet nie)
float levelMessung = 0, levelHPCL = 0;

unsigned long jetztMillis = 0;
unsigned long deltaMessungMillis = deltaMessungSekunden * 1000, letzteMessungMillis = 0;
unsigned long deltaMeldungMillis = deltaMeldungSekunden * 1000, letzteMeldungMillis = 0;


String zeitstempel() {                              // Betriebszeit als Stunde:Minute:Sekunde
  char stempel[10];
  int lfdStunden = millis() / 3600000;
  int lfdMinuten = millis() / 60000 - lfdStunden * 60;
  int lfdSekunden = millis() / 1000 - lfdStunden * 3600 - lfdMinuten * 60;
  sprintf (stempel, "%03d:%02d:%02d", lfdStunden, lfdMinuten, lfdSekunden);
  return stempel;
}

void messung() {                                    // Sensor abfragen
  levelMessung = analogRead(sensorPin) * korrLevel;
  if (isnan(levelMessung)) {
    Serial.println(zeitstempel() + "  Fehler: Sensor konnte nicht abgefragt werden");
    delay(100);
    return;                                         //Rücksprung auf if; Endlosschleife bei Störung
  }
  letzteMessungMillis = jetztMillis;
  Serial.println(zeitstempel() + "  Messung LEVEL: " + levelMessung + " mmWS ");
}

void melde_HPCL() {                                 // Werte an EE HPCL melden
  HTTPClient http;
  completeURI += "http://192.168.188.49/addons/contronics/CLWebI.ccc?SETVARBYNAME&P_004LEVELTONNEARDUINO=";
  completeURI += levelMessung;
  http.begin(completeURI); 
  int httpCode = http.GET();
  if (httpCode == HTTP_CODE_OK) {
    requestResult = http.getString();
    Serial.println(requestResult);
    levelHPCL = levelMessung;
  }
  else
  {
    Serial.print("Result-Code");
    Serial.println(httpCode);
  }
  http.end();
}


void setup() {
  // Seriellen Monitor für Kontrollausgaben öffnen
  Serial.begin(57600);
  Serial.println("");
  Serial.println("WeMos Levelsensor");

  // WLAN-Verbindung herstellen
  WiFi.config(ip, gateway, subnet);                       // auskommentieren, falls eine dynamische IP bezogen werden soll
  WiFi.begin(ssid, password);
  Serial.print("Verbindungsaufbau");

  // Verbindungsaufbau abwarten
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" erfolgreich!");
  Serial.println("");
  Serial.print("Verbunden mit: ");
  Serial.println(ssid);
  Serial.print("Signalstaerke: ");
  int rssi = WiFi.RSSI();
  Serial.print(rssi);
  Serial.println(" dBm");
  Serial.print("IP-Adresse: ");
  Serial.println(WiFi.localIP());
  Serial.println("");

  // HTTP-Server starten
  server.begin();
  Serial.println(zeitstempel() + "  HTTP-Server gestartet");

  // Startwerte fuer Zeittrigger
  letzteMessungMillis = millis();
  letzteMeldungMillis = millis();
}


void loop() {
  // auf HTTP-Anfragen warten
  server.handleClient();

  jetztMillis = millis();

  // neue Messung falls Zeitintervall erreicht
  if (jetztMillis - letzteMessungMillis > deltaMessungMillis) {
    letzteMessungMillis = jetztMillis;
    messung();
  }

  // neue Meldung an HPCL falls Zeitintervall erreicht
  if ((deltaMeldungMillis != 0) && ((jetztMillis - letzteMeldungMillis) > deltaMeldungMillis)) {
    Serial.println(zeitstempel() + "  Zeitintervall erreicht: ");
    letzteMeldungMillis = jetztMillis;
    melde_HPCL();
  }

  // neue Meldung an HPCL falls Level den Schwellwert erreicht
  if ((deltaLevel != 0) && abs((levelMessung - levelHPCL) >= deltaLevel)) {
    Serial.println(zeitstempel() + "  Leveländerung: ");
    levelHPCL = levelMessung;
    melde_HPCL();
  }
}

Familienvater
Beiträge: 7151
Registriert: 31.12.2006, 15:18
System: Alternative CCU (auf Basis OCCU)
Wohnort: Rhein-Main
Danksagung erhalten: 34 Mal

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von Familienvater » 22.07.2017, 12:10

Hi,

Messverstärker/Instrumentenverstärker-Schaltung habe ich einfach bei Wikipedia gefunden, da braucht es keine Handskizze von mir :-)

Zwei Dinge an Deinem Code:

Code: Alles auswählen

    void melde_HPCL() {                                 // Werte an EE HPCL melden
      HTTPClient http;
      completeURI += "http://192.168.188.49/addons/contronics/CLWebI.ccc?SETVARBYNAME&P_004LEVELTONNEARDUINO=";
      completeURI += levelMessung;
Du musst natürlich die erste Zuweisung der completeURI nur mit = machen, mit += hängst Du ja jedesmal wieder was an, dann geht relativ schnell dem kleinen der Speicher aus...

Und

Code: Alles auswählen

    String zeitstempel() {                              // Betriebszeit als Stunde:Minute:Sekunde
      char stempel[10];
....
      return stempel;
    }
Ich weiß nicht wie verzeihend C++/der Arduino-Compiler ist, aber ich würde ein static char stempel[10] draus machen, damit "lebt" der Speicherbereich auch noch, nachdem die Funktion verlassen wurde. Soetwas kann (irgendwann) knallen, muss es aber nicht, mit static ist man auf der sicheren Seite, oder man nutzt wiederum eine globale Variable, die behält auch immer ihre Gültigkeit.

Ansonsten sieht das soweit gut aus :-)

Der Familienvater

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 22.07.2017, 15:58

Hi,

den Code kann ich leider heute nicht testen, da ich nicht in der Nähe meiner CCU2 bin.

Jedoch habe ich anbei einen kleinen Schaltplan erstellt, habe mein Bastelkasten dabei und möchte nicht gleich meinen Wemos zerschießen, ev. schaust Du mal drüber.

Gruß Axel
Unbenannt.PNG

Familienvater
Beiträge: 7151
Registriert: 31.12.2006, 15:18
System: Alternative CCU (auf Basis OCCU)
Wohnort: Rhein-Main
Danksagung erhalten: 34 Mal

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von Familienvater » 22.07.2017, 16:33

Hi,

ich habe von Elektronik "keine" Ahnung, aber mit nur einer OP-Amp-Stufe kann es kein Instrumenten/Messverstärker sein, das braucht 2 Stufen, guckst Du hier:
https://de.wikipedia.org/wiki/Instrumen ... #Zwei_OPVs

Das ist meine "Platine", mit der ich ins Rennen gegangen bin, ich kann Dir aber nicht sagen, ob ich da später noch einen Fehler nur auf der Platine behoben habe, und/oder das auch im Lochmaster nachgezogen habe. Aber noch mal zur Erinnerung: Mein Sensor macht 25 mV Fullscale und die Schaltung skaliert auf 0-10V, Deiner müsste FullScale 5V haben, und Du willst auf 0-3,3V?
2017-07-22_16h29_03.png
Der Familienvater

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 31.07.2017, 21:03

Hi,

bin schon ziemlich am verzweifeln, die Messung mit dem MPX2010GP habe ich fast verworfen, mangels Erfolg mit dem Messwertverstärker.

Inzwischen bin ich umgestiegen auf Ultraschallsensor HC-SR04 (hab durch Zufall einen, da ich mir zu Anfang ein Starterkit gekauft habe). Die Messung mit dem Arduino uno R3 funktioniert ohne Probleme, jedoch habe ich beim Wemos D1 mini keinen Erfolg, egal welche Digital Pins ich verwende.

Anbei das Programm, eventuell hat jemand einen TIP, ansonsten würde eigentlich alles bis zu Homeputer funktionieren.

Code: Alles auswählen

#define ECHO_PIN 5
#define TRIGGER_PIN 0
#define SCHALLGESCHWINDIGKEIT 0.0343

void setup() {
  // put your setup code here, to run once:
  pinMode(ECHO_PIN, INPUT);
  pinMode(TRIGGER_PIN, OUTPUT);
  Serial.begin(57600);
}

float MissEntfernungMitUltraschall()
{   digitalWrite(TRIGGER_PIN, LOW);
    delayMicroseconds(3);
    digitalWrite(TRIGGER_PIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIGGER_PIN, LOW);
    int pulsdauer = pulseIn(ECHO_PIN, HIGH);
    float entfernung = (pulsdauer*SCHALLGESCHWINDIGKEIT) / 2;
    Serial.print("Die Entfernung beträgt: ");
    Serial.print(entfernung);
    Serial.println(" cm");
}

void loop() {
  // put your main code here, to run repeatedly:
  MissEntfernungMitUltraschall();
  delay(1000);

}
Gruß Axel

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 06.08.2017, 17:46

Hi,

wie versprochen anbei Beschreibung des Projektes.

Zuerst nochmals der Grundaufbau:
Grundaufbau.JPG
hier die Komponenten:
Ultraschall.JPG
Die Installation Wemos und IDE ist hier gut beschrieben.
http://rozek.droppages.com/ESP8266_de/WeMos_D1_mini_de

Jetzt das Programm im Wemos

Code: Alles auswählen

/*
Füllstandskontrolle
==============================================================
Autor:.................: AFi
Erstellt...............: 5.8.2017
Version................: 6

Wemos verbindet sich mit dem definierten WLAN als Server und
der Haussteuerung (EE HPCL) als Client

Hardware: WeMos D1 mini (oder Clone)
          Ultraschall Sensor HC-SR04
==============================================================
*/
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WebServer.h>
#define ECHO_PIN 4                                                //ACHTUNG D2!!!!
#define TRIGGER_PIN 2                                             //ACHTUNG D4!!!!
#define SCHALLGESCHWINDIGKEIT 0.343                               //343 m/s = 0,343 mm/µs

//Netzwerkeinstellungen und Variablen Definition
const char* ssid = ".................";                                 //SSID des vorhandenen WLANs
const char* password = "..................";                        //Passwort für das vorhandene WLAN
IPAddress gateway(999,999,999,9);                                 //IP-Adresse des WLAN-Gateways
IPAddress subnet(999,999,999,9);                                  //Subnetmask
IPAddress ip(999,999,999,99);                                     //feste IP-Adresse für den WeMos
const char* host = "999.999.999.99";                              //IP-Adresse der CCU (Haussteuerung)
ESP8266WebServer server(99);                                      //Webserver initialisieren auf Port 80
String SendeURL = "";                                             //Übergabe URL an CCU (Haussteuerung)
unsigned long deltaMessungSekunden = 10;                          //Zeitintervall (Sekunden) nachdem eine Messung erfolgt
float h_Tonne = 1000;                                             //Höhe Tonne, bzw. max Abstand Sensor bis Boden
String ErgebnisMeldung;                                           //Ergebnismeldung bei Sendung Daten an URL
unsigned long deltaMeldungSekunden = 3600;                        //Zeitintervall (Sekunden) nachdem eine Meldung an CCU (Haussteuerung) erfolgt; 0 nie
float DeltaLevel = 40;                                            //Level Änderung bei der eine Meldung an CCU erfolgt in mm; 0 nie
float LevelCCU;                                                   //Level der an CCU gesendet wird
float Level;                                                      //Level aus Messung
unsigned long jetztMillis = 0;                                    //Variable Zeit für Vergleichsabfragen
unsigned long deltaMessungMillis = deltaMessungSekunden * 1000;   //Umrechnung Sekunden in Millisekunden
unsigned long letzteMessungMillis = 0;
unsigned long deltaMeldungMillis = deltaMeldungSekunden * 1000;
unsigned long letzteMeldungMillis = 0;
String ZeitStempel() {                                            //Ablaufzeit / Betriebszeit als hh:mm:ss
  static char stempel[10];
  int lfdStunden = millis() / 3600000;
  int lfdMinuten = millis() / 60000 - lfdStunden * 60;
  int lfdSekunden = millis() / 1000 - lfdStunden * 3600 - lfdMinuten * 60;
  sprintf (stempel, "%02d:%02d:%02d", lfdStunden,lfdMinuten,lfdSekunden);
  return stempel;
}

void setup() {
  pinMode(ECHO_PIN, INPUT);
  pinMode(TRIGGER_PIN, OUTPUT);
  Serial.begin(115200);
  Serial.println("");
  Serial.println("==================================");
  Serial.println("WeMos D1 mini Füllstandsmessung");
  Serial.println("==================================");

  //WLAN-Verbindung aufbauen
  WiFi.config(ip, gateway, subnet);
  WiFi.begin(ssid, password);
  Serial.print("Verbindungsaufbau....");
  //Verbindungsaufbau abwarten
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(200);
    Serial.print(".");
  }
  Serial.println(" erfolgreich!");
  Serial.println("");
  Serial.print("Verbunden mit: ");
  Serial.println(ssid);
  Serial.print("Signalstärke: ");
  int rssi = WiFi.RSSI();
  Serial.print(rssi);
  Serial.println(" dBm");
  Serial.print("IP-Adresse: ");
  Serial.println(WiFi.localIP());
  Serial.println("");
  
  //HTTP-Server starten
  server.begin();
  Serial.println(ZeitStempel() + " HTTP-Server gestartet");
  Serial.println("");
  //Startwerte für Zeittrigger
  letzteMessungMillis = millis();
  letzteMeldungMillis = millis();
}

// Messung mit Sensor ausführen
void MissEntfernungMitUltraschall() {
    digitalWrite(TRIGGER_PIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIGGER_PIN, LOW);
    int pulsdauer = pulseIn(ECHO_PIN, HIGH);
    //Abfrage ob Messung erfolgreich oder Störung auf Sensor
    if (isnan(pulsdauer)) {
      Serial.println (ZeitStempel() + " Fehler: Sensor konnte nicht abgefragt werden!!");
      delay(100);
      return;
    }
    letzteMessungMillis = jetztMillis;
    Level = h_Tonne - (pulsdauer*SCHALLGESCHWINDIGKEIT) / 2;
    Serial.println(ZeitStempel() + " Der Füllstand beträgt: " + Level + " mmWS");
}
//Meldung an HPCL (homeputerCL/CCU absetzen
void melde_HPCL() {
  HTTPClient http;
  SendeURL = "http://192.168.188.49/addons/contronics/CLWebI.ccc?SETVARBYNAME&P_004LEVELTONNEARDUINO=";
  SendeURL += Level;
  http.begin(SendeURL);
  int httpCode = http.GET();
  if (httpCode == HTTP_CODE_OK) {
    ErgebnisMeldung = http.getString();
    Serial.println(ZeitStempel() + " Übertragung: " + ErgebnisMeldung);
    LevelCCU = Level;
  }
  else
  {
    Serial.println(ZeitStempel() + " Übertragung: " + httpCode);
  }
  http.end();
}

void loop() 
{
  // auf HTTP-Anfragen warten
  server.handleClient();
  jetztMillis = millis();
  
  // neue Messung falls Zeitintervall erreicht
  if (jetztMillis - letzteMessungMillis > deltaMessungMillis)
  {
    letzteMessungMillis = jetztMillis;
    MissEntfernungMitUltraschall();
  }
  
  // neue Meldung an CCU falls Zeitintervall erreicht
  if ((deltaMeldungMillis != 0) && ((jetztMillis - letzteMeldungMillis) > deltaMeldungMillis))
  {
    Serial.println(ZeitStempel() + " Zeitintervall erreicht");
    letzteMeldungMillis = jetztMillis;
    melde_HPCL();
  }

  // neue Meldung an CCU falls Level den Schwellwert erreicht
  if ((DeltaLevel != 0) && (abs(Level - LevelCCU) >= DeltaLevel))
  {
    Serial.println(ZeitStempel() + " Leveländerung erreicht");
    LevelCCU = Level;
    melde_HPCL();
  }
}
In HPCL ist ein virtuelles Objekt vom Typ kapazitiver Füllstandssensor (HM-Sen-Wa-Od) angelegt, um das Feld im Makro "ausführen bei Empfang" zu haben und hier läuft folgendes Makro ab (seit heute):

Code: Alles auswählen

//Erstellt am: 06.08.2017
//Version: 1
//Funktion: Befüllung Tonne bei Niedrigstand
//Bemerkung:
//Magnetventil1 = Entnahme Tonne
//Magnetventil2 = Befüllung Tonne


//===================================================================
// Tonne füllen
//===================================================================
Wenn K_004GartenBewaesserung_AM = 1 und K_004GartenBewaesserung <>1 und P_004LevelTonneArduino <= C_015LevelSwitchUnten und (Uhrzeit zwischen "17:00:00" und "21:00:00") dann
	K_023HuetteMagnetventile1:=1
	warte("00:00:10")
	K_023HuetteMagnetventile2:=1
	warte("00:00:10")
	K_004GartenBewaesserung:=1
endewenn
//===================================================================
// Tonne füllen beenden
//===================================================================
Wenn K_004GartenBewaesserung_AM = 1 und K_004GartenBewaesserung <>1 und P_004LevelTonneArduino >= C_016LevelSwitchMax und (Uhrzeit zwischen "17:00:00" und "21:30:00") dann
	K_004GartenBewaesserung:=0
	warte("00:00:05")
	K_023HuetteMagnetventile1:=0
	warte("00:00:05")
	K_023HuetteMagnetventile2:=0
endewenn
K_004GartenBewaesserung_AM ist ein Schalter "Auto/Manuell" -> Auto Steuerung läuft, Manuell keine Steuerung aktiv
K_004GartenBewaesserung ist ein Schalter Pumpe ein/aus
P_004LevelTonneArduino ist die Füllstandsmessung mittels Arduino
C_016LevelSwitchMax Maximal gewünschter Füllstand im Dialog wählbar
C_015LevelSwitchUnten Minimal gewünschter Füllstand im Dialog wählbar


Hoffe habe nichts vergessen.

Gruß Axel

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 19.08.2017, 20:56

Hi,

melde mich zum einen um zu berichten und zum anderen fehlt mir noch eine Info zu meinem Glück. Da ich nicht zu Hause bin, fehlt mir die komplette Möglichkeit zum Test.
Nachdem ich die Füllstandsmessung mit dem Wemos D1 mini und einem Ultraschall Sensor HC-SR04 realisiert habe und die Steuerung der Pumpe, Magnetventile und Beleuchtung via Homematic Schaltarktoren bereits vorhanden waren, hab ich mir überlegt, warum nicht alles via Wemos und Relais.
Der Code im Wemos funktioniert soweit (s. unten):
- die Meldungen des Füllstands landen in HPCL
- die Befehle zum Start der Pumpe und Öffnung der Ventile (derzeit prüfbar über Relais, den Baukasten habe ich bei mir)
funktionieren via I-Explorer.

Die Befehlsfolge aus HPCL ist mir leider nicht bekannt, habe derzeit (s.unten) den URL direkt eingegeben, bei der Compilierung kam kein Fehler. Habe auch einiges über Getsite gelesen, soll aber nicht der Hit sein.

Derzeitige Programmierung HPCL (nicht getestet, nur kompiliert

Code: Alles auswählen

//===================================================================
// Tonne füllen
// Befüllen der Tonne bei min-Stand bis max-Stand
// aufgerufen von VirtSensor_LevelTonne
//===================================================================
//Füllung starten
Wenn Virt_01_BewaessGarten_MA = 1 und Virt_01_Pumpe <>1 und VirtSensor_LevelTonne <= Anz_LevelSwitchUnten und (Uhrzeit zwischen "17:00:00" und "21:00:00") dann
	http://999.999.999.99/addons/contronics/CLWebI.ccc?SETVARBYNAME&BRAUN_MV_ANSAUGSTUTZEN_AUF
	Virt_01_MagnetvAnsaugst:=1
	http://999.999.999.99/addons/contronics/CLWebI.ccc?SETVARBYNAME&ORANGE_MV_ZURTONNE_AUF
	Virt_01_MagnetvDruckst:=1
	warte("00:00:10")
	http://999.999.999.99/addons/contronics/CLWebI.ccc?SETVARBYNAME&GELB_WAPUMPE_AN
	Virt_01_Pumpe:=1
	warte("00:0010")
	http://999.999.999.99/addons/contronics/CLWebI.ccc?SETVARBYNAME&BRAUN_MV_ANSAUGSTUTZEN_ZU
	Virt_01_MagnetvAnsaugst:=0
endewenn
//Füllung beenden
Wenn Virt_01_BewaessGarten_MA = 1 und VirtSensor_LevelTonne >= Anz_LevelSwitchMax und (Uhrzeit zwischen "17:00:00" und "21:30:00") dann
	http://999.999.999.99/addons/contronics/CLWebI.ccc?SETVARBYNAME&GELB_WAPUMPE_AUS
	Virt_01_Pumpe:=0
	warte("00:00:10")
	http://999.999.999.99/addons/contronics/CLWebI.ccc?SETVARBYNAME&BRAUN_MV_ANSAUGSTUTZEN_ZU
	Virt_01_MagnetvAnsaugst:=0
	http://999.999.999.99/addons/contronics/CLWebI.ccc?SETVARBYNAME&ORANGE_MV_ZURTONNE_ZU
	Virt_01_MagnetvDruckst:=0
endewenn


Derzeitiger Programmstand Wemos, getestet und funktionstüchtig

Code: Alles auswählen

/*
Steuerung im Gartenhaus
==============================================================
Autor:.................: AFi
Erstellt...............: 16.8.2017
Version................: 1

Wemos verbindet sich mit dem definierten WLAN als Server und
der Haussteuerung (EE HPCL) als Client

Hardware: WeMos D1 mini (oder Clone)
          5 Relais Shield 10A 220V
          Ultraschall Sensor; HC-SR04
==============================================================
*/
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WebServer.h>
#define ECHO_PIN 4                                                //ACHTUNG D2!!!!
#define TRIGGER_PIN 2                                             //ACHTUNG D4!!!!
#define SCHALLGESCHWINDIGKEIT 0.343                               //343 m/s = 0,343 mm/µs
#define braun_MV_Ansaugstutzen 5                               //ACHTUNG D1!!!!; Magnetventil Ansaugstutzen
#define orange_MV_ZurTonne 13                                  //ACHTUNG D7!!!!; Magnetventil zur Tonne
#define gelb_WaPumpe 12                                        //Achtung D6!!!!; Wasserpumpe
#define gruen_LichtGarten 14                                   //Achtung D5!!!!; Licht Garten


//Netzwerkeinstellungen und Variablen Definition
const char* ssid = ".......";                                 //SSID des vorhandenen WLANs
const char* password = ".........";                        //Passwort für das vorhandene WLAN
IPAddress gateway(999,999,9,9);                                 //IP-Adresse des WLAN-Gateways
IPAddress subnet(999,999,999,9);                                  //Subnetmask
IPAddress ip(999,999,9,999);                                     //feste IP-Adresse für den WeMos
const char* host = "999.999.9.99";                              //IP-Adresse der CCU (Haussteuerung)
ESP8266WebServer server(99);                                      //Webserver initialisieren auf Port 99
String SendeURL = "";                                             //Übergabe URL an CCU (Haussteuerung)
unsigned long deltaMessungSekunden = 5;                           //Zeitintervall (Sekunden) nachdem eine Messung erfolgt
float h_Tonne = 740;                                              //Höhe Tonne, bzw. max Abstand Sensor bis Boden
String ErgebnisMeldung;                                           //Ergebnismeldung bei Sendung Daten an URL
unsigned long deltaMeldungSekunden = 3600;                        //Zeitintervall (Sekunden) nachdem eine Meldung an CCU (Haussteuerung) erfolgt; 0 nie
float DeltaLevel = 15;                                            //Level Änderung bei der eine Meldung an CCU erfolgt in mm; 0 nie
float LevelCCU;                                                   //Level der an CCU gesendet wird
float Level;                                                      //Level aus Messung
unsigned long jetztMillis = 0;                                    //Variable Zeit für Vergleichsabfragen
unsigned long deltaMessungMillis = deltaMessungSekunden * 1000;   //Umrechnung Sekunden in Millisekunden
unsigned long letzteMessungMillis = 0;
unsigned long deltaMeldungMillis = deltaMeldungSekunden * 1000;
unsigned long letzteMeldungMillis = 0;
char MAC_char[18];                                                // globale Variable mit der Mac-Adresse des WLAN-Moduls

String ZeitStempel() {                                            //Ablaufzeit / Betriebszeit als hh:mm:ss
  static char stempel[10];
  int lfdStunden = millis() / 3600000;
  int lfdMinuten = millis() / 60000 - lfdStunden * 60;
  int lfdSekunden = millis() / 1000 - lfdStunden * 3600 - lfdMinuten * 60;
  sprintf (stempel, "%02d:%02d:%02d", lfdStunden,lfdMinuten,lfdSekunden);
  return stempel;
}

void MV_Ansaugstutzen_auf() {
  digitalWrite(braun_MV_Ansaugstutzen, HIGH);
  server.send(200, "text/plain", "Ansaugstutzen Magnetventil ist auf");
  delay(100);
  Serial.println(ZeitStempel() + " Ansaugstutzen Magnetventil ist auf");
}

void MV_Ansaugstutzen_zu() {
  digitalWrite(braun_MV_Ansaugstutzen, LOW);
  server.send(200, "text/plain", "Ansaugstutzen Magnetventil ist zu");
  delay(100);
  Serial.println(ZeitStempel() + " Ansaugstutzen Magnetventil ist zu");
}

void MV_ZurTonne_auf() {
  digitalWrite(orange_MV_ZurTonne, HIGH);
  server.send(200, "text/plain", "Zur Tonne Magnetventil ist auf");
  delay(100);
  Serial.println(ZeitStempel() + " Zur Tonne Magnetventil ist auf");
}

void MV_ZurTonne_zu() {
  digitalWrite(orange_MV_ZurTonne, LOW);
  server.send(200, "text/plain", "Zur Tonne Magnetventil ist zu");
  delay(100);
  Serial.println(ZeitStempel() + " Zur Tonne Magnetventil ist zu");
}

void WaPumpe_an() {
  digitalWrite(gelb_WaPumpe, HIGH);
  server.send(200, "text/plain", "Wasserpumpe ist an");
  delay(100);
  Serial.println(ZeitStempel() + " Wasserpumpe ist an");
}

void WaPumpe_aus() {
  digitalWrite(gelb_WaPumpe, LOW);
  server.send(200, "text/plain", "Wasserpumpe ist aus");
  delay(100);
  Serial.println(ZeitStempel() + " Wasserpumpe ist aus");
}
//If-Abfrage notwendig, da Wechselschaltung
void LichtGarten_an() {
  if (digitalRead(gruen_LichtGarten) == HIGH) {
    digitalWrite(gruen_LichtGarten, LOW);
  }
  else {
    digitalWrite(gruen_LichtGarten, HIGH);
  }
  server.send(200, "text/plain", "Licht Garten ist an");
  delay(100);
  Serial.println(ZeitStempel() + " Licht Garten ist an");
}
//If-Abfrage notwendig, da Wechselschaltung
void LichtGarten_aus() {
  if (digitalRead(gruen_LichtGarten) == LOW) {
    digitalWrite(gruen_LichtGarten, HIGH);
  }
  else {
    digitalWrite(gruen_LichtGarten, LOW);
  }
  server.send(200, "text/plain", "Licht Garten ist aus");
  delay(100);
  Serial.println(ZeitStempel() + " Licht Garten ist aus");
}

void setup() {
  pinMode(ECHO_PIN, INPUT);
  pinMode(TRIGGER_PIN, OUTPUT); 
  pinMode(braun_MV_Ansaugstutzen, OUTPUT);
  pinMode(orange_MV_ZurTonne, OUTPUT);
  pinMode(gelb_WaPumpe, OUTPUT);
  pinMode(gruen_LichtGarten, OUTPUT);
  Serial.begin(115200);
  Serial.println("");
  Serial.println("==================================");
  Serial.println(" WeMos D1 mini Füllstandsmessung,");
  Serial.println(" Bewaesserung und Lichtsteuerung");
  Serial.println("      G A R T E N H A U S");
  Serial.println("----------------------------------");
  Serial.println("Stand: 16.08.2017     Version: 1.0");
  Serial.println("==================================");

  //WLAN-Verbindung aufbauen
  WiFi.config(ip, gateway, subnet);
  WiFi.begin(ssid, password);
  Serial.print("Verbindungsaufbau....");
  //Verbindungsaufbau abwarten
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(200);
    Serial.print(".");
  }
  Serial.println(" erfolgreich!");
  Serial.println("");
  Serial.print("Verbunden mit: ");
  Serial.println(ssid);
  Serial.print("Signalstärke: ");
  int rssi = WiFi.RSSI();
  Serial.print(rssi);
  Serial.println(" dBm");
  Serial.print("IP-Adresse: ");
  Serial.println(WiFi.localIP());
  Serial.println("");
  
  //HTTP-Server starten
  server.begin();
  Serial.println(ZeitStempel() + " HTTP-Server gestartet");
  Serial.println("");
  //Startwerte für Zeittrigger
  letzteMessungMillis = millis();
  letzteMeldungMillis = millis();

  //MAC-Adresse Arduino auslesen
  uint8_t MAC_array[6];
  // MAC-Adresse ermitteln und ausgeben
  WiFi.macAddress(MAC_array);                               // die 6 Byte der MAC-Adresse auselsen und in ein Array schreiben
  for (int i = 0; i < sizeof(MAC_array); ++i){
    sprintf(MAC_char,"%s%02x:",MAC_char,MAC_array[i]);
  }
  MAC_char[strlen(MAC_char)-1] = '\0';                      // letztes Zeichen ":" kürzen
  // MAC-Adresse steht in der globalen Variable: MAC_char
  Serial.print("MAC-Adresse: ");
  Serial.print(MAC_char);
  Serial.println(" ");

  //HTTP-Anfragen bearbeiten
  server.on("/braun_MV_Ansaugstutzen_auf", MV_Ansaugstutzen_auf);
  server.on("/braun_MV_Ansaugstutzen_zu", MV_Ansaugstutzen_zu);
  server.on("/orange_MV_ZurTonne_auf", MV_ZurTonne_auf);
  server.on("/orange_MV_ZurTonne_zu", MV_ZurTonne_zu);
  server.on("/gelb_WaPumpe_an", WaPumpe_an);
  server.on("/gelb_WaPumpe_aus", WaPumpe_aus);
  server.on("/gruen_LichtGarten_an", LichtGarten_an);
  server.on("/gruen_LichtGarten_aus", LichtGarten_aus);
}
// Messung mit Sensor ausführen
void MissEntfernungMitUltraschall() {
    digitalWrite(TRIGGER_PIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIGGER_PIN, LOW);
    int pulsdauer = pulseIn(ECHO_PIN, HIGH);
    //Abfrage ob Messung erfolgreich oder Störung auf Sensor
    if (isnan(pulsdauer)) {
      Serial.println (ZeitStempel() + " Fehler: Sensor konnte nicht abgefragt werden!!");
      delay(100);
      return;
    }
    letzteMessungMillis = jetztMillis;
    Level = h_Tonne - (pulsdauer*SCHALLGESCHWINDIGKEIT) / 2;
    Serial.println(ZeitStempel() + " Der Füllstand beträgt: " + Level + " mmWS");
}
//Meldung an HPCL (homeputerCL/CCU absetzen
void melde_HPCL() {
  HTTPClient http;
  SendeURL = "http://999.999.999.99/addons/contronics/CLWebI.ccc?SETVARBYNAME&VIRTSENSOR_LEVELTONNE=";
  SendeURL += Level;
  http.begin(SendeURL);
  int httpCode = http.GET();
  if (httpCode == HTTP_CODE_OK) {
    ErgebnisMeldung = http.getString();
    Serial.println(ZeitStempel() + " Übertragung: " + ErgebnisMeldung);
    LevelCCU = Level;
  }
  else
  {
    Serial.println(ZeitStempel() + " Übertragung: " + httpCode);
  }
  http.end();
}

void loop() 
{
  // auf HTTP-Anfragen warten
  server.handleClient();                  //auf HTTP-Anfragen warten
  jetztMillis = millis();
  
  // neue Messung falls Zeitintervall erreicht
  if (jetztMillis - letzteMessungMillis > deltaMessungMillis)
  {
    letzteMessungMillis = jetztMillis;
    MissEntfernungMitUltraschall();
  }
  
  // neue Meldung an CCU falls Zeitintervall erreicht
  if ((deltaMeldungMillis != 0) && ((jetztMillis - letzteMeldungMillis) > deltaMeldungMillis))
  {
    Serial.println(ZeitStempel() + " Zeitintervall erreicht");
    letzteMeldungMillis = jetztMillis;
    melde_HPCL();
  }

  // neue Meldung an CCU falls Level den Schwellwert erreicht
  if ((DeltaLevel != 0) && (abs(Level - LevelCCU) >= DeltaLevel))
  {
    Serial.println(ZeitStempel() + " Leveländerung erreicht");
    LevelCCU = Level;
    melde_HPCL();
  }
}

Familienvater
Beiträge: 7151
Registriert: 31.12.2006, 15:18
System: Alternative CCU (auf Basis OCCU)
Wohnort: Rhein-Main
Danksagung erhalten: 34 Mal

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von Familienvater » 19.08.2017, 23:38

Hi,

Dein HPCL Code würde, wenn die IP-Adresse der CCU angeben wird, Objekte in HPCL schalten, weil Du das Web-Interface von HPCL aufrufst.
Du willst aber den Wemos per html Steuern, der hat aber kein CLWebI-Interface. Du hast im Wemos-Code irgendwelche server.on("/braun_MV_Ansaugstutzen_auf", MV_Ansaugstutzen_auf); "Eventhandler" auf URLs gelegt, und genau diese URLs musst Du aus HPCL aufrufen, damit etwas auf dem Wemos passiert.

Das Problem dabei: Die Getsite-Funktion von HPCL ist alles andere als "prickelnd", die führt über kurz oder lang (aktuell) dazu, das Dein Projekt abstürzt und sich neu startet, vor allem, wenn sie kurz hintereinander mehrfach genutzt werden würde (aktuell, Contronics bessert da hoffentlich zeitnah nach, aber trotzdem bleibt getsite eine für mich eher suspekte Funktion)...

Meine Vorgehensweise wäre, EIN einziger Startbefehl von HPCL an den Wemos wie auch immer, ich würde ggf. ein Shell-Aufruf mit wget machen anstatt getsite zu nutzen, dann startet die Befüllung durch den Wemos, der Wemos meldet ggf. die unterschiedlichen Zustände von Ventilen und Pumpen zurück an HPCL, entscheidet aber Hoheitlich absolut selbst, wann er Ventile öffnet/schließt, und die Pumpe an/abschaltet, da ist HPCL außen vor. HPCL entscheidet nur, wann das Nachfüllen als Vorgang grundsätzlich startet, aber der komplette Vorgang an sich wird autark vom Wemos gesteuert, sonst bist Du wieder in der Falle, das evtl. das Getsite zum Abschalten des Füllvorgangs schiefgeht, und Du solltest dann eh eine "Sicherheitsschaltung" im Wemos einbauen, die bei unklaren Verhältnissen z.B. ein Einschalten der Pumpe verhindert, weil das Fass eh schon voll ist, oder die Pumpe abschaltet, bevor das Fass überläuft.

Der Familienvater

Antworten

Zurück zu „homeputer CL“