Als nächsten Schritt meines Projekts zur Überwachung des Wasserstands meiner Zisterne, habe ich ein SSD1306 OLED Display ergänzt, das in meiner Garage in der Nähe der Pumpe installiert werden soll. Hier möchte ich die Wasserhöhe und – eines Tages – den Wasserstand anzeigen.

Als Vorarbeiten wird im Wesentlichen der Artikel „Entfernungsmessung auf Basis eines ESP32 und SmartHomeNG“ vorausgesetzt.

Mittlerweile bin ich bei der Messung des Ultraschallsignales des HR-SR04 allerdings auf die Arduino Bibliothek NewPing umgestiegen, die die Messung übernimmt:Als Display kommt ein kleines OLED Display mit SSD 1306 Controller zum Einsatz (https://www.az-delivery.de/products/0-96zolldisplay, ca. 7 Euro).

Das Display wird wie folgt zusätzlich zum HC-SR04 angeschlossen:

Als Bibliothek kommt die „ESP8266 and ESP32 Oled Driver for SSD1306 display“ von Daniel Eichhorn und Fabrice Weinberg in Version 4.0.0 zum Einsatz:

Der angepasst Sourcecode sieht nun wie folgt aus. Es ist dabei zu beachten, dass das Webservices- Plugin inzwischen über die REST Schnittstelle angesteuert wird. Weiterhin sind alle Log-Outputs für den Seriellen Monitor entfernt worden. Sämtliche relevanten Outputs werden jetzt auf dem Display ausgegeben.


#include <HTTPClient.h>
#include <NewPing.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>
#include <Wire.h>
#include "SSD1306.h"

const int triggerPin = 15;   // HC-SR04: Trigger Pin
const int echoPin = 4;       // HC-SR04: Echo Pin
const int sdaPin = 21;       // Display: SDA Pin
const int sclPin = 22;       // Display: SCL Pin
const int sensorRange = 280; // Reichweite (< maximale Reichweite)

// HC-SR04
NewPing sonar(triggerPin, echoPin, sensorRange); // create NewPing instance

// Wifi
char ssid[] = "<wlan_ssid>";     // your network SSID (name)
char pass[] = "<wlan_password>"; // your network password
char host[] = "192.168.178.100"; // ip of service interface in SmartHomeNG
int port = 4321;                 // port of service interface in SmartHomeNG
char cm_item[] = "test.numeric";
int status = WL_IDLE_STATUS;
WiFiClient client;

// Display
SSD1306Wire display(0x3c, sdaPin, sclPin);

void setup() {
  Serial.begin(19200);
  // Init Display
  display.init();
  display.flipScreenVertically();
  // Init Wifi
  initialise_wifi();
}

void loop() {
  delay(50);
  unsigned int result = sonar.ping();
  float cm = sonar.convert_cm(result); //(result/2)/29.1; //

  while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }

  if (cm > 0) {
    if (client.connect(host, port)) {
      HTTPClient http;
      char portStr[12];
      sprintf(portStr, "%d", port);
      char url[128];
      sprintf(url, "http://%s:%s/rest/items/%s", host, portStr, cm_item);
      http.begin(url);
      http.addHeader("Content-Type", "application/json");
      char cmStr[12];
      char cmStrFull[24];
      sprintf(cmStr, "%f", cm);
      sprintf(cmStrFull, "%i cm", (int)cm);
      int httpCode = http.PUT(cmStr);
      String payload = http.getString();
      http.end();

      display.clear();
      display.setFont(ArialMT_Plain_16);
      display.drawString(0, 0, "Wasserstand:");
      display.setFont(ArialMT_Plain_24);
      display.drawString(0, 17, cmStrFull);
      display.display();
    }
  }
  // Wait 5 seconds and do next measurement
  delay(5000);
}

static void initialise_wifi(void) {
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 0, "Setting up wifi...");
  display.display();

  while (status != WL_CONNECTED) {
    display.drawString(0, 11, "Attempting to connect...");
    display.display();
    status = WiFi.begin(ssid, pass);
    delay(10000);
  }
  display.drawString(0, 22, "Connected to wifi!");
  display.display();
  printWifiStatus();
}

void printWifiStatus() {
  IPAddress ip = WiFi.localIP();
  String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
  display.drawString(0, 33, "IP: "+ipStr);
  display.display();
  long rssi = WiFi.RSSI();
  char rssiStr[255];
  sprintf(rssiStr, "RSSI: %d dBm", rssi);
  display.drawString(0, 44, rssiStr);
  display.display();
}

Nach der Initialisierung des Displays in der Methode setup, kann mittels display.drawString(...) Text auf das Display gesendet werden. Der erste Parameter ist dabei die X-, der zweite die Y-Koordinate. Im dritten Parameter wird der String gesetzt. Mit display.display(); werden alle zuvor eingesteuerten Operationen dann wirklich auf dem Display ausgegeben. Ein display.clear(); leert die auf dem Display ausgegebenen Werte, damit neuer Text dargestellt werden kann. Wird kein display.display(); aufgerufen, so wird immer mehr auf das Display geschrieben. Dies kann soweit führen, dass Text über bestehenden Text geschrieben wird.

Dies kann am Beispiel der WLAN-Initialisierung gut gesehen werden. Das Gehäuse ist dabei wieder von Thingiverse bezogen und via 3D Drucker gedruckt worden (https://www.thingiverse.com/thing:2176764):


Nach der Initialisierung wird nun auf dem Display der Abstand angezeigt:

In Teil 3 folgt nun in Kürze noch ein Update zu meiner tatsächlichen Installation in der Zisterne und der Garage. Die Arbeiten sind bereits vollendet und die Werte werden via Kabel in die Garage auf den ESP32 übertragen. Mehr dazu aber in der nächsten Zeit…

(Die in diesem Artikel verwendeten Screenshots und Fotos wurden selber erstellt. Für den Schaltplan wurde das Tool Fritzing verwendet.)


Schreibe einen Kommentar

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