Lichtschranke Auslöseschwelle

Hallo Leute,

Ich habe folgendes Problem.
Ich habe für meinen Vater eine Alarmanlage für seinen Garten gebaut, welche mit einem Arduino gesteuert wird.
Der Alarm wird durch eine Lichtschranke ausgelöst.
Das Problem ist aber wenn z.B ein Vogel durch die Schranke fliegt bekommen wir auf unsere Handys die SMS, dass die Anlage ausgelöst hat, außerdem geht dann noch eine Sirene und Lichter an.
Die Anlage hat diese Woche schon 5-mal ausgelöst, ich habe keine Lust, dass es stress mit den Nachbarn gibt.

Ich habe den Code mal eingefügt.
Pin9 /ausloeser_status soll z.B. 2sec HIGH sein und dann sollte der Alarm erst auslösen.
Wie könnte man das Programmieren?

const int power_led = 13;     //Rote LED
const int call_led = 12;      // Grüne LED

int ausloeser = 9;            // Signal eingang /Auslöser
int ausloeser_status = 0;

void setup()

{
  Serial.begin(9600);
  
  
  
  pinMode (13, OUTPUT);    // LED
  pinMode (12, OUTPUT);    // LED
  pinMode (9, INPUT);    // Signal eingang
  pinMode (7,OUTPUT);    // Relay Modul IN1
  pinMode (6,OUTPUT);    // Relay Modul IN2
  
  

  digitalWrite (7,HIGH);
  digitalWrite (6,HIGH);
  digitalWrite (power_led, HIGH);
  digitalWrite (call_led, LOW);
  
 delay(1000);                  // GESM MODUL Starten
   pinMode(8, INPUT);          // GSM Modul Knopf
  digitalWrite(8, LOW);
  pinMode(8, OUTPUT);
  delay(1000);
  pinMode(8, INPUT);
  
  
}


void loop()
{
  ausloeser_status = digitalRead(ausloeser);
  
     
   
    if (ausloeser_status == HIGH)              // Lichtschranke,Verzögerung sollte hier rein?
    {
          
   digitalWrite(12,HIGH);

    Serial.println("AT+CMGF=1"); 
    delay(500); 
    Serial.println("AT+CMGS=xxxxxxxx"); //Nummer
    delay(1000); 
    Serial.print("Garten Alarm"); 
    delay(500); 
    Serial.print(char(26)); 

        digitalWrite(7,LOW);
        digitalWrite(6,LOW);
        delay(30000);               // Zeit,wie lang das Licht usw. an ist
        digitalWrite(7,HIGH);
        digitalWrite(6,HIGH);
           
        digitalWrite(12,HIGH) ;
        digitalWrite(13,HIGH);
    }
}

Sry wenn der Code nicht so toll ist,ich habe in Programmieren leider eine 5 :frowning:

Hallo und willkommen im Forum!

DerBastler97:
Pin9 /ausloeser_status soll z.B. 2sec HIGH sein und dann sollte der Alarm erst auslösen.

Du meinst, ein Einbrecher wartet 2 Sekunden? Da bin ich skeptisch!

Abgesehen mal davon: Wenn ausloeser_status==LOW und digitalRead(ausloeser)==HIGH, also bei positiver Flanke, warte zwei Sekunden, wenn dann digitalRead(ausloeser) immer noch HIGH ist, dann Alarm auslösen.

Blockierende Programmierung beispielsweise mittels delay() führt nicht selten zu Problemen. Etwas Lesestoff oder das Beispiel BlinkWithoutDelay könnte Dich weiterbringen.

Die Lichtschranke ist ca 20cm von den zu Bewachen Gartenhäusern entfernt das heißt, wenn der Einbrecher sich am Schloss zuschaffen macht löst er die Schranke auf jeden Fall aus.
Mir geht es mit der Verzögerung nur darum ,dass keine Vögel den Alarm auslösen.

