Arduino Forum

International => Deutsch => Topic started by: petemanzel on Jun 29, 2016, 12:25 am

Title: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jun 29, 2016, 12:25 am
Hallo!

Ich steuere eine Wasserpumpe für mein Hauswasserwerk mit einem Drucksensor, einem Arduino und einem Relais. Funktioniert soweit eigentlich auch. Nur schaltet sich das ganze nur sehr stotternd aus.

Ich würde gerne bei überschreiten des festgelegten Ausschaltdrucks über eine bestimmte Zeit (z.B. 3 Sek.) den Druck messen und wenn der Druck sich nicht mehr verändert erst ausschalten.

Wie stelle ich das am besten an?

So sieht das Ganze bis her aus:

Code: [Select]

/*
  Meine Pumpensteuerung
 */

int druckSensor = A2;
int pumpenRelais = 8;
byte state = 0;                
int lastState = 0;

void problem(void) {
  digitalWrite(pumpenRelais, LOW);
}

void setup() {
  
  Serial.begin(9600);
  pinMode (pumpenRelais, OUTPUT);
}

void loop() {
  
 long sensorSumme=0;
 
 #define SAMPLES 200
  
  for (int i=0; i<SAMPLES; i++) // Signal mehrmals messen, ca. 20 Millisekunden lang
  {
    sensorSumme+=analogRead(druckSensor);
  }
  int sensorWert = sensorSumme/SAMPLES; // Mittelwert bilden
   Serial.println(sensorWert);

  if(sensorWert <= 520) state = 0; // Pumpe AN
  if(sensorWert >= 550) state = 1; // Pumpe AUS
  
  if(lastState != state) {
  lastState = state;
    
      switch (state)
      {
      case 0:   // Pumpe Aus
        digitalWrite(pumpenRelais, LOW);
      break;
      
      case 1:   // Pumpe An
        digitalWrite(pumpenRelais, HIGH);
      break;
      
      default:
      problem();
      }
  }
}
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: Scherheinz on Jun 29, 2016, 06:17 am
Du kannst mit millis() eine Zeit ablaufen lassen und dann nochmal messen. Aber deine Schalthysterese 520/550 ist viel zu eng, das wird immer zu Problemen führen. Ein- und Ausschaltpunkt sollten deutlich auseinander liegen.
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jun 29, 2016, 07:26 am
Guten Morgen,

Soll eigentlich auch, meine Schalthysterese war ursprünglich 350/550. Das Problem ist, wenn der Druck abfällt, der Einschaltpunkt erreicht wird und die Pumpe anspringt, dann springt der Druck ganz kurz auf den Abschaltpunkt und die Pumpe hat nicht die Zeit den Druck in der Leitung aufzubauen.

Deshalb soll wenn der Auschaltpunkt erreicht wird für 3 Sek. gemessen werden ob der Druck stabil bleibt und dann erst abgeschaltet werden.

Ich hatte auch an millis() gedacht. Aber wie baue ich das ein?

Danke!
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: buffalo64 on Jun 29, 2016, 07:32 am
Mir ist eine Kleinigkeit aufgefallen: Die schreibst einmal pumpenrelais und einmal pumprelais, ist das beabsichtigt oder ein Tippfehler?

Hast du dir zu millis() schon das Beispiel BlinkWithoutDelay angesehen?
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jun 29, 2016, 07:49 am
Tipfehler!! Danke!

Hab ich geändert!

Ist das korrekt:

Code: [Select]

/*
  Meine Pumpensteuerung
 */

int druckSensor = A2;
int pumpenRelais = 8;
byte state = 0;                 
int lastState = 0;
unsigned long previousMillis = 0;
const long interval = 3000;

void problem(void) {
  digitalWrite(pumpenRelais, LOW);
}

void setup() {
 
  Serial.begin(9600);
  pinMode (pumpenRelais, OUTPUT);
}

