Ampelanlage reagiert nicht auf Schalter

//Auto
int A_rot = 13;
int A_gelb = 7;
int A_gruen = 8;


//Fußgänger
int F_rot = 4;
int F_gruen = 2;

int Taster = 9;
int TasterLesen;


void setup() {
  Serial.begin(9600);
  
  pinMode(A_rot, OUTPUT);
  pinMode(A_gelb, OUTPUT);
  pinMode(A_gruen, OUTPUT);

  pinMode(F_rot, OUTPUT);
  pinMode(F_gruen, OUTPUT);
  pinMode(A_gruen, OUTPUT);

  pinMode(Taster, INPUT_PULLUP);

   
 

}

void Autofahrer(){

 
 digitalWrite(A_gruen, HIGH);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_rot, LOW);
 digitalWrite(F_rot, HIGH);
 digitalWrite(F_gruen, LOW);
 delay(3000);
 digitalWrite(A_gruen, LOW);
 digitalWrite(A_gelb, HIGH);
 delay(1000);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_rot, HIGH);
 delay(3000);
 digitalWrite(A_gelb, HIGH);
 delay(1000);
 digitalWrite(A_rot, LOW);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_gruen, HIGH);

 delay(5000);
 

}



void loop() {
 TasterLesen = digitalRead(Taster);

  if(TasterLesen == LOW){
  
   Serial.println("Gedrückt");
   goto Fusgaenger;
  
  }

 else {
 Autofahrer();
 
 }
 
 Fusgaenger: 

 digitalWrite(A_gruen, HIGH);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_rot, LOW);
 digitalWrite(F_rot, HIGH);
 digitalWrite(F_gruen, LOW);
 delay(3000);
 digitalWrite(A_gelb, HIGH);
 digitalWrite(A_gruen, LOW);
 delay(1000);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_rot, HIGH);
 delay(3000);

 digitalWrite(F_rot, LOW);
 digitalWrite(F_gruen, HIGH);
 delay(5000);

 digitalWrite(F_gruen, LOW);
 digitalWrite(F_rot, HIGH);
 delay(3000);
 digitalWrite(A_gelb, HIGH);
 delay(2000);
 digitalWrite(A_rot, LOW);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_gruen, HIGH);

 }

Das Problem ist folgendes: Die Ampel an sich funktioniert, sie läuft durch ihre Phase, etc.. aber nach jedem 2ten durchlauf wird automatisch die if-schleife für das Fußgängerprogramm aktiviert, ohne das der button gedrückt wurde. Das Programm reagiert aber genrell nicht auf den Button. Richtig angeschlossen ist alles btw., da der Button funktioniert, wenn ich ein kleines Testprogramm mit if-schleife benutze (kann gerade kein bild hochladen). Hat jemand also eine erklärung, wieso die Fußgänger Ampel beim 2ten durchlauf immer aktiviert auf?
danke im voraus und sorry falls ich Infos vergessen hab.

Nimm mal das "goto Fusgaenger" weg und setze eine richtige Funktion inkl. Aufruf ein, so, wie bei Autofahrer.

jetzt schaltet es zwar nicht mehr automatisch um, aber der button wird immer noch nicht erkann

Ich verstehe wie auch HotSystems nicht wieso Du goto verwendest.
Dein if ruft entweder die Funktion Autofahrer auf oder springt zu Fußgänger. Nach dem if wird auf jeden Fall der Code für Fußgänger ausgeführt.

Die Lösung wurde Dir bereits gezeigt.

Vergiß GOTO. Durch Funktionen in C/C++ brauchst Du keine Sprünge und GOTO ist nur in wenigen speziellen Fällen sinnvoll, die ich Dir gar nicht nennen kann weil ich noch nie in meinen Sketchen solche Fälle hatte.

Grüße Uwe

Hast Du einen Wackelkontakt am Taster?

ne, wie gesagt, wenn ich nen kleines testprogramm laufen lass funktioniert er

