Füllstandsmessung Zisterne mit ESP8266

Das Projekt realisiert die Messung der Füllstandshöhe in der Zisterene mit einem ESP8266 und dem Ultraschallsensor US100. Die Daten werden dann mittels MQTT and FHEM gesendet und in FHM visualisiert.

Die Schaltung gestallet sich recht einfach. Es wird ein ESP8266 ( am besten mit Antennenanschluss) benötigt und ein US100 Ultraschall Sensor.

Verschaltung des ESP8266 mit US100

Der Quellcode

Programmiert wurde mit VisualCode und PlatformIO. Es werden mehrere Messungen durchgeführt und die Ergebnisse gemittelt und über MQTT and FHEM gesendet. Nach erfolgreicher Messung wird der ESP32 in den DeepSleep Modus für ca. 1 Stunden versetzt. In diesem Modus verbraucht er sehr wenig Strom.



/*
 *  This sketch measure the distance from top to the watersurface of the zysterne
 *
 *  
 *  
 *
 */

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <MQTTClient.h>
#include <SoftwareSerial.h>


#define _TEST

#define STAND     "/Zysterne/Stand"
#define TEMP      "/Zysterne/Temperatur"
#define WifiRSSI  "/Zysterne/RSSI"
#define ZQM        "/Zysterne/QM"
#define ZINFO        "/Zysterne/Info"

const char* ssid     = "****";
const char* password = "****";

const char* host = "192.168.xxx.xxx";
 //FHEM Host
int nVal = 0;

// 4294967295 max time
// 1 Second 1000000 -- 60*60* 1000000;
unsigned long sleepTimeS = 4294967295;

long interval = 1000*10;

int nLed = 4;

int trigPin = 5;    //Trig 
int echoPin = 4;    //Echo 

long temperatur = 0;

int nSendState = 0;
int nState = 0;
int nResendCount = 0;

unsigned long previousMillis = 0;
bool bFinish = false;

int nUS100MeasureState = 0;

#ifdef ESP8266
extern "C" {
#include "user_interface.h"
}
#endif



const int US100_TX = 5;
const int US100_RX = 4;

// Instancia nuevo canal serie
SoftwareSerial US100Serial(US100_RX, US100_TX);

MQTTClient mqtt;
WiFiClient net;

#define BAUD 115200

void setup() {
  Serial.begin(9600);
  US100Serial.begin(9600);
  delay(10);

  WiFi.begin(ssid, password);
  mqtt.begin(host, net);
  mqtt.onMessage(messageReceived);

  pinMode(nLed, OUTPUT);

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

 digitalWrite(nLed, LOW);

}

bool ConnectWifi()
{
  Serial.print("Connecting to ");
  Serial.println(ssid);

  int nCount = 0;

  while(WiFi.waitForConnectResult() != WL_CONNECTED)
  {

    if( nCount >= 10  )
      return false;

    WiFi.begin(ssid, password);
    Serial.println("WiFi connection failed. Retry.");
    delay(1000);
    nCount++;
  }

 Serial.println("WiFi connected");
 Serial.println("IP address: ");
 Serial.println(WiFi.localIP());

 Serial.print("RSSI:");
 Serial.println(WiFi.RSSI());
 PrintMqttInfo("IP address: " + String(WiFi.localIP()) );
 PrintMqttInfo("RSSI: " + String(WiFi.RSSI()) );

 return true;

}

//------------------------------------------------------------------------------------------------------------------

void loop()
{

  mqtt.loop();
  if( nState >= 1 && !bFinish )
  {
      SendToFhem();
      return;
  }


 if( bFinish)
 {

  unsigned long currentMillis = millis();

  delay(100);

  if (currentMillis - previousMillis < 2000 )
    return;

  if( nSendState < 4 && nResendCount < 5)
  {
      Serial.println("Resending....");
      nState = 1;
      nSendState = 0;
      bFinish = false;
      nResendCount++;
  }
  else
      CloseAll();

  return ;

 }
  delay(2000);

#ifdef _TEST
  ConnectWifi() ;
#endif

  bool bOk = false;

  int nCount = 10;

  while( !bOk )
  {
    PrintMqttInfo("Reading US100: " + String(nCount));

    int n1 = ReadingUS100();
    PrintMqttInfo("N1: "+String(n1));

    nVal   = ReadingUS100();
    PrintMqttInfo("N2: "+ String(nVal));

    int nDiff = abs(nVal-n1);
    PrintMqttInfo("Diff - "+ String(nDiff));

    if( nDiff < 100 && nUS100MeasureState == 2 )
    {
       PrintMqttInfo("Read finish...");
       bOk = true;
       continue;
    }
    nCount--;
    if( nCount <= 0)
    {
      PrintMqttInfo("Going to deepSleep....");
      mqtt.loop();
      ESP.deepSleep(10000 );
    }

    delay(1000);
 }
  if( ConnectWifi()  )
     nState = 1;// Starts
  else
    CloseAll();

}