void loop() {
 
 long sensorSumme=0;
 
 #define SAMPLES 200
 
  for (int i=0; i<SAMPLES; i++) // Signal mehrmals messen, ca. 20 Millisekunden lang
  {
    sensorSumme+=analogRead(druckSensor);
  }
  int sensorWert = sensorSumme/SAMPLES; // Mittelwert bilden
   Serial.println(sensorWert);

 unsigned long currentMillis = millis();

  if(sensorWert <= 350) state = 0; // Pumpe AN
  if(sensorWert >= 550) {

  if(currentMillis - previousMillis >= interval)
    previousMillis = currentMillis;   

  if(sensorWert >= 550) state = 1; // Pumpe AUS
  }
  if(lastState != state) {
  lastState = state;
   
      switch (state)
      {
      case 0:   // Pumpe Aus
        digitalWrite(pumpenRelais, LOW);
      break;
     
      case 1:   // Pumpe An
        digitalWrite(pumpenRelais, HIGH);
      break;
     
      default:
      problem();
      }
  }
}
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: qualidat on Jun 29, 2016, 09:51 am
Du solltest die Messwerte des Drucksensors im Loop kontinuierlich einlesen und "glätten", dann passiert bei kurzen Impulsen Nichts. Das ginge z.B. mit einem Array aus 5 Foat-Variablen so:

Code: [Select]

loop{
  press[4]=press[3];
  press[3]=press[2];
  press[2]=press[1];
  press[1]=press[0];
  press[0]=aktmess();

  medmess=(press[4]+press[3]+press[2]+press[1]+press[0])/5;

  if (medmess>auschalt_schwelle){ ausschalt();}
  if (medmess<einschalt_schwelle){ einschalt();}
  delay(20);
}

Man nennt sowas "kontinuierliche Mittelwertbildung" ... der gezeigte Code ist nur eine Denkanregung, man kann die Mittelwertbildung auch deutlich länger machen, dann natürlich in einer for-Schleife. Der Unterschied zu deiner Lösung ist, dass nicht das Programm quasi angehalten und mehrfach gemessen wird, sondern nach jeder Messung erneut eine Entscheidung getroffen wird ... find ich "flüssiger". Ein maßvoll eingesetztes delay bewirkt eine kalkulierbare Zyklus- und Integrationszeit.
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jun 29, 2016, 10:44 am
Hallo qualidat!

Dein Vorschlag liest sich sehr gut, überfordert mich gerade aber ein klein wenig.
Ich bin ja aber hier um zu lernen und möchte das sehr gerne versuchen.

Poste später einen Versuch!

Danke!
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: ardubu on Jun 29, 2016, 11:40 am
das machst du schon hier
Code: [Select]
#define SAMPLES 200
 
  for (int i=0; i<SAMPLES; i++) // Signal mehrmals messen, ca. 20 Millisekunden lang
  {
    sensorSumme+=analogRead(druckSensor);
  }
  int sensorWert = sensorSumme/SAMPLES; // Mittelwert bilden
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: ardubu on Jun 29, 2016, 11:58 am
versuch es mal so
Code: [Select]

/*
  Meine Pumpensteuerung
 */

const int druckSensor = A2;
const int pumpenRelais = 8;
bool state = 0;                 
bool lastState = 0;
unsigned long previousMillis = millis();
const int interval = 3000;

void problem(void) {
  digitalWrite(pumpenRelais, LOW);
}

void setup() {
 
  Serial.begin(9600);
  pinMode (pumpenRelais, OUTPUT);
}

void loop() {
 
 long sensorSumme=0;
 
 #define SAMPLES 200
 
  for (int i=0; i<SAMPLES; i++) // Signal mehrmals messen, ca. 20 Millisekunden lang
  {
    sensorSumme+=analogRead(druckSensor);
  }
  int sensorWert = sensorSumme/SAMPLES; // Mittelwert bilden
   Serial.println(sensorWert);

  if(sensorWert <= 350) state = 0; // Pumpe AN

  if(millis() - previousMillis >= interval && sensorWert >= 550)
  {
    previousMillis = millis();   
    state = 1; // Pumpe AUS
  }
  if(lastState != state) {
  lastState = state;
   
      switch (state)
      {
      case 0:   // Pumpe Aus
        digitalWrite(pumpenRelais, LOW);
      break;
     
      case 1:   // Pumpe An
        digitalWrite(pumpenRelais, HIGH);
      break;
     
      default:
      problem();
      }
  }
}
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jun 29, 2016, 06:39 pm
Danke ardubu!

Ich habe jetzt noch eine Ermittlung des Maximaldruckes in das setup eingebaut und entsprechende Variablen angelegt. Ich hab das ganze noch nicht im Einsatz gehabt.

Funktioniert das so eurer Meinung nach?

Code: [Select]

/*
  Meine Pumpensteuerung
 */

const int druckSensor = A2;
const int pumpenRelais = 8;
bool state = 0;                 
bool lastState = 0;
unsigned long previousMillis = millis();
const int interval = 3000;
const int kalibrieren = 30000;

int maxDruck = 0;
int newDruck = 0;

