Ausgang bei Ereignis einmalig für bestimmte Zeit schalten

Hallo,
ich bin ganz neu hier und hänge gerade an einer kleinen Aufgabe.

Ich messe mittels HC-SR04 Sensor eine Entfernung. Beim unterschreiten eines bestimmten Wertes (Abstand zum Sensor) wird über Ausgang 2 ein Relaismodul angesteuert, Relais zieht an bis der Wert (Abstand zum Sensor) wieder überschritten ist, dann fällt das Relais wieder ab.

So weit so gut, dies funktioniert schon mal. Anbei der Code. Die LED´s dienen nur zur optischen Erkennung, sind nicht relevant.

int trigger=5;
int echo=4;
long dauer=0;
long entfernung=0;

int hupe=2;

int LEDgruen=8;
int LEDgelb=7;
int LEDrot=6;

void setup()
{
pinMode (trigger, OUTPUT);
pinMode (echo, INPUT);
pinMode (hupe, OUTPUT);
pinMode (LEDgruen, OUTPUT);
pinMode (LEDgelb, OUTPUT);
pinMode (LEDrot, OUTPUT);
}

void loop()
{
digitalWrite(trigger, LOW);
delay(5);
digitalWrite(trigger, HIGH);
delay(10);
digitalWrite(trigger, LOW);
dauer= pulseIn(echo, HIGH);
entfernung = (dauer/2) * 0.03432;

if (entfernung <=50 )
{
digitalWrite (hupe, LOW); // Relaismodul invertiert, zieht bei LOW an!!
digitalWrite (LEDrot, HIGH);
}
else if (entfernung <=75)
{
digitalWrite (LEDgelb, HIGH);
}
else if (entfernung <=90)
{
digitalWrite (LEDgruen, HIGH);
}
else
{
digitalWrite (hupe, HIGH); // Relaismodul invertiert, fällt bei HIGH ab!!
digitalWrite (LEDgelb, LOW);
digitalWrite (LEDrot, LOW);
digitalWrite (LEDgruen, LOW);
}
delay(100);
}

Nun möchte ich aber dass mein Relais bei unterschreiten der Entfernung nur einmal kurz ( z.B. 200ms) anzieht, und dann wieder abfällt. Erst wenn der Abstand vom Sensor den vorgegebenen Wert wieder überschritten hat, darf bei erneuter Annäherung an den Sensor und Unterschreitung des Abstandes das Relais erneut (für 200ms) anziehen.

Ich hoffe das Problem ist verständlich!
Ich komme hierbei irgendwie nicht weiter,

vielleicht könnt ihr mir ja nen Tipp geben, wie dies zu lösen ist!
Würde mich sehr freuen, vielen Dank!

Nö. Aber nen Klassiker.
Was ist denn Dein Relais?
Aahhh - da war was im Code mit Hupe.

Ok...

Also.....
Merker setzen.
Ist Merker gesetzt und vorher auch: nicht wieder auslösen.
Merker löschen, wenn Bedingung nicht erfüllt.

Was mir noch nicht klar ist, welche Entfernungen Du messen willst:

long entfernung=0;

Na dann mal nen Versuch aus der Holen Hand.
ABER!
Der vollkommen ungetestet und wenn Du Deinen Code in Codetags steckst, ist der eindeutig besser lesbar.
Dazu vor der ersten Zeile ein in rechteckigen Klammern gesetztes Wort "code" und am Ende eine einfache Zeile mit in rechteckicgen Klammern gesetztes "/code"

Alternativ: In der ARDUINO-IDE BERARBEITEN - FÜR FORUM KOPIEREN.
Da passiert alles von allein...

So wie hier:

const byte trigger = 5;
const byte echo = 4;
unsigned long dauer = 0;

const byte hupe = 2;

const byte LEDgruen = 8;
const byte LEDgelb = 7;
const byte LEDrot = 6;

void setup()
{
  pinMode (trigger, OUTPUT);
  pinMode (echo, INPUT);
  pinMode (hupe, OUTPUT);
  pinMode (LEDgruen, OUTPUT);
  pinMode (LEDgelb, OUTPUT);
  pinMode (LEDrot, OUTPUT);
}

void loop()
{

  if (getEntfernung() <= 50 )
  {
    digitalWrite (hupe, LOW); // Relaismodul invertiert, zieht bei LOW an!!
    digitalWrite (LEDrot, HIGH);
    merker = false;
  }
  else if (getEntfernung <= 75)
  {
    digitalWrite (LEDgelb, HIGH);
    merker = false;
  }
  else if (getEntfernung <= 90)
  {
    digitalWrite (LEDgruen, HIGH);
    merker = false;
  }
  else if (!merker)
  {
    // Hier löst die Hupe aus, die nicht nachtriggerbar sein soll?
    digitalWrite (hupe, HIGH); // Relaismodul invertiert, fällt bei HIGH ab!!
    digitalWrite (LEDgelb, LOW);
    digitalWrite (LEDrot, LOW);
    digitalWrite (LEDgruen, LOW);
    merker = true;
  }
  delay(100);
  digitalWrite (hupe, LOW);
}