Dann zeige jetzt mal den aktuellen Sketch.

//Auto
int A_rot = 13;
int A_gelb = 7;
int A_gruen = 8;


//Fußgänger
int F_rot = 4;
int F_gruen = 2;

int Taster = 9;
int TasterLesen;


void setup() {
  Serial.begin(9600);
  
  pinMode(A_rot, OUTPUT);
  pinMode(A_gelb, OUTPUT);
  pinMode(A_gruen, OUTPUT);

  pinMode(F_rot, OUTPUT);
  pinMode(F_gruen, OUTPUT);
  pinMode(A_gruen, OUTPUT);

  pinMode(Taster, INPUT_PULLUP);

   
 

}

void Autofahrer(){

 
 digitalWrite(A_gruen, HIGH);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_rot, LOW);
 digitalWrite(F_rot, HIGH);
 digitalWrite(F_gruen, LOW);
 delay(3000);
 digitalWrite(A_gruen, LOW);
 digitalWrite(A_gelb, HIGH);
 delay(1000);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_rot, HIGH);
 delay(3000);
 digitalWrite(A_gelb, HIGH);
 delay(1000);
 digitalWrite(A_rot, LOW);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_gruen, HIGH);

 delay(5000);
 

}

void Fusgaenger() { 

 digitalWrite(A_gruen, HIGH);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_rot, LOW);
 digitalWrite(F_rot, HIGH);
 digitalWrite(F_gruen, LOW);
 delay(3000);
 digitalWrite(A_gelb, HIGH);
 digitalWrite(A_gruen, LOW);
 delay(1000);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_rot, HIGH);
 delay(3000);

 digitalWrite(F_rot, LOW);
 digitalWrite(F_gruen, HIGH);
 delay(5000);

 digitalWrite(F_gruen, LOW);
 digitalWrite(F_rot, HIGH);
 delay(3000);
 digitalWrite(A_gelb, HIGH);
 delay(2000);
 digitalWrite(A_rot, LOW);
 digitalWrite(A_gelb, LOW);
 digitalWrite(A_gruen, HIGH);
}

void loop() {
 TasterLesen = digitalRead(Taster);

  if(TasterLesen == LOW){
  
   Serial.println("Gedrückt");
   Fusgaenger();
  
  }

 else {
 Autofahrer();
 
 }
 
 

 }

und hier das Testprogramm wenn dus brauchst:

int Taster = 9;
int TasterLesen;
int A_gruen = 8;

void setup() {
   Serial.begin(9600);
pinMode(A_gruen, OUTPUT);

  pinMode(Taster, INPUT_PULLUP);
}

void loop() {
  TasterLesen = digitalRead(Taster);
if(TasterLesen == LOW){
  Serial.println("Gedrückt");
  digitalWrite(A_gruen, HIGH);
  delay(2000);
  digitalWrite(A_gruen, LOW);
}
}

Hallo azubis12345

Ein Tipp:

Nimm ein Stück Papier und zeichne dir die Reihenfolge der gleichzeitigen Ampelphasen für Autos und Fußgänger auf.

Und dann setze diese Ampelphasen in einen Sketch, wie auch immer programmiert, um.

Viel Spass und Erfolg.

Bin jetzt etwas weiter: habe herausgefunden das die Tastereingabe nur gezählt wird, wenn man zu beginn des programms" Autofahrer()" (also während der Grünphase) den Button gedrückt hält, die eingabe zählt also nur für diesen kleinen moment zu beginn. kann man dies irgendwie ändern, z.B so das die eingabe gespeichert wenn man den button drückt während das programm läuft?

Dann gib den Schalterzustand über Seriale Schnittstelle aus um zu sehen was da gelesen wird.
Andererseits während eines Ampelzyklusses ( Autofahrer 13 Sekunden und Fußgänger 19 Sekunden) wird der Taster nicht eingelesen.
Falls Du jederzeit die im Autofahrerzyklus einen Fußgängerzyklus vormerken möchtest mußt Du Dich von delay() verabschieden und die Zeiten mit millis() bestimmen.
Grüße Uwe