void problem(void) {
  digitalWrite(pumpenRelais, LOW);
}

void setup() {
 
  Serial.begin(9600);
  pinMode (pumpenRelais, OUTPUT);

  digitalWrite(pumpenRelais, LOW);

if(millis() - previousMillis >= kalibrieren)
  {
    newDruck = analogRead(druckSensor);
   
    if(newDruck > maxDruck)
    maxDruck = newDruck;
  }
  digitalWrite(pumpenRelais, HIGH);
}

void loop() {
 
 long sensorSumme=0;

 #define SAMPLES 200
 
  for (int i=0; i<SAMPLES; i++) // Signal mehrmals messen, ca. 20 Millisekunden lang
  {
    sensorSumme+=analogRead(druckSensor);
  }
  int sensorWert = sensorSumme/SAMPLES; // Mittelwert bilden
   Serial.println(sensorWert);

  if(sensorWert <= maxDruck - 100) state = 0; // Pumpe AN

  if(millis() - previousMillis >= interval && sensorWert >= maxDruck)
  {
    previousMillis = millis();   
    state = 1; // Pumpe AUS
  }
  if(lastState != state) {
  lastState = state;
   
      switch (state)
      {
      case 0:   // Pumpe Aus
        digitalWrite(pumpenRelais, LOW);
      break;
     
      case 1:   // Pumpe An
        digitalWrite(pumpenRelais, HIGH);
      break;
     
      default:
      problem();
      }
  }
}
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 04, 2016, 04:47 pm
Das ganze funktioniert immer noch nicht so wie es soll.

Es werden irgendwie nicht die 3000 millis (interval) abgewartet bis sich der druck stabilisiert hat. Was habe ich denn da immer noch falsch?

Danke!
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: michael_x on Jul 04, 2016, 04:56 pm
setup() wird einmal aufgerufen, da liefert millis() zunächst eine 0 zurück.

also ist if(millis() - previousMillis >= kalibrieren)  nicht erfüllt

  digitalWrite(pumpenRelais, HIGH);     wird ausgeführt und setup ist fertig.
Und wie soll es statt dessen sein ?
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 04, 2016, 05:09 pm
setup() wird einmal aufgerufen, da liefert millis() zunächst eine 0 zurück.

also ist if(millis() - previousMillis >= kalibrieren)  nicht erfüllt

  digitalWrite(pumpenRelais, HIGH);     wird ausgeführt und setup ist fertig.
Und wie soll es statt dessen sein ?
In diesem Teil (setup) soll der maximale Wert, der in 30 Sek. gemessen wurde, in die Variable "maxDruck" geschrieben werden.

Dann muss das wohl so:

if(millis() >= kalibrieren)

Richtig?

Der Teil im Loop funktioniert aber auch nicht:

 if(millis() - previousMillis >= interval && sensorWert >= maxDruck)

Danke!
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: Serenifly on Jul 04, 2016, 05:16 pm
In diesem Teil (setup) soll der maximale Wert, der in 30 Sek. gemessen wurde, in die Variable "maxDruck" geschrieben werden.
Dann schaue mal nach was "if" genau macht und wie oben gesagt wie oft setup() ausgeführt wird
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 04, 2016, 05:35 pm
Ok! "if" möchte gerne durchlaufen. Kann aber nicht weil "setup" nur einmal durchläuft.

Die Ermittlung der Varianle "maxDruck" soll aber nur einmal ausgeführt werden. Deshalb dachte ich eben nicht in  "loop" damit.

Wie kann ich das lösen?
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 04, 2016, 06:00 pm
Ich hab´s gefunden!
https://www.arduino.cc/en/Tutorial/Calibration

Ich werde das jetzt so mal testen.

Code: [Select]

/*
  Meine Pumpensteuerung
 */

const int druckSensor = A2;
const int pumpenRelais = 8;
bool state = 0;                 
bool lastState = 0;
unsigned long previousMillis = millis();
const int interval = 3000;
const int kalibrieren = 30000;

int maxDruck = 0;
int newDruck = 0;

void problem(void) {
  digitalWrite(pumpenRelais, LOW);
}

void setup() {
 
  Serial.begin(9600);
  pinMode (pumpenRelais, OUTPUT);

  digitalWrite(pumpenRelais, LOW);

while (millis() >= kalibrieren)
  {
    newDruck = analogRead(druckSensor);
   
    Serial.println(maxDruck);

    if(newDruck > maxDruck)
    maxDruck = newDruck;
  }
  digitalWrite(pumpenRelais, HIGH);
}

