Befehl NUR bei der Änderung einer Variable ausführen

Hallo liebe Arduino-Community,

ich hoffe Ihr könnt mir weiterhelfen.

Und zwar habe ich folgendes Problem:

Ich möchte über einen magnetischen Schalter (non latching Hall Switch) ein Relai ansteuern, welches eine Wasserpumpe bedient. Hält man einen Magneten vor den Sensor ist der ausgegebene Wert 0, sonst steht er auf 1.

Wenn ich einen Magneten an den Sensor halte schaltet sich das Relai an und die Pumpe läuft.
Der Code dazu:

#include <Servo.h>




const int servoPin = 11;    //Belegungspin Servo
const int relaisPin = 13;    //Belegungspin Relai für Wasserpumpe
const int hallPin = 2;    //Belegungspin HallSensor
int hallSensorValue = 1;

Servo myservo;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  myservo.attach(servoPin);
  myservo.write(0);
  pinMode(relaisPin, OUTPUT);
  pinMode(hallPin, INPUT);
  digitalWrite(relaisPin,HIGH);  
}

void loop()
{
  myservo.write(0);
  hallSensorValue = 1;
  hallSensorValue = digitalRead(hallPin);
    while (hallSensorValue == 0)
    {
      myservo.write(45);
      delay(1000);
      digitalWrite(relaisPin,LOW);
      delay(2000);
      digitalWrite(relaisPin,HIGH);
      Serial.println("Der Servo wurde auf Position 1 gestellt");
      break;
    }
}

Nun ist es so, dass wenn ich den Magneten vor dem Sensor lasse das Relai immer wieder aufs neue angeschaltet wird, da die Bedingung ja erfüllt wird.

Gibt es eine Möglichkeit bei der if-Funktion die Bedingung auf die Änderung der Variable (von 1 auf 0) zu beziehen und nicht auf den Wert der Variable selbst?

Wenn noch fragen bestehen oder Ihr noch Informationen benötigt um mir weiterhelfen zu können dann meldet euch einfach.
Vielen Dank im voraus.

Hallo

→ studiere dieses Beispiel

(Bitte verwenden Sie Code-Tags </>)

Dann poste bitte mal den kompletten Sketch.

Ist jetzt komplett.

Da sich hallSensorValue in der Schleife nie ändert, wird die Schleife wohl nie oder immer laufen.
Wenn da nicht das break wäre.
Dann frage ich mich aber: Wieso eine Schleife, wenn sie nur einmal durchlaufen werden soll?

Erst auf 1 setzen und unmittelbar daraufhin überschreiben…

#include <TaskMacro.h> // https://forum.arduino.cc/t/projekt-multitasking/399677
#include <Servo.h>


const byte servoPin  = 11;   //Belegungspin Servo
const byte relaisPin = 13;   //Belegungspin Relai für Wasserpumpe
const byte hallPin   =  2;   //Belegungspin HallSensor

const byte stromausfall = false;

Servo myservo;

void pumenSteuerung()
{
  taskBegin();
  myservo.attach(servoPin);
  myservo.write(0);
  pinMode(relaisPin, OUTPUT);
  pinMode(hallPin, INPUT);
  digitalWrite(relaisPin,HIGH);  

  while(not stromausfall)
  {
    taskWaitFor(not digitalRead(hallPin));
    myservo.write(45);
    taskPause(1000);
    digitalWrite(relaisPin,LOW);
    taskPause(2000);
    digitalWrite(relaisPin,HIGH);
    myservo.write(0);
    taskWaitFor(digitalRead(hallPin));
  }
  taskEnd();
}

void setup(){}
void loop() {pumenSteuerung();}

Im Grunde genommen soll es nur einmal ausgeführt werden.
Jedoch soll es wieder ausgeführt werden, wenn ich den Magnet wieder vor den Sensor halte.

  1. Ich halte den Magnet vor den Sensor (Wert springt von 1 auf 0)
  2. Programm wird nur einmal ausgeführt (auch wenn der Magnet noch vor dem Sensor ist)
  3. Magnet wird weggenommen (Wert geht wieder auf 1)
  4. Magnet wieder an den Sensor
  5. Programm soll wieder einmal ausgeführt werden.

