Türsteuerung

Hallo zusammen,

ich würde gerne mit dem Arduino UNO eine Schaltung realisieren mit der ich "virtuell" zwei Türen steuern kann. Zunächst zur Problemstellung, ich habe zwei Türen mit jeweils einer Verriegelungseinheit und 2 LEDs rot/grün, sowie einem Taster mit dem ich die Tür anfordere. Was ich außerdem noch habe ist ein Schalter je Tür welcher den Zustand der Türen aufnimmt, also ob diese zu oder auf ist.

Nun zum Programmablauf in Worten.

Im Grundzustand sind beide Türen verriegelt und geschlossen -> beide roten LEDs sind an.

Jetzt habe ich die Möglichkeit an beiden Türen die Entriegelung durch drücken des Tasters zu "aktivieren".

Wenn ich den Taster 1 drücke -> Tür 1 wird entriegelt, rote LED 1 geht aus grüne LED 1 geht an. Nun kann ich die Tür 1 öffnen, die Tür 2 bleibt verriegelt und die rote LED 2 bleibt an. Außerdem ist das Entriegeln der Tür 2 bei entriegelter Tür 1 gesperrt bis Tür 1 wieder verriegelt ist.

Also soviel zum Thema meiner Steuerung.

Ich habe bereits versucht etwas Code zu schreiben nur leider macht er wie so oft nicht das was er soll :frowning:

int rot1 = 12;
int gruen1 = 11;
int rot2 = 10;
int gruen2 = 9;
int tast1 = 2;
int tast2 = 3;
int schloss1 = 8;
int schloss2 = 7;
int tuer1 = 6;
int tuer2 = 5;

volatile int tast1State = LOW;
volatile int tast2State = LOW;


void setup()
{
  pinMode(tast1,INPUT);
  pinMode(tast2,INPUT);
  pinMode(rot1,OUTPUT);
  pinMode(gruen1,OUTPUT);
  pinMode(rot2,OUTPUT);
  pinMode(gruen2,OUTPUT);
  pinMode(schloss1, OUTPUT);
  pinMode(schloss2, OUTPUT);
  pinMode(tuer1, INPUT);
  pinMode(tuer2, INPUT);
  
  attachInterrupt(0, schloss1Change, FALLING);
  attachInterrupt(1, schloss2Change, FALLING);
}

void loop ()
{
  digitalWrite(rot1, HIGH);
  digitalWrite(gruen1, LOW);
  digitalWrite(rot2, HIGH);
  digitalWrite(gruen2, LOW);
  
}
  
  
void schloss1Change()
{
 tast1State = !tast1State;
 digitalWrite(rot1, LOW);
 digitalWrite(gruen1, HIGH);
 digitalWrite(rot2, HIGH);
 digitalWrite(gruen2, LOW);
 digitalWrite (schloss1, tast1State);
 
 if(tuer1 == HIGH)
 {
   while(tuer1 == HIGH)
   {
      digitalWrite(rot1, HIGH);
      digitalWrite(gruen1, HIGH);
   }
   
 }

}


void schloss2Change()
{
 tast2State = !tast1State;
 digitalWrite (schloss2, tast2State);
  
}

Ich dachte ich versuche es über Interrupts, also mein Programm macht eigentlich nichts außer meine LEDs ansteuern bis ein Taster betätigt wird. In den Zweiten Interrupt habe ich noch nichts gefüllt, da ich nach dem probieren des ersten Programms erst meinen Fehler finden möchte.

Ich bin über jede konstruktive Hilfe dankbar und falls irgendwelche Informationen fehlen sagt bitte bescheid.

Vielen vielen Dank bereits im Voraus.

Gruß

Häns

Sorry, ich spreche kein Deutsch (mit Google Translate)
Ich kann nicht testen, aber versuchen Sie es.

int rot1 = 12;
int gruen1 = 11;
int rot2 = 10;
int gruen2 = 9;
int tast1 = 2;
int tast2 = 3;
int schloss1 = 8;
int schloss2 = 7;
int tuer1 = 6;
int tuer2 = 5;

bool strasseTur=0; //0=verschlossen, 1=aufschliessen
bool zurukTur=0;  

