Ampelschaltung Probleme mit Interrupts Taster nicht Prellfrei...

Guten Tag,
Ich habe ein Ampelschaltung programiert. Die zwei neben Straßen werden durch Interrupts ausgelöst so das diese Grün bekommen. Jedoch haben wir keine Prellfreien Taster (Reedkontakte) Deswegen haben wir in der Interrupt service routine erstmal nach dem ersten Interrupts weitere ausgestellt. Jedoch klappt das Interrrupt immer noch nicht richtig. Die LEDs wechseln und blinken aber es wir gefühlt mehrfach unterbrochen und die Pausen nicht beachtet.
Vielleicht hat je jemand ein Tipp für uns :slight_smile: Wäre echt cool :slight_smile:

Unser Code:

/*    Ampelschaltung
**    Von Patrick und Luca 
*/
const byte ampel_1_rot   = 2;    //Ampel mit Variablen entsprechenden Port zuordnen
const byte ampel_1_gel   = 3;    //Ampel Nord
const byte ampel_1_gru   = 4;
const byte ampel_2_rot   = 5;    //Ampel mit Variablen entsprechenden Port zuordnen
const byte ampel_2_gel   = 6;    //Ampel Ost
const byte ampel_2_gru   = 7;
const byte ampel_3_rot   = 8;    //Ampel mit Variablen entsprechenden Port zuordnen
const byte ampel_3_gel   = 9;    //Ampel Süd
const byte ampel_3_gru   = 10;
const byte ampel_4_rot   = 11;    //Ampel mit Variablen entsprechenden Port zuordnen
const byte ampel_4_gel   = 12;    //Ampel West
const byte ampel_4_gru   = 13;
const byte reed_nw       = 0;    //Redkontakte als Variable um die Ports festzulegen
const byte reed_os       = 1;
const int gruenphase     = 10000;
const int gelbphase      = 3000;