void loop() {
 
 long sensorSumme=0;

 #define SAMPLES 200
 
  for (int i=0; i<SAMPLES; i++) // Signal mehrmals messen, ca. 20 Millisekunden lang
  {
    sensorSumme+=analogRead(druckSensor);
  }
  int sensorWert = sensorSumme/SAMPLES; // Mittelwert bilden
   Serial.println(sensorWert);
   Serial.println(maxDruck);

  if(sensorWert <= maxDruck - 100) state = 0; // Pumpe AN

  if(millis() - previousMillis >= interval && sensorWert >= maxDruck)
  {
    previousMillis = millis();   
    state = 1; // Pumpe AUS
  }
  if(lastState != state) {
  lastState = state;
   
      switch (state)
      {
      case 0:   // Pumpe Aus
        digitalWrite(pumpenRelais, LOW);
      break;
     
      case 1:   // Pumpe An
        digitalWrite(pumpenRelais, HIGH);
      break;
     
      default:
      problem();
      }
  }
}


Kann man da noch was verbessern?
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: Serenifly on Jul 04, 2016, 06:06 pm
Das ist nie wahr!
Code: [Select]

while (millis() >= kalibrieren)


millis() ist am Anfang 0 ist inkrementiert jede Millisekunde.

<= geht vielleicht. Das println() muss da aber weg. So schnell kannst du nicht auf die serielle Schnittstelle schreiben
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: michael_x on Jul 04, 2016, 06:13 pm
Wenn du es umdrehst:   while (millis() < kalibrieren)
dauert setup 30 sek und sammelt in dieser Zeit das Maximum von    analogRead(druckSensor)

Ich würde aber die Serial.println Ausgaben verringern, indem ich sie höchstens in die maxWert-Erkennung einbaue.

Code: [Select]
if(newDruck > maxDruck) {
      maxDruck = newDruck;
      Serial.print(millis()); Serial.print(" : "); Serial.println(maxDruck);
   }


Das kann allerhöchstens 1023 Zeilen geben ;) und du siehst auch, ob 30s kalibrieren nicht völlig überdimensioniert sind
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 04, 2016, 06:24 pm
Wenn du es umdrehst:   while (millis() < kalibrieren)
dauert setup 30 sek und sammelt in dieser Zeit das Maximum von    analogRead(druckSensor)

So hatte ich mir das auch gedacht!

Also: Stecker rein -> Pumpe geht an -> Ermittelt 30 Sek. lang den Maximaldruck -> übergibt den ermittelten maxDruck -> geht über zum Normalbetrieb.

Werde das also jetzt so probieren und mich dann melden und berichten!

Code: [Select]

/*
  Meine Pumpensteuerung
 */

const int druckSensor = A2;
const int pumpenRelais = 8;
bool state = 0;                 
bool lastState = 0;
unsigned long previousMillis = millis();
const int interval = 3000;
const int kalibrieren = 30000;

int maxDruck = 0;
int newDruck = 0;

void problem(void) {
  digitalWrite(pumpenRelais, LOW);
}

void setup() {
 
  Serial.begin(9600);
  pinMode (pumpenRelais, OUTPUT);

  digitalWrite(pumpenRelais, LOW);

while (millis() < kalibrieren)
  {
    newDruck = analogRead(druckSensor);
   
    if(newDruck > maxDruck) {
      maxDruck = newDruck;
      Serial.print(millis); Serial.print(" : "); Serial.println(maxDruck);
   }
  }
  digitalWrite(pumpenRelais, HIGH);
}

void loop() {
 
 long sensorSumme=0;

 #define SAMPLES 200
 
  for (int i=0; i<SAMPLES; i++) // Signal mehrmals messen, ca. 20 Millisekunden lang
  {
    sensorSumme+=analogRead(druckSensor);
  }
  int sensorWert = sensorSumme/SAMPLES; // Mittelwert bilden
   Serial.println(sensorWert);
   Serial.println(maxDruck);

  if(sensorWert <= maxDruck - 100) state = 0; // Pumpe AN

  if(millis() - previousMillis >= interval && sensorWert >= maxDruck)
  {
    previousMillis = millis();   
    state = 1; // Pumpe AUS
  }
  if(lastState != state) {
  lastState = state;
   
      switch (state)
      {
      case 0:   // Pumpe Aus
        digitalWrite(pumpenRelais, LOW);
      break;
     
      case 1:   // Pumpe An
        digitalWrite(pumpenRelais, HIGH);
      break;
     
      default:
      problem();
      }
  }
}
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 04, 2016, 08:13 pm
Bekomme jetzt diese Fehlermeldung:

