#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// LCD Display Initialisierung
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Keypad Initialisierung
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9,8,7,6};
byte colPins[COLS] = {5,4,3, 12};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Pins
const int relayPin = 10;
const int flowSensorPin = 2;
// Variablen
volatile int pulseCount = 0; // Anzahl der Impulse
float calibrationFactor = 0.01; // Kalibrierungsfaktor
float flowRate = 0; // Liter pro Minute
float totalLiters = 0; // Gesamte geflossene Liter
float targetLiters = 0; // Zielmenge
bool relayState = false; // Relaiszustand
bool paused = false; // Pausenstatus
bool inCalibrationMode = false; // Kalibrierungsmodus
unsigned long lastMillis = 0; // Zeitmanagement für LCD-Updates
int debounceTime = 1000; // Debounce-Zeit für lange Tasten
unsigned long keyPressTime = 0; // Zeitpunkt des Tastendrucks
unsigned long lastFlowCalculation = 0; // Zeitpunkt der letzten Berechnung
int pulseCountLastSecond = 0; // Anzahl der Impulse in den letzten 3 Sekunden
// Setup
void setup() {
lcd.init();
lcd.backlight();
lcd.print("System Start...");
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, LOW);
pinMode(flowSensorPin, INPUT);
attachInterrupt(digitalPinToInterrupt(flowSensorPin), pulseCounter, RISING); //Falling wenn normal high und Signal low
delay(2000);
lcd.clear();
}
// Hauptprogramm
void loop() {
char key = keypad.getKey();
if (key) {
handleKey(key);
}
// Flussrate berechnen und anzeigen
if (millis() - lastMillis > 1000) {
lastMillis = millis();
calculateFlow();
updateLCD();
checkRelay();
}
}
// Funktion: Durchflussrate berechnen
void calculateFlow() {
unsigned long currentMillis = millis();
// Wenn mehr als 1 Sekunde vergangen ist
if (currentMillis - lastFlowCalculation >= 1000) {
// Berechne die Durchflussrate basierend auf den Impulsen der letzten 3 Sekunden
flowRate = (pulseCountLastSecond / calibrationFactor) / 3.0; // Liter pro Minute
totalLiters += flowRate / 60.0 * 1.0; // Gesamte Litermenge basierend auf den letzten 3 Sekunden
pulseCountLastSecond = 0; // Zurücksetzen des Impulszählers
lastFlowCalculation = currentMillis; // Zeit der letzten Berechnung speichern
}
}
// Impulszählung, aufgerufen bei jedem Impuls des Flow-Sensors
void pulseCounter() {
pulseCountLastSecond++; // Erhöhe den Impulszähler für die letzten 3 Sekunden
}
// Funktion: LCD aktualisieren
void updateLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Ziel: ");
lcd.print(targetLiters, 0);
lcd.print("L");
lcd.setCursor(0, 1);
lcd.print("");
lcd.print(totalLiters, 0);
lcd.print("L");
lcd.setCursor(8, 1);
lcd.print(flowRate, 0);
lcd.setCursor(11, 1);
lcd.print("L/min");
}
// Funktion: Taste verarbeiten
void handleKey(char key) {
if (key >= '0' && key <= '9') {
if (!inCalibrationMode) {
targetLiters = targetLiters * 10 + (key - '0');
} else {
calibrationFactor = calibrationFactor * 10 + (key - '0');
}
updateLCD();
} else if (key == '#') {
if (relayState && !paused) {
paused = true;
digitalWrite(relayPin, LOW); // Relais ausschalten
} else if (relayState && paused) {
paused = false;
digitalWrite(relayPin, HIGH); // Relais einschalten
} else if (!relayState) {
relayState = true;
paused = false;
digitalWrite(relayPin, HIGH); // Relais einschalten
}
updateLCD();
} else if (key == '*') {
totalLiters = 0;
targetLiters = 0;
updateLCD();
} else if (key == '1' || key == '3') {
if (keyPressTime == 0) {
keyPressTime = millis();
} else if (millis() - keyPressTime > debounceTime) {
inCalibrationMode = true;
calibrationFactor = 0;
lcd.clear();
lcd.print("Kalibrierung");
lcd.setCursor(0, 1);
lcd.print("Faktor: ");
lcd.print(calibrationFactor);
}
}
}
// Funktion: Relais prüfen
void checkRelay() {
if (totalLiters >= targetLiters && relayState && targetLiters>0) {
relayState = false;
paused = false;
digitalWrite(relayPin, LOW);
lcd.clear();
lcd.print("Fertig!");
delay(2000);
lcd.clear();
updateLCD();
}
}