unsigned long getEntfernung()
{
  digitalWrite(trigger, LOW);
  delay(5);
  digitalWrite(trigger, HIGH);
  delay(10);
  digitalWrite(trigger, LOW);
  dauer = pulseIn(echo, HIGH);
  return (dauer / 2) * 0.03432;
}

Hallo my_xy_projekt!

Vielen Dank für die superschnelle Hilfe!
Also die Entfernung welche ich Messen möchte soll <=50 cm sein. Wird der Wert unterschritten soll ausgelöst werden (Hupe).

Ich habe deinen Code mal versucht, da kommt ein Fehler bei
"else if (!merker)"

Fehlermeldung:
`merker´was not declared in this scope.

Vielleicht könntest du mir hierbei nochmal helfen?
Vielen Dank!

Du musst den merker noch als bool definieren.
Das bei den übrigen Definitionen ganz oben im Sketch.

Ja, war ja nur runtertackert...

const byte triggerPin = 5;
const byte echoPin = 4;
const byte hupePin = 2;
bool merker = false;

const byte LEDgruen = 8;
const byte LEDgelb = 7;
const byte LEDrot = 6;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  pinMode (triggerPin, OUTPUT);
  pinMode (echoPin, INPUT);
  pinMode (hupePin, OUTPUT);
  pinMode (LEDgruen, OUTPUT);
  pinMode (LEDgelb, OUTPUT);
  pinMode (LEDrot, OUTPUT);
}

void loop()
{

  if (getEntfernung() <= 50 )
  {
    digitalWrite (hupePin, LOW); // Relaismodul invertiert, zieht bei LOW an!!
    digitalWrite (LEDrot, HIGH);
    merker = false;
  }
  else if (getEntfernung <= 75)
  {
    digitalWrite (LEDgelb, HIGH);
    merker = false;
  }
  else if (getEntfernung <= 90)
  {
    digitalWrite (LEDgruen, HIGH);
    merker = false;
  }
  else if (!merker)
  {
    // Hier löst die Hupe aus, die nicht nachtriggerbar sein soll?
    digitalWrite (hupePin, HIGH); // Relaismodul invertiert, fällt bei HIGH ab!!
    digitalWrite (LEDgelb, LOW);
    digitalWrite (LEDrot, LOW);
    digitalWrite (LEDgruen, LOW);
    merker = true;
  }
  delay(100);
  digitalWrite (hupePin, LOW);
}

unsigned long getEntfernung()
{
  unsigned long dauer = 0;
  const float umrechner = 0.03432;
  digitalWrite(triggerPin, LOW);
  delay(5);
  digitalWrite(triggerPin, HIGH);
  delay(10);
  digitalWrite(triggerPin, LOW);
  dauer = pulseIn(echoPin, HIGH);
  Serial.print(F("errechnete Weite: "));
  Serial.println((dauer / 2) * umrechner);
  return (dauer / 2) * umrechner;
}

Vielen Dank für die Hilfe,
jetzt hab ich schon ein paar Dinge gelernt. Funktioniert leider noch nicht so wie ich es mir vorstelle.

Momentan fällt das Relais (Hupe) bei unterschreiten der Entfernung (50cm) kurz ab. Es sollte aber umgekehrt sein. (Das Relaismodul invertiert, sprich bei LOW zieht es an. Ich könnte nun auch nach nem anderen Relaismodul schauen, aber es sollte ja so auch lösbar sein).

Habe versucht das im Programm umzustellen, komme aber leider noch nicht klar damit.

Und, es funktioniert mit diesem Code nur noch die rote LED (Entfernung <50cm)
Die grüne LED sollte bei <90cm leuchten, die gelbe LED dann bei <75cm.

Irgendwie doch etwas aufwändiger als ich dachte. Naja, ich werde noch viel lernen müssen.

Vielen Dank für die Hilfe, vielleicht fällt euch ja noch was dazu ein :slight_smile: !

Ja.. so isses... Ist nen Klacks.

Ja.

Und auch an Dich der Hinweis, bitte unter DATEI - VOREINSTELLUNGEN - den Haken setzen bei: VOLLSTÄNDIGE AUSGABE BEI KOMPILIERUNG
Und darunter das Feld COMPILER_WARNUNGEN auf ALLE stellen.

Dann kommt u.a. raus:

36:29: warning: ISO C++ forbids comparison between pointer and integer [-fpermissive]
   else if (getEntfernung <= 90)

Und schon wird klar, das nach getEntfernung das "()" fehlt - siehe oben bei 50....

Also nachtragen.
Dann sehen auch wir uns morgen, mit den Änderungen, die Du noch möchtest.

200mS ein Relais ansprechen sehe ich als frommen Wunsch. Das ist unter Umständen zu schnell für ein Relais. Nimm einen Transistor dafür.

Grüße Uwe

Ach hier... ungetestet aber kompiliert fehlerfrei. Wenn ich Deine Aufgabenstellung richtig verstanden habe....

const byte triggerPin = 5;
const byte echoPin = 4;
const byte hupePin = 2;
bool merker = false;
unsigned long startTime; // Merker Wann hat hupen angefangen
unsigned long hupeTime = 500; // Zeit in ms!

const byte LEDgruen = 8;
const byte LEDgelb = 7;
const byte LEDrot = 6;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  pinMode (triggerPin, OUTPUT);
  pinMode (echoPin, INPUT);
  pinMode (hupePin, OUTPUT);
  pinMode (LEDgruen, OUTPUT);
  pinMode (LEDgelb, OUTPUT);
  pinMode (LEDrot, OUTPUT);
}

void loop()
{
  if (getEntfernung() <= 50)
  {
    digitalWrite (LEDrot, HIGH);
    if (!merker)
    {
      digitalWrite (hupePin, LOW); // Relaismodul invertiert, zieht bei LOW an!!
      startTime = millis();
      merker = true;
    }
  }
  else if (getEntfernung() <= 75)
  {
    digitalWrite (LEDgelb, HIGH);
    merker = false;
  }
  else if (getEntfernung() <= 90)
  {
    digitalWrite (LEDgruen, HIGH);
    merker = false;
  }
  else
  {
    digitalWrite (hupePin, HIGH); // Relaismodul invertiert, fällt bei HIGH ab!!
    digitalWrite (LEDgelb, LOW);
    digitalWrite (LEDrot, LOW);
    digitalWrite (LEDgruen, LOW);
    merker = false;
  }
  if (millis() - startTime >= hupeTime)
  {
    digitalWrite (hupePin, HIGH); // Relaismodul invertiert, fällt bei HIGH ab!!
  }
}


unsigned long getEntfernung()
{
  unsigned long dauer = 0;
  const float umrechner = 0.03432;
  digitalWrite(triggerPin, LOW);
  delay(5);
  digitalWrite(triggerPin, HIGH);
  delay(10);
  digitalWrite(triggerPin, LOW);
  dauer = pulseIn(echoPin, HIGH);
  Serial.print(F("errechnete Weite: "));
  Serial.println((dauer / 2) * umrechner);
  return (dauer / 2) * umrechner;
}

Hallo,

vielen, vielen Dank! Der Code passt nun perfekt!!
Ich finde es echt superklasse dass einem (leider noch) sehr ahnungslosen Einsteiger wie mir, mal auf die Schnelle derart unkompliziert und kompetent geholfen wird! :+1:

Ich habe einiges dabei gelernt, und bin absolut motiviert weitere Projekte anzugehen!

Herzlichen Dank!

Hallo uwefed,
vielen Dank für den Hinweis! Habe es ausprobiert, 200ms funktionieren problemlos. Eine Sekunde kann manchmal länger als erwartet sein :slight_smile:

Stell die hupeTime mal auf 10000.
Fahre kurz unter die 50 und nach einer Sekunde kommst wieder zurück.
Hupe geht nicht aus?
Von der Logik her müsste der hier jetzt das Problem beheben.
Wenn ja, schau Dir beide Codes parallel an - dann siehst Du die Logik dahinter.

const byte triggerPin = 5;
const byte echoPin = 4;
const byte hupePin = 2;
bool merker = false;
unsigned long startTime; // Merker Wann hat hupen angefangen
unsigned long hupeTime = 500; // Zeit in ms!

const byte LEDgruen = 8;
const byte LEDgelb = 7;
const byte LEDrot = 6;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  pinMode (triggerPin, OUTPUT);
  pinMode (echoPin, INPUT);
  pinMode (hupePin, OUTPUT);
  pinMode (LEDgruen, OUTPUT);
  pinMode (LEDgelb, OUTPUT);
  pinMode (LEDrot, OUTPUT);
}

void loop()
{
  if (getEntfernung() <= 50)
  {
    digitalWrite (LEDrot, HIGH);
    if (!merker)
    {
      digitalWrite (hupePin, LOW); // Relaismodul invertiert, zieht bei LOW an!!
      startTime = millis();
      merker = true;
    }
  }
  else if (getEntfernung() <= 75)
  {
    digitalWrite (LEDgelb, HIGH);
    merker = false;
  }
  else if (getEntfernung() <= 90)
  {
    digitalWrite (LEDgruen, HIGH);
    merker = false;
  }
  else
  {
    digitalWrite (LEDgelb, LOW);
    digitalWrite (LEDrot, LOW);
    digitalWrite (LEDgruen, LOW);
    merker = false;
  }
  if (millis() - startTime >= hupeTime || !merker)
  {
    digitalWrite (hupePin, HIGH); // Relaismodul invertiert, fällt bei HIGH ab!!
  }
}

unsigned long getEntfernung()
{
  unsigned long dauer = 0;
  const float umrechner = 0.03432;
  digitalWrite(triggerPin, LOW);
  delay(5);
  digitalWrite(triggerPin, HIGH);
  delay(10);
  digitalWrite(triggerPin, LOW);
  dauer = pulseIn(echoPin, HIGH);
  Serial.print(F("errechnete Weite: "));
  Serial.println((dauer / 2) * umrechner);
  return (dauer / 2) * umrechner;
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.