mioPressControlIntervall.ino: In function 'void setup()':
mioPressControlIntervall:33: error: call of overloaded 'print(long unsigned int (&)())' is ambiguous

Hab die serielle Ausgabe in "setup" jetzt erstmal Auskommentiert.

Setup scheint yu funktionieren.

Die Pumpe geht jetzt aber nicht an bei maxDruck -(minus) 100.
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: Serenifly on Jul 04, 2016, 08:53 pm
Code: [Select]

Serial.print(millis());

Die Klammern fehlen. Ohne Klammer ist es die Adresse der Funktion und die müsste man auf int casten damit man sie drucken kann. Für die reine Adresse meckert der Compiler völlig korrekt an dass eine entsprechende Funktion fehlt, die als Parameter eine Funktion hat die unsigned long zurück gibt und keine Parameter hat.
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 04, 2016, 08:59 pm
Danke Serenifly!

Warum geht die Pumpe jetzt aber nicht an bei unterschreiten von (maxDruck - 100)?
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: agmue on Jul 04, 2016, 09:25 pm
Versuche mal zum Testen:
Code: [Select]
const int interval = 0;Du verwendest Hysterese, Zeitverzögerung und Flanke, da könnte sich was behindern. Nur so eine Idee.
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 04, 2016, 09:47 pm
Hallo agmue,

danke aber leider erfolglos!

Vielleicht hilft es wenn ich erkläre was da passieren soll.

Der Einschaltpunkt soll (maxDruck - 100).

Wenn dann die Pumpe also an ist und der Druck über 3 Sek. (interval = 3000) stabil bei maxDruck liegt, dann erst soll die Pumpe wieder aus gehen.

Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: ElEspanol on Jul 04, 2016, 10:46 pm
Mich würde sowas auch interessieren. Was für ein Sensor verwendest du?
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 04, 2016, 11:03 pm
Hallo ElEspanol.

Ich verwende diesen hier:

http://www.ebay.it/itm/G1-4-inch-5V-0-1-2-MPa-Pressure-Transducer-Sensor-Oil-Fuel-Diesel-Gas-Water-Air-/172243023623?hash=item281a7bf707:g:iWkAAOSw3YNXYh4V
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: ElEspanol on Jul 04, 2016, 11:53 pm
von dem gingen bei mir schon 4 Stück kaputt. brächten nur noch wirre Werte.
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: SkobyMobil on Jul 05, 2016, 12:10 am
Hallo,
warum nimmst Du nicht einfach zwei Drucksensoren- und läßt sie in einem
Fensterdiskriminator laufen?
Meiner Meinung nach würde es die Sache auch "sicherer" machen.
Nur mal so…
Gruß und Spaß
Andreas
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 05, 2016, 07:17 am
Hallo Andreas.

Ich hatte als nächstes an eine Wasserflusssensor gedacht. Mit dem könnte ich dann auch die Pumpe vor Trockenlauf schützen.

Hat niemand eine Idee wieso die Pumpe nicht wieder anspringt?

Danke!
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: qualidat on Jul 05, 2016, 07:38 am
Der grundlegende Fehler ist deine Mittelwertbildung, glaub es doch endlich. Es bringt Nichts, wenn man in einer Schleife, die in 20ms "durch" ist, die Werte einsammelt und mittelt - dann hast du einen Mittelwert über die 20ms - das ist viel zu schnell und folgt damit immer noch den Sprüngen des Sensorsignales ziemlich direkt.

Mein Vorschlag sah vor, jeweils einen Teil des Mittelwertes bei jedem Haupt-Loop dazuzuholen, deshalb dieses "Schieberegister" (siehe meinen Beitrag oben). Wenn also der gesamte Loop mit einem Delay von z.B. 20ms versehen ist, werden nicht in 20ms alle Messwerte gemittelt, sondern alle 20ms kommt ein Teil dazu, DAS ist der entscheidende Unterschied.

Würde man diesen Puffer z.B. 500 Variablen groß machen, dann hättest du einen Mittelwert über eine Sekunde ...
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 05, 2016, 07:50 am
Hallo qualidat!

Ich habe mir in den Referenzen "Arrays" angesehen und auch das "KnightRider" Tutorial.
Aber ich komme da nicht weiter.

Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: slartibartfast on Jul 05, 2016, 08:41 am
Ich beziehe mich mal auf Deinen Sketch in Post#18:

