Das mit den zwei Schwimmern ist schon klar: unten: einschalten, oben: ausschalten.
Aber dein Code .... :o
ist schon etwas chaotisch.
Ich denke, dein Problem ist nicht mal das Programmieren, sondern die Struktur.
Ich würde das grundsätzlich anders aufbauen:
ohne blockierende While-Schleifen.
Am Anfang der loop beide Schalter abfragen und das Ergebnis in Variable schreiben.
Dann in der loop deine ganzen Zustandsvariablen abfragen und entsprechend agieren.
aber, bevor du anfängst zu codieren, nimm ein Blatt Papier, zeichen erst mal auf, was genau dein Code wann und in welcher Reihenfolge machen soll.
Die Logik mit den Pullups stimmt schon. Er basiert seine ganze Schaltung darauf dass der Eimer nicht voll ist und prüft immer nur das. Der volle Eimer muss irgendwie im else Fall stecken, aber der Code ist so verquer dass ich da auch nicht durch steige.
Der untere Schwimmer ist im gegebenen Code vollkommen überflüssig, das stimmt. Ich vermute mal dass dieser das einschalten der Pumpe steuern soll, tut er aber nicht.
Momentan wird die Pumpe nur dadurch eingeschaltet dass keine Störung vorliegt. Merkwürdige Logik.
Der Code sieht aus als hättest du mal drauf los programmiert ohne dir vorher Gedanken zu machen was du eigentlich steuern willst.
Mach dir erst einmal Gedanken bevor du anfängst zu programmieren. Welche Ereignisse treten ein, und welche Befehle sollen ausgegeben werden?
Ereignisse:
Eimer leer
Eimer voll
Pumpe läuft zu lange
Befehle:
Pumpe an
Pumpe aus
LED an
(-Steuerung stoppen)
Du bringst dich schon damit durcheinander dass du sagst "Wenn beide Schwimmer nicht schwimmen". - Dass der obere Schwimmer nicht schwimmen kann wenn der untere es nicht tut gebietet die Physik, also reicht es den unteren auf nicht schwimmend zu prüfen.
Das muss dann in logische Zusammenhänge verknüpft werden.
Könnte z.b. so aussehen:
int su = 2; // schwimmer unten
int so = 3;// schwimmer oben
int pump = 8; // Pumpe
int led = 9; //Ledpin
int storung = 0;// hilfsvariable
long zeit = 0;
long szeit= 900000;// Sicherheitszeit 15 min
void setup()
{
pinMode (su, INPUT_PULLUP); // Input und pullup
pinMode (so, INPUT_PULLUP);// Input und pullup
pinMode (pump, OUTPUT);
pinMode (led, OUTPUT);
Serial.begin (9600);
}
void loop()
{
delay(50);
//Pumpe
if (digitalRead(su) && !digitalRead(pump)) { //Wenn Eimer bis unten leer und Pumpe aus
digitalWrite(pump, HIGH); //Pumpe an
zeit = millis(); //Einschlatzeitpunkt merken
}
if (!digitalRead(so) && digitalRead(pump)) //Wenn Eimer bis oben voll, schalte Pumpe aus
if ((millis() - szeit ) && digitalRead(pump)) { //Wenn nach abgelaufener Zeit Pumpe immer noch läuft
digitalWrite(led, HIGH); //Gibt Störung aus
digitalWrite(pump, LOW); //Schalte Pumpe ab
while(1) {}; //Halte den Arduino endlos in der Störung fest bis die Reset Taste gedrückt wird.
}
}
Ausser dem genannten Timeout würde ich schon auch den oberen Schalter abfragen, auch wenn der untere „nicht schwimmt“. Und den unteren auch, auch wenn der obere schwimmt.
Dadurch lassen sich Fehlfunktion der Hardware abfangen.
Eingangszustand ist "Voll". Wenn der Schalter su aktiviert wird, springt er in "Pumpen".
Aus Pumpen springt er wieder zu "Voll", wenn Schalter "so" aktiviert ist, oder zu "Fehler" über den Timeout.
Als Code kann das dann in etwa so aussehen:
void loop() {
bool su = digitalread(su_Pin);
bool so = digitalread(so_Pin);
static byte State = 0; // status der Statemachine: Voll:0, Pumpen:1, Fehler:2
switch (State){
case 0: // Status Voll
if (su){ // wenn unterer Pegel erreicht
digitalWrite(Pumpenpin, HIGH); // Pumpe ein
StartZeit = millis(); // Zeit merken
State = 1; // nächster State: Pumpen
}
break;
case 1: // Status Pumpen
if (so){ // wenn oberer Pegel erreicht
digitalWrite(Pumpenpin, LOW); // Pumpe aus
State = 0; // nächster State: Voll
}
if(millis()-Startzeit > timeout){ // Totzeit abgelaufen
digitalWrite(Pumpenpin, LOW); // Pumpe aus
digitalWrite(Fehlerpin, HIGH); // Fehler LED an
State = 2; // nächster Status: Fehler
}
break;
case 2: // Status Fehler
// hier könnte man z.B. eine Reset-Taste einlesen.
break;
default:
}// end switch
}// end loop
guntherb:
Meinst du mich?
Einfach eine Totzeit, damit die Pumpe nicht endlos läuft.
Nein...sorry.
Ich meine den TO. In seinem Sketch fehlt mir einfach die Logik.
Und wenn die Schwimmer wieder oben sind, sollte die Pumpe doch ausschalten, also warum noch die "Totzeit" ?
HotSystems:
Und wenn die Schwimmer wieder oben sind, sollte die Pumpe doch ausschalten, also warum noch die "Totzeit" ?
Könnte mir vorstellen das dies eine Sicherheitsfunktion ist falls der obere Schwimmer defekt sein sollte. So würde ich es aufjedenfall auch machen falls die Pumpe laufen soll, wenn man nicht in der Nähe ist.
bdorer:
Könnte mir vorstellen das dies eine Sicherheitsfunktion ist falls der obere Schwimmer defekt sein sollte. So würde ich es aufjedenfall auch machen falls die Pumpe laufen soll, wenn man nicht in der Nähe ist.
Da könnte ich mir ganz andere Probleme vorstellen, bevor ein Schwimmer defekt geht.
Z.B.
2. Netzteil, welches bei defekt eine Hupe anschaltet oder SMS sendet.
2. Controller, der zusätzlich den Wasserstand prüft.
Wenn er mit einer Wasserpumpe in einen Behälter pumpt, dann ist das offenbar nicht aus der Wasserleitung, denn da brauche ich keine Pumpe, sondern ein Ventil.
Also kann es passieren, dass da wo er das Wasser rauspumpt, auch mal kein Wasser mehr zu holen ist. Dann läuft die Wasserpumpe trocken, was sie in der Regel sehr übel nimmt. Also braucht man auch noch eine Durchflusskontrolle in der Leitung nach der Pumpe, um dann wenn die Pumpe läuft kontrollieren zu können, ob noch Wasser durch die Pumpe läuft. Und wenn man schon einen Durchflusszähler kontrolliert, kann man damit auch gleich sehen ob der Behälter auf jeden Fall schon voll sein müßte. So hat man eine zusätzliche Kontrolle über den Füllstand, wenn der Endschalter nicht mehr geht.
Die Pumplogik sollte sein:
su aktiv, bis so oder timeout zuschlägt. Timeout sollte in Abhängigkeit der tatsächlichen Pumpdauer gewählt werden.
Su und so bilden eine Hysterese
Weitere Logik und evtl. ein Meldesystem um Fehlfunktionen wie Wassermangel im Brunnen, defekte Schwimmerschalter, manuelle Manipulation, etc. ist anzuraten.
Z.B. 2 x timeout hintereinander lässt auf Wassermangel, defekte Pumpe oder oberer Schwimmerschalter schliessen.
da muss dann nur noch die TimeOut Funktion noch mit dazu, und etwas Fehlerbehandlung.
aber das ist ja oft so, dass die eigentliche Funktion recht klein ist, und das Drum Herum viel Platz braucht.