#include <Wire.h>
#include <Preferences.h>
//#include <RTCVars.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// SerialPrint als Debug
#define DEBUG 1
#if DEBUG == 1
#define debug(x) Serial.print(x)
#define debugg(x, y) Serial.print(x, y)
#define debugln(x) Serial.println(x)
#define debuggln(x, y) Serial.println(x, y)
#else
#define debug(x)
#define debugg(x, y)
#define debugln(x)
#define debugg(x, y)
#endif
// Ultraschall-Sensor
#define US_TRIG 32
#define US_ECHO 34
// Schalter
#define BTN 33
// OLED
# define OLED_Breite 128
# define OLED_Hoehe 64
# define OLED_RESET -1
# define OLED_Adresse 0x3c
Adafruit_SSD1306 OLED(OLED_Breite, OLED_Hoehe, &Wire, OLED_RESET);
// Variablen
int Tank_Laenge = 98; // Tanklänge in cm
int Tank_Breite = 22; // Tankbreite in cm
int Tank_Hoehe = 300; // Tankhöhe in cm
int MessgrenzeSensor = 2; // Korekturwert in cm, um auf 100% Füllung bei Erreichen der Messgrenze zu kommen = minimaler Messwert Sensor
float Tankkapazitaet = (Tank_Laenge*Tank_Breite*Tank_Hoehe) / 1000; // Maximale Tankkapazität in Liter
float FuellstandLiter, FuellstandProzent;
byte FuellstandLED = 0; // Anzahl zu leuchtender LEDs in Abhängigkeit der Tankfüllung
byte OLED_Zeile = 12, OLED_Spalte = 40;
long Startzeit, Zeit_EndeMessung, DauerMessung, DauerDatenausgabe;
// Flash bzw. RTCmemory
Preferences FLASH;
//RTCVars RTCmem;
void FuellstandsMessung() {
digitalWrite(US_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(US_TRIG, LOW);
float Distanz = (pulseIn(US_ECHO, HIGH) / 58);
float Wasserstand = Tank_Hoehe - Distanz + MessgrenzeSensor; // + MessgrenzeSensor, um auf 100 % Füllung (2cm unter Sensor = Überlaufreserve) zu kommen
FuellstandLiter = (Tank_Laenge * Tank_Breite * Wasserstand) / 1000; // Füllstand in Liter berechnen
FuellstandProzent = FuellstandLiter / Tankkapazitaet * 100; // Füllstand in % berechnen
FuellstandLED = map(FuellstandProzent, 0, 100, 1, 16); // Anzahl zu leuchtende LEDs ermitteln
// Füllstand in RTCmemory speichern
// RTCmem.saveToRTC();
// Füllstand in Flash speichern
FLASH.putFloat("FuellLiter", FuellstandLiter);
FLASH.putFloat("FuellProzent", FuellstandProzent);
Zeit_EndeMessung = millis();
DauerMessung = Zeit_EndeMessung - Startzeit;
debug(Distanz);
debug(F(" cm Distanz, "));
debug(FuellstandLiter);
debug(F(" Liter bzw. "));
debug(FuellstandProzent);
debugln(F(" %"));
debug(F("Zeit bis Ende 1. Messung: "));
debug(DauerMessung);
debugln(F(" Millisekunden"));
}
void DatenausgabeOLED() {
OLED.clearDisplay();
OLED.setCursor(0 * OLED_Spalte, 1 * OLED_Zeile);
OLED.print(FuellstandLiter);
OLED.setCursor(1 * OLED_Spalte, 1 * OLED_Zeile);
OLED.print(" L (NEU)");
OLED.setCursor(0 * OLED_Spalte, 2 * OLED_Zeile);
OLED.print(FuellstandProzent);
OLED.setCursor(1 * OLED_Spalte, 2 * OLED_Zeile);
OLED.write(" % (NEU)");
DauerDatenausgabe = millis() - Startzeit;
OLED.setCursor(0 * OLED_Spalte, 3 * OLED_Zeile);
OLED.print(DauerDatenausgabe);
OLED.setCursor(1 * OLED_Spalte, 3 * OLED_Zeile);
OLED.print(" Millisekunden");
OLED.display();
}
void setup() {
Startzeit = millis();
Serial.begin(115200);
debugln("Habe die Ehre!");
FLASH.begin("FuellstandFlash", false);
//RTCmem.registerVar(&FuellstandLiter); // we send a pointer to each of our variables
//RTCmem.registerVar(&FuellstandProzent);
// PINs
pinMode(US_TRIG, OUTPUT);
pinMode(US_ECHO, INPUT);
pinMode(BTN, INPUT);
// OLED initialisieren
if (!OLED.begin(SSD1306_SWITCHCAPVCC, OLED_Adresse)) {
debugln(F("OLED-Initialisierung fehlgeschlagen!"));
} else {
OLED.clearDisplay();
OLED.setTextColor(SSD1306_WHITE);
OLED.setTextSize(1);
OLED.cp437(true); // Codepage437 = Sonderzeichen
}
/*
// Alten Füllstand aus RTCmemory auslesen & auf OLED ausgeben
if (RTCmem.loadFromRTC()){
OLED.setCursor(0 * OLED_Spalte, 1 * OLED_Zeile);
OLED.print(FuellstandLiter);
OLED.setCursor(1 * OLED_Spalte, 1 * OLED_Zeile);
OLED.print(" L (ALT)");
OLED.setCursor(0 * OLED_Spalte, 2 * OLED_Zeile);
OLED.print(FuellstandProzent);
OLED.setCursor(1 * OLED_Spalte, 2 * OLED_Zeile);
OLED.write(" % (ALT)");
OLED.display();
delay(2000);
OLED.clearDisplay();
}else{
FuellstandLiter = 0;
FuellstandProzent = 0;
OLED.setCursor(0 * OLED_Spalte, 1 * OLED_Zeile);
OLED.print("Keine alten Daten...");
OLED.display();
delay(2000);
OLED.clearDisplay();
}
*/
// Alten Füllstand aus Flash auselen & auf OLED ausgeben
FuellstandLiter = FLASH.getFloat("FuellLiter", 0);
OLED.clearDisplay();
OLED.setCursor(0 * OLED_Spalte, 1 * OLED_Zeile);
OLED.print(FuellstandLiter);
OLED.setCursor(1 * OLED_Spalte, 1 * OLED_Zeile);
OLED.print(" L (ALT)");
FuellstandProzent = FLASH.getFloat("FuellProzent", 0);
OLED.setCursor(0 * OLED_Spalte, 2 * OLED_Zeile);
OLED.print(FuellstandProzent);
OLED.setCursor(1 * OLED_Spalte, 2 * OLED_Zeile);
OLED.write(" % (ALT)");
OLED.display();
delay(2000);
OLED.clearDisplay();
// WakeUp konfigurieren
esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 1);
// Messung durchführen
FuellstandsMessung();
// Datenausgabe
DatenausgabeOLED();
delay(2000);
// DeepSleep
esp_deep_sleep_start();
}
void loop() {}