Code: [Select]

 // (...)

  if(sensorWert <= maxDruck - 100) state = 0; // Pumpe AN

  if(millis() - previousMillis >= interval && sensorWert >= maxDruck)
  {
    previousMillis = millis();   
    state = 1; // Pumpe AUS
  }
  if(lastState != state) {
  lastState = state;
   
      switch (state)
      {
      case 0:   // Pumpe Aus
        digitalWrite(pumpenRelais, LOW);
      break;
     
      case 1:   // Pumpe An
        digitalWrite(pumpenRelais, HIGH);
      break;
     
      default:
      problem();
      }
  }
}

Du setzt den Wert von "state" auf 0 und als Kommentar "Pumpe AN"
Nach dem Vergleich von Millis() mit previousMillis setzt Du "state" auf 1 und als Kommentar "Pumpe AUS"
Im anschließenden Switch schaltest Du aber genau entgegen gesetzt.
Und da wunderst Du Dich das die Pumpe nicht ausschaltet?
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 05, 2016, 08:53 am
Ich habe im "switch / case" falsch kommentiert!

digitalWrite(pumpenRelais, LOW); Macht die Pumpe an!

Danke für den Hinweis!
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: ElEspanol on Jul 05, 2016, 08:57 am
Nimm anstatt der Mittelwertbildung einen Running Median mit 31 Werten und schiebe alle 100 ms einen Wert rein.

Oder warte einfach nach dem einschalten der Pumpe 3 Sekunden mit dem Messen und mach dann erst den Median oder Average. Gibt ne schöne Lib für
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: petemanzel on Jul 05, 2016, 09:23 am
Hallo!

"kontinuierliche Mittelwertbildung" hat "qualidat" mir ja auch schon vorgeschlagen. Aber das überfordert mich gerade ein wenig!

Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: SkobyMobil on Jul 05, 2016, 09:51 am
Hallo,
was mir noch auffällt…
Mit was rechnest Du da eigentlich? So wie es aussieht mit einem Wert, der von
A2 geliefert wird.
Dein Sensor hat einen Arbeitsbereich von 0 bis 12bar bei 0,5 bis 4,5v

Dünnes Eis…

bei der Auflösung von 0 bis 1023 sind das dann bei einem AD-Wert von 922 gleich
12 bar und bei einem AD-Wert von 103 dann 0bar.

Bei einer Schalthysterese 520/550 sind das dann 6,11 bis 6,55bar.
Bei einer Schalthysterese 350/550 sind das dann 3,62 bis 6,55bar.

Dünnes Eis Ende...

Ich würde das ganze erst einmal in "bar" umrechnen und dann einmal schauen,
wie genau die Pumpe denn den Druck halten kann.

Die wird einen Druck von z.B. von 3bar ja nicht 100%tig halten können.
Aus dieser Druck-Differenz mußt Du ja erst einmal raus. Dann hat auch der Sensor
eine bestimmte Fehler-Toleranz. Diese mußt Du in Deiner Berechnung mit
einbeziehen.

Wenn Du das schon "samplen" willst, dann mußt Du das in Deinem Arbeitsbereich
machen, der z.B. bei 3 bis 4bar liegt.
Das wäre dann der AD-Wert 308 bis 376.
Das sind 64 AD-Werte die Du erst einmal stabil einfangen mußt. Wenn Du nicht
weißt, was geliefert wird- und auch nicht, was Du brauchst, dann kannst Du mit
Deinen millis() rumhampeln bis das Rohr platzt.
Gruß und Spaß
Andreas
P.S. mal sehen ob das Eis hält...
P.P.S. ein "TrockenLaufSensor" ist eine gute Idee. Schau mal nach, was für
eine ED Deine Pumpe für die Laufzeit hat, vielleicht mußt Du sie nach einer
bestimmten Zeit abschalten.
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: ElEspanol on Jul 05, 2016, 10:07 am
Ich hatte das bereits im Einsatz, aber nach dem 4. Sensor stillgelegt, bis ich was besseres finde.

1. RunningMedian lib ist ideal dafür, weil beim Median Ausreißer eben nicht berücksichtigt werden. Bei Mittelwert schon. Wobei die Lib beides kann.
2. Per z.B. simpleTimer lib machst du alle 100 ms eine Messung und schreibst sie in den Median
3. Damit du überhaupt weisst, um welchen Wertebereich es geht (siehe ein Post vorher), lass dir per Testsketck alle 20ms die Messung seriell ausgeben und logge das mit. Schalte dann die Pumpe ein paarmal an und aus, damit du mehrere Messreihen bekommst.