Zur Zeit schaltet sich die Pumpe wieder und wieder an wenn ich den Magnet vor den Sensor halte.
Auch wenn ich dein Programm nutze.

Nein!

Wartet darauf, dass der Magnet von dem Sensor weg genommen wird.

Deine 5 Punkte Liste wird komplett und korrekt abgehandelt.

Okay das habe ich verstanden, jedoch ist es so, dass es nicht jedes mal funktioniert.
Manchmal klappt es genau so wie ich es möchte aber wenn ich es dann nochmal teste wird die Pumpe öfters angeschaltet (wie oft ist immer unterschiedlich). Nachdem die pumpe dann nicht mehr angeschaltet wird dreht sich der Servo zurück

Kann es sein, dass deine 5 Punkte Liste noch nicht alle Eventualitäten erfasst?
Noch nicht vollständig ist?

Eigentlich schon.
Was ich mit dem Programm realisieren möchte ist eine automatische Befüllung von Gläsern.

Die Magneten werden unter den Gläsern befestigt.

Nun soll sich, wenn ein Glas auf den Sensor gestellt wird, der Servo drehen, sodass der Hahn über dem Glas ist. Ist der Servo an der richtigen Position wird die Pumpe eingeschaltet und das Glas befüllt. Danach soll der Servo wieder auf die Ausgangspositon fahren.
Am Ende soll es natürlich nicht nur die Möglichkeit geben ein Glas zu befüllen sondern mehrere nacheinander, aber das kommt erst wenn es mit einem Glas funktioniert.

Also: Nein!
Denn es gibt nur ja und nein, in der Digitaltechnik.
Ein “Eigentlich” gibt es da nicht.

Irgendwas tut deine Maschine anders, als du erwartest.
z.B. könnte ich mir vorstellen, dass dein Hallsensor ein wenig “flackert”, also kein klares Signal liefert.

Was sehen Sie mit diesem Code? (Serial Monitor @115200 Bauds)

const byte hallPin = 2;    //Belegungspin HallSensor

void setup() {
  pinMode(hallPin, INPUT);
  Serial.begin(115200);
}

void loop() {
  static byte vorherigerWert = 255;
  byte aktuellerWert = digitalRead(hallPin);
  if (aktuellerWert != vorherigerWert) {
    Serial.print(F("Magnetischen Schalter : "));
    Serial.println((aktuellerWert == LOW) ? F("LOW") : F("HIGH"));
    vorherigerWert = aktuellerWert;
  }
}

→ Sehen Sie Flackern?

Nein ich sehe kein flackern.
Im Monitor steht “Magnetischen Schalter : LOW” wenn ich den Magneten vor den Sensor halte und wenn nicht dann “Magnetischen Schalter : HIGH”.

und Sie sehen nur einmal HIGH oder LOW? Richtig?

Richtig

Das ist gut. Dies vereinfacht die Codierung. Sie müssen sich nicht mit ‘bouncing’ befassen.

Sobald dies ausgelöst wird, benötigen Sie eine einfache Zustandsmaschine. Wie weissen Sie, dass ein Glas voll ist?

Ich habe die Zeit gemessen wie lange die Pumpe eingeschaltet sein muss um das Glas zu füllen.

Sie können ein Programm schreiben, das nur wartet

#include <Servo.h>
Servo servorMotor;

const byte hallPin = 2;           //Belegungspin HallSensor
const byte servoPin = 11;         //Belegungspin Servo
const byte WasserpumpePin = 13;   //Belegungspin Relai für Wasserpumpe

void setup() {
  pinMode(hallPin, INPUT);
  pinMode(WasserpumpePin, OUTPUT);
  digitalWrite(WasserpumpePin, HIGH);
  servorMotor.attach(servoPin);
  servorMotor.write(0);
  Serial.begin(115200);
}

void loop() {
  if (digitalRead(hallPin) == LOW) {
    servorMotor.write(45);
    delay(1000);
    digitalWrite(WasserpumpePin, LOW);
    delay(2000);
    digitalWrite(WasserpumpePin, HIGH);
    delay(1000);
    servorMotor.write(0);
    while (digitalRead(hallPin) == LOW); // aktive Warten; kein flackern
  }
}

Vielen vielen Dank mit dem Code funktioniert es einwandfrei.

:beers: :clinking_glasses:

:slight_smile:

1 Like