//------------------------------------------------------------------------------------------------------

void PrintMqttInfo(String val)
{
  Serial.println(val);
#ifndef _TEST
  return;
#endif

  SendMQTT(ZINFO,val);
}

int ReadingUS100()
{
  int nCount = 2;

  int n = 0;
  for( int i = 0; i < nCount; i++ )
  {
    n += MeasurePingRx();//random(60,105);
    delay(500);
  }
  return  n/nCount;
}

//------------------------------------------------------------------------------------------------------

void CloseAll()
{
  mqtt.disconnect();

  net.stop();
  Serial.println();
  Serial.println("closing connection");
  WiFi.disconnect();
  delay(1000);

  while (WiFi.status() == WL_CONNECTED )
  {
    delay(100);
    Serial.println("Disconnecting..");
  }

  delay(4000);
  //DeepSleep
  ESP.deepSleep(sleepTimeS );

}

bool ConnectMQTT()
{
  if( mqtt.connected() )
    return true;

   Serial.println("Connecting mqtt....");

   while (!mqtt.connect(host))
   {
     Serial.print(".");
     delay(200);
   }
   delay(200);
   mqtt.subscribe(STAND);
   mqtt.subscribe(WifiRSSI);
   mqtt.subscribe(TEMP);
   mqtt.subscribe(ZQM);
#ifdef _TEST
  mqtt.subscribe(ZINFO);
#endif

   return true;
}

//------------------------------------------------------------------------------------------------------------------

bool SendToFhem()
{
  Serial.println("Sending... ");
  switch(nState)
  {
      case 1: SendMQTT(STAND, String(nVal));
        nState++;
        break;

      case 2:
      {
        double qm = (1650 - nVal) * 0.0041547;
        SendMQTT(ZQM, String(qm));
        nState++;
      }
        break;

      case 3:
        SendMQTT(TEMP, String(temperatur));
        nState++;
        break;

      case 4:
          SendMQTT(WifiRSSI, String(WiFi.RSSI()));
          nState++;
          bFinish = true;
          break;
  }
  previousMillis = millis();
  return true;
}

//------------------------------------------------------------------------------------------------------------------
bool SendMQTT(String key,String val)
{
  ConnectMQTT();

  Serial.print(key); Serial.println(val);

  mqtt.publish(key, String(val));
  mqtt.loop();

  return true;
}

//-----------------------------------------------------------------------------------------------------------------------------------------

int MeasurePingRx()
{

    unsigned int HighLen = 0;
    unsigned int LowLen  = 0;
    unsigned int Len_mm  = 0;
    unsigned int temp  = 0;

    Serial.print("Read.... ");

    US100Serial.flush(); 
    US100Serial.write(0x55); 

    delay(1000);
    nUS100MeasureState = 0;

    if(US100Serial.available() >= 2)
    {
        nUS100MeasureState++;
        HighLen = US100Serial.read(); 
        LowLen  = US100Serial.read();
        Len_mm  = HighLen * 256 + LowLen; // Distanz
        if((Len_mm > 1) && (Len_mm < 10000)) // c
        {
            Serial.print("Distancia: ");
            Serial.print(Len_mm, DEC);
            Serial.println(" mm");
            PrintMqttInfo("Distanz: "+ String(Len_mm) + " mm");
        }
    }

    US100Serial.flush(); 
    US100Serial.write(0x50); 

    delay(1000);
    if(US100Serial.available() >= 1) 
    {
        nUS100MeasureState++;
        temp = US100Serial.read(); 
        if((temp > 1) && (temp < 130)) 
        {
            temp -= 45; // corrige offset de 45º
            temperatur = temp;
            Serial.print("Temperatur: ");
            Serial.print(temp, DEC);
            Serial.println(" C.");
            PrintMqttInfo("Temperatur: "+ String(temp,DEC) + " C");
        }
    }

  return Len_mm;

}

//------------------------------------------------------------------------------------------------------------------

void messageReceived(String &topic, String &payload) {
  Serial.print("incoming: ");
  Serial.print(topic);
  Serial.print(" - ");
  Serial.print(payload);
  Serial.println();

  if( topic.compareTo(STAND) == 0 )
      nSendState++;
  else
  if( topic.compareTo(ZQM) == 0 )
      nSendState++;
  else
  if( topic.compareTo(TEMP) == 0 )
    nSendState++;
  else
  if( topic.compareTo(WifiRSSI) == 0 )
      nSendState++;

  Serial.print("State: ");
  Serial.println(nSendState);
}

//------------------------------------------------------------------------------------------------------------------

Schreibe einen Kommentar