void loop()
{
  ausloeser_status = digitalRead(ausloeser);
  
     if (digitalRead(ausloeser)== HIGH)
     {
       delay(2000);
     }
     
    if (ausloeser_status == HIGH)              // Lichtschranke pin9
    {

Funktioniert das?

Das funktioniert, macht aber nicht, was Du willst. Durch ausloeser_status = digitalRead(ausloeser); sollte ausloeser_status HIGH sein, wenn der Eingang es ist. Das überprüfst Du mit zwei Sekunden Verzögerung, aber in dieser Zeit kann sich der Variableninhalt nicht verändert haben.

agmue:
Das funktioniert, macht aber nicht, was Du willst. Durch ausloeser_status = digitalRead(ausloeser); sollte ausloeser_status HIGH sein, wenn der Eingang es ist. Das überprüfst Du mit zwei Sekunden Verzögerung, aber in dieser Zeit kann sich der Variableninhalt nicht verändert haben.

....da du sie ja nicht wieder erneut einliest (digitalRead)

Würde es jetzt so funktionieren?
Mit dem ersten If frage ich, ob der Eingang HIGH ist wenn ja verzögert das Programm, wenn es nach der Verzögerung immer noch High ist, dann geht der Alarm los?
Sry wenn ich vielleicht so dumme fragen stelle,bin wirklich schlecht im Programmieren

void loop()
{
  ausloeser_status = digitalRead(ausloeser);
  
   
   if (digitalRead(ausloeser)==HIGH)
     {delay(2000);
     }
  
   if (digitalRead(ausloeser)==HIGH)
    {

Deine Loop wird so immer noch nicht richtig funktionieren.

Du solltest das Delay(2000) wie auch schon von "agmue" beschrieben komplett ersetzen. Dann wird dein Programm nicht angehalten. Dies auch bei dem Delay(30000) beachten.

Wichtig ist, dass dein Programm innerhalb einer "Zeit-Schleife" immer wieder prüft, ob sich der Status der Variable "ausloeser_status" geändert hat. Das ist in dem Link von agmue sehr schön beschrieben.
Und am Ende muss die Variable auch wieder zurück gesetzt werden.

Der endliche Automat hat sich bei mir bewährt, auch um die Gedanken zu sortieren. Ich beginne also mit enum Zustaende {WARTEN, BESTAETIGUNG, ALARM}; und dem Automaten:

switch (zustand) {
    case WARTEN:
      break;
    case BESTAETIGUNG:
      break;
    case ALARM:
      break;
  }

Dann folgt die Verzögerung und der Abbruch, wenn es nur ein Vogel war:

int ausloeser = 9;            // Signal eingang /Auslöser
unsigned long aktMillis;
unsigned long prevMillis;
unsigned int intervall;
bool ausloeser_status;
bool prevAusloeser;
enum Zustaende {WARTEN, BESTAETIGUNG, ALARM};
byte zustand = WARTEN;

void setup() {
  Serial.begin(9600);
  pinMode (ausloeser, INPUT);    // Signal Eingang
  prevAusloeser = digitalRead(ausloeser);
  Serial.println("Programmanfang");
}

void loop() {
  ausloeser_status = digitalRead(ausloeser) && !prevAusloeser;  // positive Flanke
  prevAusloeser = digitalRead(ausloeser);
  switch (zustand) {
    case WARTEN:
      if (ausloeser_status) {
        prevMillis = millis();
        intervall = 2000;
        Serial.println("Warten auf Alarmbestaetigung");
        zustand = BESTAETIGUNG;
      }
      break;
    case BESTAETIGUNG:
      if (digitalRead(ausloeser) == LOW) {
        intervall = 0;
        Serial.println("Nur ein Vogel");
        zustand = WARTEN;
      } else if (millis() - prevMillis >= intervall) {
        prevMillis = millis();
        intervall = 30000;
        Serial.println("Garten Alarm begonnen");
        zustand = ALARM;
      }
      break;
    case ALARM:
      if (millis() - prevMillis >= intervall) {
        prevMillis = millis();
        intervall = 0;
        Serial.println("Garten Alarm beendet");
        zustand = WARTEN;
      }
      break;
  }
}

Auf dieser Struktur aufbauend können dann noch die Relais geschaltet und weitere Feinheiten ergänzt werden.