DIY Kondensat-Pumpe – Kondensatpumpe selbst bauen

Da ich vom meinem Heizungskeller einen Schlauch quer durch meinen Wäschekeller für den Ablauf des Kondensats aus dem Kamin liegen hatte, suchte ich eine für mich optimale Lösung um das kontaminierte Wasser abzupumpen.
Die angebotenen Lösungen waren in meinen Augen zu kostenintensiv, weswegen ich mich hinsetzte und eine eigene Lösung entwickelte. Hier nun das Ergebnis.

!!Nachbau wie immer auf eigene Gefahr!!

Ablaufplan

Dieses Bild hat ein leeres Alt-Attribut. Der Dateiname ist Steuerung-Kondensatpumpe-1.png

Erweitert wurde der Ablaufplan durch eine anfängliche Abfrage, ob sich der Füllstand geändert hat.
Ist aber der maximale Füllstand erreicht, läuft die Routine bis entweder der Füllstand nach Abpumpen erreicht oder manuell eingegriffen wird.

Benötigte Bauteile:

  • 1 x ESP8266 (NodeMCU V3)
  • 1 x Netzteil 9V
  • 1 x Netzteil 5V
  • 2 x LED (1 x rot, 1 x grün)
  • 2 x Widerstand 220 Ohm
  • 1 x Ultraschallmodul HC-SR04
  • 1 x Relaismodul
  • 1 x OLED-Display 0,96″
  • 1 x Pumpe (säurebeständig, Kondensat aus Kaminen sind schwefelhaltig)
  • 1 x Kunstoffbox zum Auffangen des Kondensats
  • 3D-Ausdruck Gehäuse (Eigenkonstruktion)
  • 3D-Ausdruck Steg mit Deckel über Box (Eigenkonstruktion)
  • 3D-Ausdruck Gehäuse für Relais-Modul
  • diverse Kabel und Litzen für Stromversorgung und Zusammenbau
  • Teilstück 3-Loch-Streifenrasterplatine

Versuchsaufbau

/*********
  Michael Wiesner
  Complete project details at https://4bastler.de
  Ultraschall-Sensor und Relaismodul 
*********/

//WiFi-Verbindung
#include <ESP8266WiFi.h>  

//Display
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//Zeitserver
#include <NTPClient.h>
#include <WiFiUdp.h>

//WLAN-Daten
const char* ssid = "Deine SSID";
const char* password = "Dein Passwort für das WLAN";

// Web Server Port 80 definieren
WiFiServer server(80);

//Zeitserver
//Zeitverschiebung UTC <-> MEZ (Winterzeit) = 3600 Sekunden (1 Stunde)
//Zeitverschiebung UTC <-> MEZ (Sommerzeit) = 7200 Sekunden (2 Stunden)
const long utcOffsetInSeconds = 3600;
char daysOfTheWeek[7][12] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};

//Zeitserver
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

//Display
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//Variablen
//Variablen Serveraufruf
const char* host = "Hier die IP eurer Steuereinheit einsetzen";

String text1 = "Initialisiere";
String text2 = "Initialisiere";
String textf1 = "Initialisiere";
String textf2 = "Initialisiere"; 
int dlauf1 = 0;
int Zeile1x = 0;
int Zeile1y = 0;
int Zeile2x = 0;
int Zeile2y = 25;
int Zeile3x = 0;
int Zeile3y = 35; 

const int echoPin = 0;  //D3
// const int trigPin = 2;  //D4

const int minDist = 6; //Mindestabstand in cm
const int anzPinMin = 12;  // D6 Anzeige ob Mindestabstand unterschritten

const int maxDist = 12; //Mindestabstand in cm
const int anzPinMax = 13;  // D7 Anzeige ob Maxabstand unterschritten

const int alarmDist = 4; //Mindestabstand in cm
const int anzPinAlarm = 13;  //Anzeige ob Pumpe nicht geschaltet wurde

const int schaltPinPumpe = 15;

long duration;
int distance;
int distanceold = 17;

//Funktionen
int abstandmessen ()
{
  const int trigPin = 2;  //D4
  pinMode(trigPin, OUTPUT);
  
  int abstand = 0;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  abstand = duration * 0.034 / 2;
  return abstand;
}


//Ende Funktionen

void setup()
{
  
  pinMode(echoPin, INPUT);

  //LED-Anzeige
  pinMode(anzPinMin, OUTPUT);
  pinMode(anzPinMax, OUTPUT);

  //Pumpe
  pinMode(schaltPinPumpe, OUTPUT);
  
  Serial.begin(115200);

  digitalWrite(schaltPinPumpe, LOW);
  digitalWrite(anzPinMin, LOW);
   digitalWrite(anzPinMax, HIGH);

   //WLAN verbinden
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  
  //Starten des Webservers
  server.begin();
  Serial.println("Web server running. Waiting for the ESP IP...");
  delay(200);


  //Zeitserver starten
  timeClient.begin();

  // Printing the ESP IP address
  Serial.println(WiFi.localIP());
  timeClient.update();
  
  //Display
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(100);
  display.clearDisplay();

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 25);
  // Display static text
  display.println("Starte");
  display.println("test");
  display.display();
  delay(1500); 
}

