Browse Source

rework to use functions and not a state machine

master
Constantin Fürst 2 years ago
parent
commit
2e578004c7
  1. 248
      zisterne.ino

248
zisterne.ino

@ -20,18 +20,11 @@
4. Aktueller Druck - atmosphärischen Druck = Messdruck
Beispiel: 29810 Pa = 3040 mmH2O = 100% Füllstand
5. Abluftventil öffnen
*/
// Bibliothek für die I2C-Schnittstelle
#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>
// Konstruktor initialisieren
// Ohne Parameter werden Default Werte verwendet
SparkFun_MicroPressure mpr;
// Zuordnung der Ein- Ausgänge
@ -39,8 +32,8 @@ SparkFun_MicroPressure mpr;
#define DA 0 // GPIO0 (Richtung MotorA)
#define PUMPE 4 // GPIO4 (PWM 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 AUS LOW // Pumpe ausschalten
#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 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;
// Kommandos über serielle Schnittstelle
if (Serial.available()) {
char inChar = (char)Serial.read();
if ((inChar == '\r') || (inChar == '\n')) {
@ -188,31 +96,121 @@ void loop() {
digitalWrite(VENTIL, AUF);
}
else if (inputString == "start") {
if (messSchritt == 0) {
Serial.println("Messung gestartet");
messSchritt = 1;
}
Measurement();
}
inputString = "";
} 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()) {
// 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;
}
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);
}
Loading…
Cancel
Save