void setup()
{
  pinMode(tast1,INPUT);
  pinMode(tast2,INPUT);
  pinMode(rot1,OUTPUT);
  pinMode(gruen1,OUTPUT);
  pinMode(rot2,OUTPUT);
  pinMode(gruen2,OUTPUT);
  pinMode(schloss1, OUTPUT);
  pinMode(schloss2, OUTPUT);
  pinMode(tuer1, INPUT);
  pinMode(tuer2, INPUT);
  
}

bool tast1Vor=HIGH;
bool tast2Vor=HIGH;

void loop ()
{
bool  tast1Jetzt=digitalRead(tast1);
bool  tast2Jetzt=digitalRead(tast1);
bool debounce=false;

if((tast1Jetzt==LOW)&&(tast1Vor==HIGH))
  {strasseTur=!strasseTur; //0=verschlossen, 1=aufschliessen
   debounce=true;
   }
   
if((tast2Jetzt==LOW)&&(tast2Vor==HIGH))
  {zurukTur=!zurukTur; //0=verschlossen, 1=aufschliessen
   debounce=true;
   }
   
switch(strasseTur)
  {case 0:
     digitalWrite(rot1,HIGH);
     digitalWrite(schloss1, HIGH);
     digitalWrite(gruen1, LOW);
     break;
     
   case 1:
     digitalWrite(rot1,LOW);
     digitalWrite(schloss1, LOW);
     digitalWrite(gruen1, HIGH);
     break; 
  }


switch(zurukTur)
  {case 0:
     digitalWrite(rot2,HIGH);
     digitalWrite(schloss2, HIGH);
     digitalWrite(gruen2, LOW);
     break;
     
   case 1:
     digitalWrite(rot2,LOW);
     digitalWrite(schloss2, LOW);
     digitalWrite(gruen2, HIGH);
     break; 
  }

tast1Vor=tast1Jetzt;
tast2Vor=tast2Jetzt;
if (debounce)
  delay(400);
}

Taster entprellt?

Interrupts braucht man da nicht.
Auch wenn du deine Tasten drückst, wirst du keinen anderen Zustand als in der loop sehen. Dieser überschreibt alles wieder sofort.

haens:
Ich habe bereits versucht etwas Code zu schreiben nur leider macht er wie so oft nicht das was er soll :frowning:

Mechanische (prellende) Taster fragt man grundsätzlich NIE über Hardware-Interrupts ab.

Zur Tasterabfrage gibt es zwei praktikable Möglichkeiten:

  1. Polling (ständiges Abfragen) in der loop
  2. Timer-Interrupts

Das Polling von Tastern führt im allgemeinen zu Programmen, die vom Ablauf her leichter verständlich ("EVA-Prinzip") und daher für Anfänger besser geeignet sind.

Was Du programmieren möchtest, ist vom Prinzip her ein "endlicher Zustandsautomat" ("finite state machine"):

Eine programmtechnische Umsetzung so eines Zustandsautomaten kann zum Beispiel dadurch erfolgen, dass Du allen möglichen Zuständen einen symbolischen Namen in einer Enumeration zuordnest, für Deinen Anwendungsfall, bei dem entweder zwei Türen geschlossen sein können, die Öffnung einer Tür angefordert und eine Tür zur Zeit geöffnet sein kann beispielsweise:

enum {ALLCLOSED, OPENREQUEST1, OPENDOOR1, OPENREQUEST2, OPENDOOR2};
int state=ALLCLOSED; // Anfänglicher Status

Zu jedem Zeitpunkt des Programmablaufs ist einer dieser Zustände gesetzt.

Und im Programm schaltest Du dann den Status nach gewissen Bedingungen durch, Grundgerüst der Programmlogik etwa nach dem Schema:

void loop() {
  // Eingabe ==> Alle Taster und Sensoren abfragen
  
  // Verarbeitung
  switch (state)
  {
    ALLCLOSED: if (...) state=OPENREQUEST1;  // Anforderung für Tür1
               else if (...) state=OPENREQUEST2; // Anforderung für Tür2
               break;
    OPENREQUEST1: if (...) state=OPENDOOR1; // Tür1 wurde geöffnet
                  else if (...) state=ALLCLOSED; // Tür1 wurde nicht geöffnet
                  break;  
    OPENDOOR1: if (...) state=ALLCLOSED;
               break;
    // Alle möglichen Zustände behandeln und wenn bestimmte Bedingungen erfüllt sind
    // dann Übergang auf einen neuen Status    
  }
  
  // Ausgabe ==> LEDs entsprechend des aktuellen Zustands setzen
}