wie benutze ich millis? also wie gebe ich diese an, und wie dann für verschiedene Werte?

Klar, in dem du während des Delays den Taster abfragst!
Oder das delay() in die Tonne stopfst.

Grüße Uwe

Während delay() ist das Programm blockiert, weshalb der Tastendruck nicht erkannt wird. Die Mainstream-Lösung liest Du in #12, die überlasse ich erstmal Euch, die will ich nicht wegnehmen.

Zunächst habe ich Euer Programm gekürzt und mit Konstanten garniert. Das spart Speicher.

Achtung, die Pins habe ich umsortiert!

Damit Ihr seht, daß Programmieren eine kreative Tätigkeit ist, hier eine Lösung, bei der ich delay durch eine eigene Funktion ersetze. Die Verzögerung macht sie auch, liest aber zusätzlich den Taster ein. Ergänzt habe ich die Rückmeldung für die Anforderung.

Funktion verzoegerung anstelle delay
//Auto
const byte A_rot = 5;
const byte A_gelb = 6;
const byte A_gruen = 7;

//Fußgänger
const byte F_rot = 8;
const byte F_taster = 9;
const byte F_gruen = 10;

const byte Taster = 2;
bool F_anforderung = false;

void setup()
{
  pinMode(A_rot, OUTPUT);
  pinMode(A_gelb, OUTPUT);
  pinMode(A_gruen, OUTPUT);

  pinMode(F_rot, OUTPUT);
  pinMode(F_taster, OUTPUT);
  pinMode(F_gruen, OUTPUT);

  pinMode(Taster, INPUT_PULLUP);
}


void anzeige()
{
  digitalWrite(A_gruen, HIGH);
  digitalWrite(A_gelb, LOW);
  digitalWrite(A_rot, LOW);
  digitalWrite(F_rot, HIGH);
  digitalWrite(F_gruen, LOW);
  verzoegerung(3000);
  digitalWrite(A_gelb, HIGH);
  digitalWrite(A_gruen, LOW);
  verzoegerung(1000);
  digitalWrite(A_gelb, LOW);
  digitalWrite(A_rot, HIGH);
  verzoegerung(3000);
  if (F_anforderung)
  {
    F_anforderung = false;
    digitalWrite(F_rot, LOW);
    digitalWrite(F_gruen, HIGH);
    verzoegerung(5000);
    digitalWrite(F_gruen, LOW);
    digitalWrite(F_rot, HIGH);
    verzoegerung(3000);
  }
  digitalWrite(A_gelb, HIGH);
  verzoegerung(2000);
  digitalWrite(A_rot, LOW);
  digitalWrite(A_gelb, LOW);
  digitalWrite(A_gruen, HIGH);
  verzoegerung(5000);
}

void verzoegerung(const uint32_t intervall)
{
  uint32_t vorhin = millis();
  while (1)
  {
    if(!digitalRead(Taster)) F_anforderung = true;
    digitalWrite(F_taster, F_anforderung);
    if (millis() - vorhin >= intervall) break;
  }
}

void loop() {
  anzeige();
}

Eine weitere Möglichkeit, die Blockade zu durchbrechen, ist die Verwendung von Interrupts, weil eine Interrupt Service Routine auf während delay ausgeführt wird.

Programm mit Interrupt
//Auto
const byte A_rot = 5;
const byte A_gelb = 6;
const byte A_gruen = 7;

//Fußgänger
const byte F_rot = 8;
const byte F_taster = 9;
const byte F_gruen = 10;

const byte Taster = 2;
bool F_anforderung = false;