volatile byte state_nw = HIGH;     //Normalzustand des interrupts
volatile byte state_os = HIGH;
void setup() {
  // put your setup code here, to run once:
  pinMode(ampel_1_rot, OUTPUT);   //Wofür die Pins Verwendet werden
  pinMode(ampel_1_gel, OUTPUT);
  pinMode(ampel_1_gru, OUTPUT);
  pinMode(ampel_2_rot, OUTPUT);   //Wofür die Pins Verwendet werden
  pinMode(ampel_2_gel, OUTPUT);
  pinMode(ampel_2_gru, OUTPUT);
  pinMode(ampel_3_rot, OUTPUT);   //Wofür die Pins Verwendet werden
  pinMode(ampel_3_gel, OUTPUT);
  pinMode(ampel_3_gru, OUTPUT);
  pinMode(ampel_4_rot, OUTPUT);   //Wofür die Pins Verwendet werden
  pinMode(ampel_4_gel, OUTPUT);
  pinMode(ampel_4_gru, OUTPUT);
  
   pinMode(reed_nw, INPUT_PULLUP);       //Interrupts festlegen
   pinMode(reed_os, INPUT_PULLUP);

   attachInterrupt(digitalPinToInterrupt(reed_nw), fus_nw, LOW);
   attachInterrupt(digitalPinToInterrupt(reed_os), fus_os, LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(ampel_1_gru, HIGH);   //Hauptsraßen grün
  digitalWrite(ampel_3_gru, HIGH);   
  digitalWrite(ampel_2_rot, HIGH);   //Nebenstraßen rot
  digitalWrite(ampel_4_rot, HIGH);   
}

void rot_gruen(){
  digitalWrite(ampel_2_gel, HIGH);   
  digitalWrite(ampel_4_gel, HIGH);
  digitalWrite(ampel_1_gru, LOW);
  digitalWrite(ampel_3_gru, LOW); 
  digitalWrite(ampel_1_gel, HIGH);   
  digitalWrite(ampel_3_gel, HIGH);
  digitalWrite(ampel_1_gel, HIGH);
  digitalWrite(ampel_3_gel, HIGH);
  delay(gelbphase);
  digitalWrite(ampel_2_rot, LOW);  
  digitalWrite(ampel_4_rot, LOW);  
  digitalWrite(ampel_2_gel, LOW);   
  digitalWrite(ampel_4_gel, LOW); 
  digitalWrite(ampel_2_gru, HIGH);
  digitalWrite(ampel_2_gru, HIGH);
  digitalWrite(ampel_1_gel, LOW);
  digitalWrite(ampel_3_gel, LOW);
  digitalWrite(ampel_1_rot, HIGH);
  digitalWrite(ampel_3_rot, HIGH);
  delay(gruenphase);
}
void gruen_rot() {
  digitalWrite(ampel_2_gru, LOW);
  digitalWrite(ampel_2_gru, LOW);
  digitalWrite(ampel_1_gel, HIGH);   
  digitalWrite(ampel_3_gel, HIGH);
  digitalWrite(ampel_2_gel, HIGH);   
  digitalWrite(ampel_4_gel, HIGH);
  delay(gelbphase);
  digitalWrite(ampel_1_gel, LOW);   
  digitalWrite(ampel_3_gel, LOW);
  digitalWrite(ampel_2_gel, LOW);   
  digitalWrite(ampel_4_gel, LOW);
  digitalWrite(ampel_1_rot, LOW);
  digitalWrite(ampel_3_rot, LOW);
}

void fus_nw() {
  noInterrupts();
  state_nw = !state_nw;
  rot_gruen();
  gruen_rot();
  interrupts();
}

void fus_os() {
  noInterrupts();
  state_os = !state_os;
  rot_gruen();
  gruen_rot();
  interrupts();
}

Taster brauchst du nicht per Interrupt abfragen.
Dadurch werden diese auch nicht entprellt.

Das Entprellen kannst du per Hardware (Kondensator und Widerstand hinzufügen) oder besser per Software (Debounce) machen.

Debounce

Danke für ihrer Antwort. Das Problem ist nur wir müssen mit Interrupts Arbeiten, das ist eine Bedingung.

Eine Software Seitige Lösung wäre supper

Arduino_Ampel:
Danke für ihrer Antwort. Das Problem ist nur wir müssen mit Interrupts Arbeiten, das ist eine Bedingung.

Eine Software Seitige Lösung wäre supper

Und was soll der Interrupt in dem Sketch bewirken?
Die Debounce-Routine kannst du dennoch einsetzen.

Hallo,
ich weiß ja nicht, was es für eine Kreuzung ist…
Du weißt schon, das Du genau die Hälfte der Abfragen und Pin´s sparen kannst.
Ampel Nord/Süd und West/Ost könnten sich die Pin´s/Abfragen teilen.
Du bräuchtest dann nur noch "6" für die Kreuzung.
Gruß und Spaß
Andreas

kannst mal probieren:

int valZS1;                                // Variable für den Pin Zustand 
int buttonStateS1;                        // Variable für den letzten Schalterzustand 
int buttonPressesS1 = 0;                  // Wie oft ist der Schalter gedrückt   



valZS1 = digitalRead(S1);             
if (valZS1 != buttonStateS1) 
{                                     
if (valZS1 == HIGH) 
{                                      
buttonPressesS1++;                          
}
} 
buttonStateS1 = valZS1;
if (buttonPressesS1 == 1)
{
mach was- Ampel schalten?
}

 if (buttonPressesS1 == 1)
{
buttonPressesS1 = 0;
}

Taster per Interrupt abfragen ist sehr problematisch. In dem Fall ist das Entprellen per Hardware die beste Lösung.

Hallo Patrick und Luca,
ich sehe delay() innerhalb der Interrupt-Service-Routine (ISR), was nicht funktionieren dürfte: "Inside the attached function, delay() won't work and the value returned by millis() will not increment."

Innerhalb einer ISR sollte nur eine Merkervariable gesetzt werden, um dann innerhalb von loop() ausgewertet zu werden.

Gruß an den Aufgabensteller: Mittels Interrupt einen Taster abzufragen ist nicht Arduino like.

Anregungen dürft Ihr Euch gerne holen: Anleitung: Endlicher Automat mit millis()

pin[8] und pin[9] nutze ich als Merker, was als nächstes passieren soll. Das könnte auch eine Variable sein, die von der ISR gesetzt wird.