void loop()
{
  if (dlauf1 == 0) //Display 1ter Durchlauf
  {
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 10);
      display.display();
      dlauf1 = 1;
      
  }

  //Zeitserver aktualisieren
  timeClient.update();
  display.setCursor(Zeile1x, Zeile1y);
  display.fillRect(0, Zeile1y, 128, 10, BLACK);
  // Display static text
  display.setTextSize(1);
  display.println(timeClient.getFormattedTime()); 
  display.println(WiFi.localIP());
  display.display(); 
  
  distance = abstandmessen();
  Serial.print("Distance: ");
  Serial.println(distance);

  if(distanceold != distance)
  {
    if(distance < minDist)
    {
      //Pumpe an
      digitalWrite(schaltPinPumpe, HIGH);
  
      //Display
      display.setCursor(Zeile3x, Zeile3y);
      display.fillRect(0, Zeile3y, 128, 30, BLACK);
      // Display static text
      display.setTextSize(3);
      display.println(distance); 
      display.display();
      
      digitalWrite(anzPinMin, HIGH);
      digitalWrite(anzPinMax, LOW);
      while(distance < maxDist)
      {
        distance = abstandmessen();
        Serial.print("Distance: ");
        Serial.println(distance);
  
        //Display
        display.setCursor(Zeile3x, Zeile3y);
        display.fillRect(0, Zeile3y, 128, 30, BLACK);
        // Display static text
        display.setTextSize(3);
        display.println(distance); 
        display.display();
        
        //Alarmfunktion
        while(distance<alarmDist)
        {
          distance = abstandmessen();
          Serial.print("Distance: ");
          Serial.println(distance);
          
          //Display
          display.setCursor(Zeile3x, Zeile3y);
          display.fillRect(0, Zeile3y, 128, 30, BLACK);
          // Display static text
          display.setTextSize(3);
          display.println("Alarm"); 
          display.display();
  
          //LED blinken lassen
          digitalWrite(anzPinMin, HIGH);
          delay(500);
          digitalWrite(anzPinMin, LOW);
          delay(300);
  
          //Speicherung Daten
          // We now create a URI for the request
          String url2 = "PfadzumVerarbeitender Daten?var1=Name&distance=";
          url2 += distance;
      
          delay(1000);
          
          Serial.print("Requesting URL: ");
          Serial.println(url2);
      
          //Daten auf Krake speichern
          // Use WiFiClient class to create TCP connections
          WiFiClient client;
          //const int httpPort = 80;
          if (!client.connect(host, 80)) {
          Serial.println("connection failed");
          return;
          }
          
          // This will send the request to the server
          client.print(String("GET ") + url2 + " HTTP/1.1\r\n" +
          "Host: " + host + "\r\n"+
          "Connection: close\r\n\r\n");
          //Ende Speicherung Daten
        }
        
        //Display
        display.setCursor(Zeile3x, Zeile3y);
        display.fillRect(0, Zeile3y, 128, 30, BLACK);
        // Display static text
        display.setTextSize(3);
        display.println(distance); 
        display.display();
  
        //Speicherung Daten
        // We now create a URI for the request
        String url2 = "PfadzumVerarbeitender Daten?var1=Name&distance=";
        url2 += distance;
    
        delay(1000);
        
        Serial.print("Requesting URL: ");
        Serial.println(url2);
    
        //Daten auf Krake speichern
        // Use WiFiClient class to create TCP connections
        WiFiClient client;
        //const int httpPort = 80;
        if (!client.connect(host, 80)) {
        Serial.println("connection failed");
        return;
        }
        
        // This will send the request to the server
        client.print(String("GET ") + url2 + " HTTP/1.1\r\n" +
        "Host: " + host + "\r\n"+
        "Connection: close\r\n\r\n");
        //Ende Speicherung Daten
      }
      //Pumpe aus
      digitalWrite(schaltPinPumpe, LOW);
      digitalWrite(anzPinMin, LOW);
      digitalWrite(anzPinMax, HIGH);
    }
    //Display
      display.setCursor(Zeile3x, Zeile3y);
      display.fillRect(0, Zeile3y, 128, 30, BLACK);
      // Display static text
      display.setTextSize(3);
      display.println(distance); 
      display.display();
  
      //Speicherung Daten
      // We now create a URI for the request
      String url2 = "PfadzumVerarbeitender Daten?var1=Name&distance=";
      url2 += distance;
  
      delay(1000);
      
      Serial.print("Requesting URL: ");
      Serial.println(url2);
  
      //Daten auf Krake speichern
      // Use WiFiClient class to create TCP connections
      WiFiClient client;
      //const int httpPort = 80;
      if (!client.connect(host, 80)) {
      Serial.println("connection failed");
      return;
      }
      
      // This will send the request to the server
      client.print(String("GET ") + url2 + " HTTP/1.1\r\n" +
      "Host: " + host + "\r\n"+
      "Connection: close\r\n\r\n");
      //Ende Speicherung Daten
  
      distanceold = distance;
  }
  
}

Der Quellcode ist eine erste Programmierung und natürlich noch optimierungsbedürftig.
Aber das Wichtige für mich:
Er funktioniert:
Er gibt mir den Füllstand aus und eine Alarmierung, wenn nicht gepumpt wird und der Behälter droht überzulaufen.
Schwefelbelastetes Wasser im Keller ist nicht wirklich wünschenswert.

Die Umsetzung

Steuerung getrennt in 2 Gehäusen
Das Auffangbecken

Das Auffangbecken wird vom Anschluss her definitiv überarbeitet. Die Lüsterklemme wird bei nächster Gelegenheit gegen eine professionelle Lösung ersetzt.

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert