Dringend Hilfe benötigt!

Ich muss morgen ein Projekt im Fach NWT abgeben. Für dieses Projekt muss ich mit dem Arduino UNO eine Ampelschaltung mit Taster programmieren. Der Code und die Schaltung an sich funktionieren, jedoch funktioniert der Taster gar nicht. Ich probiere schon seit Tagen verschiedenste Sachen in der Schaltung, vor allem aber im Code aus und nichts scheint zu funktionieren. Mir wurde der Tipp gegeben einen Seriellen Monitor einzubauen, was ich auch getan habe, doch dieser zeigt mir, dass mein Taster konstant auf 1 ist, selbst wenn gedrückt. Was mich hierbei verwirrt ist, dass das "L"-Lämpchen auf den Arduino Platte bei drücken aus geht, was ja eig heißt, dass der Taster aus ist, also gedrückt ist, doch der Code nimmt es irgendwie nicht war oder so...
Unten steht der Code und im Anhang ist ein Bild der Schaltung in Tinkercad

//Variablen Ampel(A)
int RotA = 8;
int Gelb = 9;
int GrunA = 10;

//Variablen Ampel(F)
int RotF = 4;
int GrunF =5;

//Variable Taster
int Taster = 13;

//Variable Lautsprecher
int Ton = 11;


void setup () {
  //Modus Ampel(A)
  pinMode(RotA,OUTPUT);
  pinMode(Gelb,OUTPUT);
  pinMode(GrunA,OUTPUT);
  
  //Modus Ampel(F)
  pinMode(RotF,OUTPUT);
  pinMode(GrunF,OUTPUT);
  
  //Modus Taster
  pinMode(Taster,INPUT_PULLUP);

 Serial.begin(9600);
}

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

  Serial.print("Tasterstatus: ");
  Serial.println(TasterLesen);

  if(TasterLesen == LOW){
    anfang();
     delay(30000);
     gelb();
     delay(2000);
     fusganger();
     Ton1();
     delay(45000);
     gelb();
     delay(2000);
   }
 else{
     delay(5000);
     anfang();
     delay(50000);
     gelb();
     delay(2000);
     fusganger();
     Ton1();
     delay(45000);
     gelb();
     delay(2000);
 }
}
void anfang(){
  digitalWrite(GrunA,HIGH);
  digitalWrite(RotF,HIGH);
  digitalWrite(GrunF,LOW);
  digitalWrite(RotA,LOW);
  digitalWrite(Gelb,LOW);
}

void gelb(){
  digitalWrite(Gelb,HIGH);
  digitalWrite(RotF,HIGH);
  digitalWrite(GrunF,LOW);
  digitalWrite(RotA,LOW);
  digitalWrite(GrunA,LOW);
}

void fusganger(){
  digitalWrite(GrunF,HIGH);
  digitalWrite(RotA,HIGH);
  digitalWrite(GrunA,LOW);
  digitalWrite(Gelb,LOW);
  digitalWrite(RotF,LOW);
}

void Ton1(){
  tone(Ton,440);
  delay(100);
  tone(Ton,440);
  delay(100);
  tone(Ton,440);
  delay(100);
  tone(Ton,440);
  delay(100);
  tone(Ton,440);
  delay(5000);
  tone(Ton,440);
  delay(100);
  tone(Ton,440);
  delay(100);
  tone(Ton,440);
  delay(100);
  tone(Ton,440);
  delay(100);
  tone(Ton,440);
  delay(5000);
  tone(Ton,440);
  delay(100);
  tone(Ton,440);
  delay(100);
  noTone(Ton);
}

Hallo,

dein Programm besteht nur aus harten delays. Selbst wenn der Taster nicht gedrückt ist, hängt das Programm im else Zweig in den delays fest. Dein Programm hat nur in dem Momment die Chance den Taster zu erkennen, wenn es den Taster abfragt und er gedrückt ist. Addiere alle delay Zeiten vom else Zweig, drücke solange den Taster, dann wird er erkannt. Genau das ist aktuell das Problem. Der Taster kann nicht in jedem Durchlauf der loop abgefragt werden.

Programmiere ohne delays. Sonst wird das nichts.
Stelle dir die Frage was macht delay(x) ...

Theseus erklärt millis()

GuntherB - BlinkwithoutDelay - Die Nachtwächtererklärung

Beruht alles auf dem IDE Bsp.: 02.Digital -> BlinkwithoutDelay

Für deine zeitlichen Aktionen benötigst du eine Schrittkette. Stichwort enum, switch case. Mittels Abfrage/Vergleich ob Zeitdifferenz erreicht ist, führt man die gewünscht Aktions aus und wechselt zum nächsten Schritt und wartet die nächste Bedingung ab ob die nächste Zeitdifferenz erreicht wurde. usw.

Damit erreicht man das das gesamte Programm, deine loop nie blockiert und ständig durchlaufen werden kann und damit in jedem Durchlauf irgendwelche Eingänge abgefragt werden können. Die Tasterabfrage kannste auch händisch entprellt mit millis machen oder schaust dir die Lib Bounce2 an.

...und nimm zum Probieren einen anderen Pin als 13.
Da hängt die LED_BUILTIN dran.

Hallo,

die LED stört den I/O Pin nicht. Da ist ein OPV als Spannungsfolger davor. Unabhängig ob der I/O Pin Eingang oder Ausgang ist.

Schau dir mal Arduino: Programmiertechniken/Statemaschine – Wikibooks, Sammlung freier Lehr-, Sach- und Fachbücher an. Da ist ganz unten eine Ampelsimulation ohne delay

Ich weiß.
Es ist aber m.E. am Anfang vielleicht hilfreich, sich die interne LED für Statusausgaben oder einen "Heartbeat" freizuhalten.

1 Like

Hallo,

in dem Licht gesehen ja. :wink:
Aber ganz ehrlich, der Thread ist laut meiner Meinung vom TO schon tot.
Wir unterhalten uns alleine. Schade eigentlich für den TO.

Hat geklappt! Vielen Dank!

Hallo,

hast du deins jetzt in der Zwischenzeit wirklich umgeschrieben?
Dann nehme ich alles zurück und sage Respekt. :+1:

Oh prima - Glückwunsch!
Dann zeig uns doch bitte mal das Ergebnis.

habe auch etwas geklöppelt... mit Simulation in Wokwi...

In Anlehnung an Deinen Sketch im C-Style umgebaut; Simulation bei Wokwi. Der Ton fehlt noch. Durch Veränderung der TIMEUNIT kann es auch langsamer laufen.

Hier der Sketch:

//Variablen Ampel(A)
const byte RotA = 8;
const byte Gelb = 9;
const byte GrunA = 10;

//Variablen Ampel(F)
const byte RotF = 4;
const byte GrunF =5;

//Variable Taster
const byte Taster = 13;

//Variable Lautsprecher
const byte Ton = 11;

#define TIMEUNIT 100

// mögliche Ampelphasen:
// Auto_Fußgänger
enum Ampelphasen {GRUEN_ROT, GELB_ROT, ROT_ROT_1, ROT_GRUEN, ROT_ROT_2, ROTGELB_ROT};
Ampelphasen phase = GRUEN_ROT;

// Zeitsteuerung
uint32_t lastTime;
uint32_t waitTime;
bool phasenAktiv = false;        // Merker für laufende Schrittkette


void setup () {
  //Modus Ampel(A)
  pinMode(RotA,OUTPUT);
  pinMode(Gelb,OUTPUT);
  pinMode(GrunA,OUTPUT);
  
  //Modus Ampel(F)
  pinMode(RotF,OUTPUT);
  pinMode(GrunF,OUTPUT);
  
  //Modus Taster
  pinMode(Taster,INPUT_PULLUP);

  Serial.begin(115200);
  schalteAmpel(phase);
}

void loop (){
  byte tasterLesen = digitalRead(Taster);
  static byte letzterTasterStatus = tasterLesen;
  uint32_t currentTime = millis();


  if (tasterLesen != letzterTasterStatus)
  {
    Serial.print("Tasterstatus: ");
    Serial.println(tasterLesen);
    letzterTasterStatus = tasterLesen;
  }

  // Wenn Taster nicht gedrückt wurde:
  //    nichts ändern (grün für die Autos)
  // anderenfalls:
  //    Ampelphasen einmal durchschalten
  if (phasenAktiv || tasterLesen == LOW)
  {
    phasenAktiv = true;
    if (currentTime - lastTime > waitTime)
    {
      // Wartezeit ist abgelaufen, nächste Ampelphase schalten
      switch(phase)
      {
        case GRUEN_ROT:
          waitTime = 5*TIMEUNIT;    // Zeit für nächste Phase!!!
          phase = GELB_ROT;
          break;
        case GELB_ROT:
          waitTime = 5*TIMEUNIT;
          phase = ROT_ROT_1;
          break;
        case ROT_ROT_1:
          waitTime = 40*TIMEUNIT;
          phase = ROT_GRUEN;
          break;
        case ROT_GRUEN:
          waitTime = 20*TIMEUNIT;
          phase = ROT_ROT_2;
          break;
        case ROT_ROT_2:
          waitTime = 10*TIMEUNIT;
          phase = ROTGELB_ROT;
          break;
        case ROTGELB_ROT:
          waitTime = 20*TIMEUNIT;   // minimale Zeit nach der auf den Taster reagiert wird
          phase = GRUEN_ROT;
          phasenAktiv = false;
          break; 
      }
      schalteAmpel(phase);
      lastTime = currentTime;
    }
  }
}

void schalteAmpel(Ampelphasen phase)
{
  switch(phase)
  {
    case GRUEN_ROT:
      digitalWrite(RotA,LOW);
      digitalWrite(Gelb,LOW);
      digitalWrite(GrunA,HIGH);
      digitalWrite(RotF,HIGH);
      digitalWrite(GrunF,LOW);
      break;
    case GELB_ROT:
      digitalWrite(RotA,LOW);
      digitalWrite(Gelb,HIGH);
      digitalWrite(GrunA,LOW);
      digitalWrite(RotF,HIGH);
      digitalWrite(GrunF,LOW);
      break;
    case ROT_ROT_1:
      digitalWrite(RotA,HIGH);
      digitalWrite(Gelb,LOW);
      digitalWrite(GrunA,LOW);
      digitalWrite(RotF,HIGH);
      digitalWrite(GrunF,LOW);
      break;
    case ROT_GRUEN:
      digitalWrite(RotA,HIGH);
      digitalWrite(Gelb,LOW);
      digitalWrite(GrunA,LOW);
      digitalWrite(RotF,LOW);
      digitalWrite(GrunF,HIGH);
      break;
    case ROT_ROT_2:
      digitalWrite(RotA,HIGH);
      digitalWrite(Gelb,LOW);
      digitalWrite(GrunA,LOW);
      digitalWrite(RotF,HIGH);
      digitalWrite(GrunF,LOW);
      break;
    case ROTGELB_ROT:
      digitalWrite(RotA,HIGH);
      digitalWrite(Gelb,HIGH);
      digitalWrite(GrunA,LOW);
      digitalWrite(RotF,HIGH);
      digitalWrite(GrunF,LOW);
      break;
  }
}

void Ton1(){
  tone(Ton,440);
  delay(100);
  noTone(Ton);
  delay(100);
}

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