void setup()
{
  pinMode(A_rot, OUTPUT);
  pinMode(A_gelb, OUTPUT);
  pinMode(A_gruen, OUTPUT);

  pinMode(F_rot, OUTPUT);
  pinMode(F_taster, OUTPUT);
  pinMode(F_gruen, OUTPUT);

  pinMode(Taster, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(Taster), ISR_Taster, FALLING);
}

void anzeige()
{
  digitalWrite(A_gruen, HIGH);
  digitalWrite(A_gelb, LOW);
  digitalWrite(A_rot, LOW);
  digitalWrite(F_rot, HIGH);
  digitalWrite(F_gruen, LOW);
  delay(3000);
  digitalWrite(A_gelb, HIGH);
  digitalWrite(A_gruen, LOW);
  delay(1000);
  digitalWrite(A_gelb, LOW);
  digitalWrite(A_rot, HIGH);
  delay(3000);
  if (F_anforderung)
  {
    F_anforderung = false;
    digitalWrite(F_taster, F_anforderung);
    digitalWrite(F_rot, LOW);
    digitalWrite(F_gruen, HIGH);
    delay(5000);
    digitalWrite(F_gruen, LOW);
    digitalWrite(F_rot, HIGH);
    delay(3000);
  }
  digitalWrite(A_gelb, HIGH);
  delay(2000);
  digitalWrite(A_rot, LOW);
  digitalWrite(A_gelb, LOW);
  digitalWrite(A_gruen, HIGH);
  delay(5000);
}

void ISR_Taster()
{
  if (!digitalRead(Taster)) F_anforderung = true;
  digitalWrite(F_taster, F_anforderung);
}

void loop() {
  anzeige();
}

Meine Programme könnt Ihr nun mit Eurer Lösung vergleichen und eine Menge in Eurem Bericht schreiben. Ich hoffe, das führt zu einer guten Note :slightly_smiling_face:

Auch kreativ, manchmal.....
Habs genau umgekehrt gemacht.
Die Tasterabfrage in das delay() implantiert.

//Auto
const byte A_rot = 5;
const byte A_gelb = 6;
const byte A_gruen = 7;

//Fußgänger
const byte F_rot = 8;
const byte F_taster = 9;
const byte F_gruen = 10;

const byte Taster = 2;
bool F_anforderung = false;

void setup()
{
  pinMode(A_rot, OUTPUT);
  pinMode(A_gelb, OUTPUT);
  pinMode(A_gruen, OUTPUT);

  pinMode(F_rot, OUTPUT);
  pinMode(F_taster, OUTPUT);
  pinMode(F_gruen, OUTPUT);

  pinMode(Taster, INPUT_PULLUP);
}


void anzeige()
{
  digitalWrite(A_gruen, HIGH);
  digitalWrite(A_gelb, LOW);
  digitalWrite(A_rot, LOW);
  digitalWrite(F_rot, HIGH);
  digitalWrite(F_gruen, LOW);
  delay(3000);
  digitalWrite(A_gelb, HIGH);
  digitalWrite(A_gruen, LOW);
  delay(1000);
  digitalWrite(A_gelb, LOW);
  digitalWrite(A_rot, HIGH);
  delay(3000);
  if (F_anforderung)
  {
    F_anforderung = false;
    digitalWrite(F_rot, LOW);
    digitalWrite(F_gruen, HIGH);
    delay(5000);
    digitalWrite(F_gruen, LOW);
    digitalWrite(F_rot, HIGH);
    delay(3000);
  }
  digitalWrite(A_gelb, HIGH);
  delay(2000);
  digitalWrite(A_rot, LOW);
  digitalWrite(A_gelb, LOW);
  digitalWrite(A_gruen, HIGH);
  delay(5000);
}

void yield()
{
    if(!digitalRead(Taster)) F_anforderung = true;
    digitalWrite(F_taster, F_anforderung);
}

void loop() {
  anzeige();
}

Ansonsten unverändert.

Natürlich wäre das eine ideale Anwendung für meinen Multitasking Kram.
Der Umbau eine Kleinigkeit.