4. Der Messbereich vom Sensor ist ungeeignet und erschwert das ganze nur.
5. Wenn du die Messreihen hast, ist egal, ob du in bar umrechnest oder die Rohwerte nimmst
6. Passende Hysterese nicht vergessen

Beim Hauswasserwerk bin ich auf einen Durchflusssensor umgestiegen, funktioniert so halbwegs. Dummerweise verengt er den Leitungsquerschnitt von 22 auf 13 mm. Sollte mal einen Bypass dran machen
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: SkobyMobil on Jul 05, 2016, 10:21 am
Hallo,
"ist egal, ob du in bar umrechnest oder die Rohwerte nimmst"

Ich würde das schon in bar oder Wassersäule rechnen und anzeigen.
Wenn er ein Si-Ventil drinne hat das z.B. bei 4bar öffnet- aber knöcheltief
im Wasser steht, dann zeigt der Arduino ihm Max Druck 376 an.
Da kann er dann etwas mit anfangen??
Steht da aber 4 Bar, ist das Aussagekräftig.

Kann sein, das ich das alles überspitzt sehe, aber vor unbeaufsichtigtem
Wasser, Öl und Gas habe ich einen HöllenRespekt.
Gruß und Spaß
Andreas
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: ElEspanol on Jul 05, 2016, 02:19 pm
klar , für die Ausgabe schon in Bar, aber intern würde ich der Einfachheit und schnelligkeit halber mit 16bit int arbeiten
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: agmue on Jul 06, 2016, 06:56 pm
Bekomme jetzt diese Fehlermeldung:

mioPressControlIntervall.ino: In function 'void setup()':
mioPressControlIntervall:33: error: call of overloaded 'print(long unsigned int (&)())' is ambiguous
Da fehlen Klammern:
Code: [Select]
Serial.print(millis()); Serial.print(" : "); Serial.println(maxDruck);
Die Pumpe geht jetzt aber nicht an bei maxDruck -(minus) 100.
Code: [Select]
sensorWert >= maxDruck
kann nicht erreicht werden, denn mehr als maxDruck geht ja nicht.
Code: [Select]
sensorWert >= (maxDruck - 50)
So funktioniert Dein Sketch.
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: SkobyMobil on Jul 07, 2016, 02:33 am
Hallo,
was macht ihr da eigentlich mit eurem "Hauswasserwerk"- wenn es denn eines ist?

Im groben funktioniert das doch so:
Ihr bohrt unsere schöne Erde an, stopft ein Rohr in das Loch, an das Rohr eine
Pumpe, dann ein Rückschlagventil, dann zum Speicher oder zur Brauchwasserstelle?

Der Durchflusssensor gehört doch vor die Pumpe, damit sie nicht trocken läuft?
Nach der Pumpe ein Rückschlagventil damit ein Druck aufgebaut werden kann?
So erzeugt ihr doch einen Arbeitdruck von z.B. 2 bis 4 bar?
Wenn kein Wasser entnommen wird, dann ist der MaxDruck 4 bar in der Anlage.
Wenn jetzt Wasser entnommen wird, dann sinkt dieser Druck langsam auf
unter 2 bar.
Also, weniger als 2 bar Pumpe an- mehr als 4 bar Pumpe aus.
Wenn jetzt eure Pumpen sich "andauernt" ein- und ausschalten, dann stimmt doch
etwas nicht an der Montage oder den Dimensionen eurer Hauswasserwerke??

Es ist doch nicht so, Pumpe an- zack 4 bar. Wasserhahn auf- zack 2 bar?
Oder sehe ich da etwas nicht richtig?
Gruß und Spaß
Andreas
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: agmue on Jul 07, 2016, 07:54 am
Ich bohrt unsere schöne Erde an, ...
Nicht doch, ich nutze Regenwasser  :)  Da wurde nur ein Loch für den Tank gegraben.

Es ist doch nicht so, Pumpe an- zack 4 bar. Wasserhahn auf- zack 2 bar?
Da Wasser nicht komprimierbar ist, verhält sich das bei meiner Tauchdruckpumpe in etwa so. Ein Hauswasserwerk sollte die Zackigkeit durch komprimierbare Luft etwas abmildern. Auch der Hausanschluß fällt von 6 auf ca. 2 bar, wenn ein Wasserhahn geöffnet wird.

Ich habe auf die ursprüngliche Frage, warum der Sketch nicht funktioniert, geantwortet. Hier ist das Forum für Arduino und nicht für Gartenbewässerung oder Toilettenspülungen, denke ich zumindest. Wobei eine Gesamtbetrachtung des Projektes ja durchaus sinnvoll sein kann. :)
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: michael_x on Jul 07, 2016, 09:22 am
Quote
Ich bohrt unsere schöne Erde an, stopft ein Rohr in das Loch, an das Rohr eine
Pumpe, dann ein Rückschlagventil, dann zum Speicher oder zur Brauchwasserstelle?
Wenn tatsächlich "die Erde angebohrt wird" und die Pumpe saugen muss, ist ein Rückschlagventil ganz unten direkt hinter/im Ansaugsieb. Damit der Saugschlauch nicht trocken fällt.
Einfachste Installationen verzichten dann sogar auf das Rückschlagventil hinter der Pumpe und setzen statt dessen den Saugschlauch unter Druck, wenn die Pumpe abschaltet.

Quote
Es ist doch nicht so, Pumpe an- zack 4 bar. Wasserhahn auf- zack 2 bar?
Doch, wenn der Speicher kein Luftpolster hat.

Und auch mit Druckluftpolster: zwischen 3.7 und 4 bar zum Abschalten würde ein Durchfluss-Sensor fast 0 anzeigen.  Da brauchst du auch eine gute Verzögerungszeit, wenn du per Durchfluss-Überwachung einen Trockenlaufschutz machen willst. So kommt es dann doch wieder Richtung Arduino.
Sonst brauchts keinen Durchfluss-Sensor.
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: ElEspanol on Jul 07, 2016, 11:57 am
Idealerweise baut man ein kleines Druckausgleichsgefäss mit Menmbran ein, das glättet die Druckschwankungen etwas.

War früher mit mechanischen Druckschaltern immer dran. Sieht aus, wie so ein runder Ballon.
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: agmue on Jul 08, 2016, 04:07 pm
Hallo,
ich weiß nicht, ob es richtig ist daruf zu antworten. Hier gab es ja schon
welche "auf den Deckel" für Toilettenspülung und Gartenbewässerung…
Also nur kurz.
"Auf den Deckel" gibt es hier höchstens was von Uwe, ich sage nur meine Meinung. Und da ist mir aufgefallen, daß sich der TO schon länger nicht mehr gemeldet hat. Da stelle ich mir die Frage, wieso das so ist. Meine Mutmaßung: Der TO ist ins Bohrloch gefallen oder das Thema hat sich von seiner ursprünglichen Fragestellung zu weit entfernt.

Ich hatte die zweite Möglichkeit vermutet und wollte freundlich auf diesen Umstand aufmerksam machen :)

Weil aber auch meine Hinweise in #39 den TO leider nicht zurückgeholt haben, doch noch was zu dem spannenden Thema Gartenbewässerung (die Toiletten habe ich nicht angeschlossen, da es sich derzeit nicht rechnet).
Wenn tatsächlich "die Erde angebohrt wird" und die Pumpe saugen muss, ist ein Rückschlagventil ganz unten direkt hinter/im Ansaugsieb. Damit der Saugschlauch nicht trocken fällt.
Ist das Loch zu tief, klappt das Saugen nicht mehr, weshalb im Bohrloch eine Tauchdruckpumpe benötigt wird, um für das Hauswasserwerk einen Vordruck zu liefern.

Ich nutze eine vergleichbare Tauchdruckpumpe mit Druckschalter (3,2 bar), Trockenlaufschutz und Schwimmerschalter im Regenwassertank zur Gartenbewässerung. Hahn auf, Wasser läuft. Der Druck reicht auch für einen Hochdruckreiniger. Da habe ich kein schlechtes Gewissen wegen Wasserverschwendung. Wenn der Tank leer ist, was ich erst einmal geschafft habe, warte ich auf den nächsten Regen ;)

Hallo Pete, wie sieht es mit Deinem Sketch aus?
Title: Re: Pumpensteuerung - schalten erst nach zeitablauf
Post by: mirwal on Jul 10, 2016, 10:34 am
if(millis() - previousMillis >= kalibrieren)
wird im Setup teil möglicherweiße nicht durchlaufen, da
millis() - previousMillis zu diesem Zeitraum kleiner 30000 sein dürfte.

im Setup
Code: [Select]

newDruck = analogRead(druckSensor);
if(newDruck > maxDruck)
  maxDruck = newDruck;