|
@ -20,18 +20,11 @@ |
|
|
4. Aktueller Druck - atmosphärischen Druck = Messdruck |
|
|
4. Aktueller Druck - atmosphärischen Druck = Messdruck |
|
|
Beispiel: 29810 Pa = 3040 mmH2O = 100% Füllstand |
|
|
Beispiel: 29810 Pa = 3040 mmH2O = 100% Füllstand |
|
|
5. Abluftventil öffnen |
|
|
5. Abluftventil öffnen |
|
|
|
|
|
|
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
// Bibliothek für die I2C-Schnittstelle
|
|
|
|
|
|
#include <Wire.h>
|
|
|
#include <Wire.h>
|
|
|
|
|
|
|
|
|
// Bibliothek für den Sensor (Im Bibliotheksverwalter unter "MicroPressure" suchen
|
|
|
|
|
|
// oder aus dem GitHub-Repository https://github.com/sparkfun/SparkFun_MicroPressure_Arduino_Library )
|
|
|
|
|
|
#include <SparkFun_MicroPressure.h>
|
|
|
#include <SparkFun_MicroPressure.h>
|
|
|
|
|
|
|
|
|
// Konstruktor initialisieren
|
|
|
|
|
|
// Ohne Parameter werden Default Werte verwendet
|
|
|
|
|
|
SparkFun_MicroPressure mpr; |
|
|
SparkFun_MicroPressure mpr; |
|
|
|
|
|
|
|
|
// Zuordnung der Ein- Ausgänge
|
|
|
// Zuordnung der Ein- Ausgänge
|
|
@ -39,8 +32,8 @@ SparkFun_MicroPressure mpr; |
|
|
#define DA 0 // GPIO0 (Richtung MotorA)
|
|
|
#define DA 0 // GPIO0 (Richtung MotorA)
|
|
|
#define PUMPE 4 // GPIO4 (PWM MotorB)
|
|
|
#define PUMPE 4 // GPIO4 (PWM MotorB)
|
|
|
#define DB 2 // GPIO2 (Richtung MotorB)
|
|
|
#define DB 2 // GPIO2 (Richtung MotorB)
|
|
|
#define SDA 12 // GPIO12 I2C
|
|
|
|
|
|
#define SCL 13 // GPIO13 I2C
|
|
|
|
|
|
|
|
|
#define SDA 12 // GPIO12 I2C
|
|
|
|
|
|
#define SCL 13 // GPIO13 I2C
|
|
|
#define AUF LOW // Ventil öffnen
|
|
|
#define AUF LOW // Ventil öffnen
|
|
|
#define AUS LOW // Pumpe ausschalten
|
|
|
#define AUS LOW // Pumpe ausschalten
|
|
|
#define ZU HIGH // Ventil schliessen
|
|
|
#define ZU HIGH // Ventil schliessen
|
|
@ -50,115 +43,30 @@ SparkFun_MicroPressure mpr; |
|
|
const int A = 3140; // Grundfläche der Zisterne in cm^2 (d * d * 3,14 / 4)
|
|
|
const int A = 3140; // Grundfläche der Zisterne in cm^2 (d * d * 3,14 / 4)
|
|
|
const int maxFuellhoehe = 3040; // Füllhöhe der Zisterne in mm
|
|
|
const int maxFuellhoehe = 3040; // Füllhöhe der Zisterne in mm
|
|
|
|
|
|
|
|
|
int atmDruck, messDruck, vergleichswert; |
|
|
|
|
|
int messSchritt, wassersaeule; |
|
|
|
|
|
String hoehe = " - - "; |
|
|
|
|
|
String volumen = "- - "; |
|
|
|
|
|
String fuellstand = " - - "; |
|
|
|
|
|
unsigned long messung, messTakt; |
|
|
|
|
|
|
|
|
|
|
|
// **************************************************************************************
|
|
|
|
|
|
// State-Machine Füllstandsmessung
|
|
|
|
|
|
//
|
|
|
|
|
|
void messablauf() { |
|
|
|
|
|
switch (messSchritt) { |
|
|
|
|
|
case 0: // Regelmäßig aktuellen atmosphärischen Druck erfassen
|
|
|
|
|
|
if (!digitalRead(VENTIL) && !digitalRead(PUMPE)) { |
|
|
|
|
|
atmDruck = messDruck; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 1: // Messung gestartet
|
|
|
|
|
|
vergleichswert = messDruck; |
|
|
|
|
|
digitalWrite(VENTIL, ZU); |
|
|
|
|
|
digitalWrite(PUMPE, EIN); |
|
|
|
|
|
messung = millis() + 2000; |
|
|
|
|
|
messSchritt = 2; |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 2: // warten solange Druck steigt
|
|
|
|
|
|
if (messDruck > vergleichswert + 10) { |
|
|
|
|
|
vergleichswert = messDruck; |
|
|
|
|
|
messung = millis() + 1000; |
|
|
|
|
|
} |
|
|
|
|
|
if (wassersaeule > (maxFuellhoehe + 200)) { |
|
|
|
|
|
Serial.println("Fehler: Messleitung verstopft!"); |
|
|
|
|
|
messSchritt = 4; |
|
|
|
|
|
} |
|
|
|
|
|
else if (messung < millis()) { |
|
|
|
|
|
digitalWrite(PUMPE, AUS); |
|
|
|
|
|
messung = millis() + 100; |
|
|
|
|
|
messSchritt = 3; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 3: // Beruhigungszeit abgelaufen, Messwert ermitteln
|
|
|
|
|
|
if (messung < millis()) { |
|
|
|
|
|
hoehe = String(wassersaeule / 10) + "cm"; |
|
|
|
|
|
volumen = String((wassersaeule / 10) * A / 100) + "L"; |
|
|
|
|
|
// Umrechnung Wassersäule in 0 - 100%
|
|
|
|
|
|
fuellstand = String(map(wassersaeule, 0, maxFuellhoehe, 0, 100)) + "%"; |
|
|
|
|
|
Serial.println("Füllhöhe: "+ hoehe); |
|
|
|
|
|
Serial.println("Volumen: " + volumen); |
|
|
|
|
|
Serial.println("Füllstand: " + fuellstand); |
|
|
|
|
|
Serial.println(); |
|
|
|
|
|
messSchritt = 4; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 4: // Ablauf beenden
|
|
|
|
|
|
digitalWrite(VENTIL, AUF); |
|
|
|
|
|
digitalWrite(PUMPE, AUS); |
|
|
|
|
|
messSchritt = 0; |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
|
messSchritt = 0; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void setup() { |
|
|
|
|
|
// Motortreiber-Signale
|
|
|
|
|
|
|
|
|
|
|
|
// Richtung Motor A
|
|
|
|
|
|
pinMode(DA, OUTPUT); |
|
|
|
|
|
digitalWrite(DA, HIGH); |
|
|
|
|
|
// PWM Motor A
|
|
|
|
|
|
pinMode(VENTIL, OUTPUT); |
|
|
|
|
|
digitalWrite(VENTIL, AUF); |
|
|
|
|
|
|
|
|
int atmDruck = 97400; |
|
|
|
|
|
|
|
|
// Richtung Motor B
|
|
|
|
|
|
pinMode(DB, OUTPUT); |
|
|
|
|
|
digitalWrite(DB, HIGH); |
|
|
|
|
|
// PWM Motor B
|
|
|
|
|
|
pinMode(PUMPE, OUTPUT); |
|
|
|
|
|
digitalWrite(PUMPE, AUS); |
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* HELPERS FOR INPUT / OUTPUT |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
Serial.begin(115200); |
|
|
|
|
|
delay(10); |
|
|
|
|
|
Serial.println(); |
|
|
|
|
|
|
|
|
void printMeasurements(const int& pressure) { |
|
|
|
|
|
const int wassersaeule = convertPressureToHeight(currentPressure); |
|
|
|
|
|
|
|
|
// I2C initialisieren mit 400 kHz
|
|
|
|
|
|
Wire.begin(SDA, SCL, 400000); |
|
|
|
|
|
|
|
|
hoehe = String(wassersaeule / 10) + "cm"; |
|
|
|
|
|
volumen = String((wassersaeule / 10) * A / 100) + "L"; |
|
|
|
|
|
// Umrechnung Wassersäule in 0 - 100%
|
|
|
|
|
|
fuellstand = String(map(wassersaeule, 0, maxFuellhoehe, 0, 100)) + "%"; |
|
|
|
|
|
|
|
|
// Drucksensor initialisieren
|
|
|
|
|
|
// Die Default-Adresse des Sensors ist 0x18
|
|
|
|
|
|
// Für andere Adresse oder I2C-Bus: mpr.begin(ADRESS, Wire1)
|
|
|
|
|
|
if(!mpr.begin()) { |
|
|
|
|
|
Serial.println("Keine Verbindung zum Drucksensor."); |
|
|
|
|
|
while(1); |
|
|
|
|
|
|
|
|
if (Serial.available()) { |
|
|
|
|
|
Serial.println("Füllhöhe: "+ hoehe); |
|
|
|
|
|
Serial.println("Volumen: " + volumen); |
|
|
|
|
|
Serial.println("Füllstand: " + fuellstand); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
messTakt = 0; |
|
|
|
|
|
messSchritt = 0; |
|
|
|
|
|
atmDruck = 97400.0; // Augangswert Atmosphärendruck in Pa
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void loop() { |
|
|
|
|
|
|
|
|
void handleSerialInput() { |
|
|
static String inputString; |
|
|
static String inputString; |
|
|
|
|
|
|
|
|
// Kommandos über serielle Schnittstelle
|
|
|
|
|
|
if (Serial.available()) { |
|
|
if (Serial.available()) { |
|
|
char inChar = (char)Serial.read(); |
|
|
char inChar = (char)Serial.read(); |
|
|
if ((inChar == '\r') || (inChar == '\n')) { |
|
|
if ((inChar == '\r') || (inChar == '\n')) { |
|
@ -188,31 +96,121 @@ void loop() { |
|
|
digitalWrite(VENTIL, AUF); |
|
|
digitalWrite(VENTIL, AUF); |
|
|
} |
|
|
} |
|
|
else if (inputString == "start") { |
|
|
else if (inputString == "start") { |
|
|
if (messSchritt == 0) { |
|
|
|
|
|
Serial.println("Messung gestartet"); |
|
|
|
|
|
messSchritt = 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
Measurement(); |
|
|
} |
|
|
} |
|
|
inputString = ""; |
|
|
inputString = ""; |
|
|
} else inputString += inChar; |
|
|
} else inputString += inChar; |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* FUNCTIONS FOR MEASUREMENT |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
// Alle 10 ms Sensorwert auslesen
|
|
|
|
|
|
|
|
|
int getPressureSensorValue() { |
|
|
|
|
|
static int measuredPressure = 0; |
|
|
|
|
|
static unsigned long messTakt = 0; |
|
|
|
|
|
// Messwert in Pascal auslesen und filtern - alle 10ms bei aufruf
|
|
|
if (messTakt < millis()) { |
|
|
if (messTakt < millis()) { |
|
|
// Messwert in Pascal auslesen und filtern
|
|
|
|
|
|
messDruck = ((messDruck * 50) + int(mpr.readPressure(PA))) / 51; |
|
|
|
|
|
// Umrechnung Pa in mmH2O
|
|
|
|
|
|
wassersaeule = (messDruck - atmDruck) * 10197 / 100000; |
|
|
|
|
|
if (wassersaeule < 0) wassersaeule = 0; |
|
|
|
|
|
|
|
|
measuredPressure = ((measuredPressure * 50) + int(mpr.readPressure(PA))) / 51; |
|
|
messTakt = millis() + 10; |
|
|
messTakt = millis() + 10; |
|
|
} |
|
|
} |
|
|
|
|
|
return measuredPressure; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int convertPressureToHeight(const int& pressure) { |
|
|
|
|
|
// Umrechnung Pa in mmH2O
|
|
|
|
|
|
const int wassersaeule = (pressure - atmDruck) * 10197 / 100000; |
|
|
|
|
|
if (wassersaeule < 0) return 0; |
|
|
|
|
|
else return wassersaeule; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int setAtmosphericPressure() { |
|
|
|
|
|
static unsigned long messTakt = 0; |
|
|
|
|
|
if (messTakt < millis()) { |
|
|
|
|
|
if (!digitalRead(VENTIL) && !digitalRead(PUMPE)) { |
|
|
|
|
|
atmDruck = getPressureSensorValue(); |
|
|
|
|
|
} |
|
|
|
|
|
messTakt = millis() + 1000; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Sicherheitsabschaltung der Pumpe bei Überdruck
|
|
|
|
|
|
if ((messSchritt == 0) && (wassersaeule > (maxFuellhoehe + 300))) { |
|
|
|
|
|
digitalWrite(PUMPE, AUS); |
|
|
|
|
|
Serial.println("Überdruck. Messleitung verstopft!"); |
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* MAIN MEASUREMENT ORCHESTRATOR |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
void Measurement() { |
|
|
|
|
|
int oldPressure = getPressureSensorValue(); |
|
|
|
|
|
digitalWrite(VENTIL, ZU); |
|
|
|
|
|
digitalWrite(PUMPE, EIN); |
|
|
|
|
|
delay(500); |
|
|
|
|
|
|
|
|
|
|
|
while (true) { |
|
|
|
|
|
const int currentPressure = getPressureSensorValue(); |
|
|
|
|
|
|
|
|
|
|
|
if (convertPressureToHeight(currentPressure) > (maxFuellhoehe + 200)) { |
|
|
|
|
|
digitalWrite(VENTIL, AUF); |
|
|
|
|
|
digitalWrite(PUMPE, AUS); |
|
|
|
|
|
Serial.println("Fehler: Messleitung verstopft!"); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (currentPressure > oldPressure + 10) { |
|
|
|
|
|
oldPressure = currentPressure; |
|
|
|
|
|
delay(100); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// State-Machine
|
|
|
|
|
|
messablauf(); |
|
|
|
|
|
|
|
|
const int finalPressure = getPressureSensorValue(); |
|
|
|
|
|
|
|
|
|
|
|
digitalWrite(VENTIL, AUF); |
|
|
|
|
|
digitalWrite(PUMPE, AUS); |
|
|
|
|
|
|
|
|
|
|
|
printMeasurements(finalPressure); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* SETUP AND LOOP FOR ARDUINO RUNTIME |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
void setup() { |
|
|
|
|
|
// Richtung Motor A
|
|
|
|
|
|
pinMode(DA, OUTPUT); |
|
|
|
|
|
digitalWrite(DA, HIGH); |
|
|
|
|
|
// PWM Motor A
|
|
|
|
|
|
pinMode(VENTIL, OUTPUT); |
|
|
|
|
|
digitalWrite(VENTIL, AUF); |
|
|
|
|
|
// Richtung Motor B
|
|
|
|
|
|
pinMode(DB, OUTPUT); |
|
|
|
|
|
digitalWrite(DB, HIGH); |
|
|
|
|
|
// PWM Motor B
|
|
|
|
|
|
pinMode(PUMPE, OUTPUT); |
|
|
|
|
|
digitalWrite(PUMPE, AUS); |
|
|
|
|
|
|
|
|
|
|
|
// enable serial console
|
|
|
|
|
|
Serial.begin(115200); |
|
|
|
|
|
delay(10); |
|
|
|
|
|
|
|
|
|
|
|
// I2C initialisieren mit 400 kHz
|
|
|
|
|
|
Wire.begin(SDA, SCL, 400000); |
|
|
|
|
|
|
|
|
|
|
|
// Drucksensor initialisieren
|
|
|
|
|
|
// Die Default-Adresse des Sensors ist 0x18
|
|
|
|
|
|
// Für andere Adresse oder I2C-Bus: mpr.begin(ADRESS, Wire1)
|
|
|
|
|
|
if(!mpr.begin()) { |
|
|
|
|
|
Serial.println("Keine Verbindung zum Drucksensor."); |
|
|
|
|
|
while(1); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void loop() { |
|
|
|
|
|
handleSerialInput(); |
|
|
|
|
|
setAtmosphericPressure(); |
|
|
|
|
|
|
|
|
|
|
|
// ensure valve is open and pump turned off
|
|
|
|
|
|
digitalWrite(VENTIL, AUF); |
|
|
|
|
|
digitalWrite(PUMPE, AUS); |
|
|
} |
|
|
} |