• Die Forumsregeln und Nutzungsbedingungen findet ihr in der Navbar unter Impressum !
    Bitte unbedingt beachten!
    Wie überall im Leben gibt es Spielregeln, so auch hier!
    Die Datenschutzerklärung zum DSGVO findet ihr ebenfalls in der Navbar unter Datenschutzerklärung !
    Hinweis nach DSGVO :
    Es ist hier keinerlei Angabe erforderlich. Alle Angaben in diesem Bereich sind öffentlich sichtbar und werden freiwillig gemacht. Mit einem Eintrag in diesem Bereich erkenne ich dieses an, und bestätige die Datenschutzerklärung zur DSGVO für das Forum gelesen zu haben.

    Danke
  • Hallo Gast, beschränke dich hier bitte auf den Bereich der Elektronik. Die Fahrzeuge oder Gebäude, wo diese Elektronik eingebaut wird bitte in dem passenden Fachbereiich behandeln. Auch wenn Teile des Projektes dadurch im Forum doppelt vorhanden sind! Danke.

Arduino Ampelsteuerung

Stephan_56

New member
Registriert
15.02.2014
Beiträge
34
...die 100.000ste :hfg

Hallo Forum,

nachdem ich mich nun endlich einmal dazu durchgerungen habe, mir auch einen Arduino (UNO V3) zuzulegen (war im Kit recht günstig), habe ich die Übungslektionen hinter mich gebracht.

Die Aufgabe, die ich mir gestellt hatte war: Ampelstuerung mit 2 Richtungen, Fußgängersteuerung mit Interrupt und eine Not/Nachtschaltung. Natürlich hat mir Google bei der Suche nach Ideen geholfen...

Programmiertechnisch am ekeligsten fand ich ja diese delay(x) für die Phasensteuerung. Deswegen möchte ich die noch auf millis() umstellen.
Erste Versuche sind kläglich gescheitert.

Statt der delay(x) habe ich ein zeit=millis()+3000; eingegeben. zeit wurde als long deklariert, weil 32768 nur für 32 Sekunden reicht. long hingegen reicht für über 550 Stunden :ok
Dazu eine Variable für die jeweilige Phase. Ausgewertet habe ich dann mit if ( millis() > zeit && phase=n) {...} .
Das Programm durchlief zwar die Befehle in den Schleifen, schaltet aber die LEDs nicht. Im {}-Block der if-Bedingung werden die LEDs neu gesetzt und der Zähler für die Phase neu gesetzt.
Zweck des Ganzen ist, den Arduino nicht in den delays zu blocken, sondern ihn über die Variable Zeit, basierend auf den millis() ständig am Laufen zu halten. Ich hatte mal gelesen, das sei so besser. Die Form der Interrupt-Behandlung (nur kurze Routine) habe ich bei Winni "gemopst".

Nach der Grundstellung der Ampel werden die als if... gewandelten delay angesteuert. Löppt aber nicht, jedenfalls die LEDs nicht.

Beispielhaft hier mal zwei Blöcke:

Code:
// Phase 1 ROT/GELB folgt auf alles ROT bei Ampel 1
// 5000 millis hier nicht reingehen, da phase=1 auch nicht in alle anderen Teile
if (millis() > zeit && phase == 1)
	{
	digitalWrite(ledpinRot1, HIGH); //Rot
	digitalWrite(ledpinGelb1,HIGH); //Gelb
	digitalWrite(ledpinGruen1, LOW);
	digitalWrite(ledpinRot2, HIGH); //Rot
	digitalWrite(ledpinGelb2, LOW);
	digitalWrite(ledpinGruen2, LOW);
	zeit = millis() + 3000;
	phase = 2;
	}

// Phase 2 zeigt Ampel1 3 sek rot/gelb	
if (millis() > zeit && phase == 2)
	{
	phase = 3;
	zeit = millis() + 5000;
	}

// Phase 3 zeigt Ampel 1 GRÜN für 5 sek	
if millis() > zeit and phase == 3 
        {
	// delay(3000); 
	digitalWrite(ledpinRot1, LOW);
	digitalWrite(ledpinGelb1, LOW);
	digitalWrite(ledpinGruen1, HIGH); // Grün
	digitalWrite(ledpinRot2, HIGH); // Rot
	digitalWrite(ledpinGelb2, LOW);
	digitalWrite(ledpinGruen2, LOW);
	zeit = millis() + 5000;
	phase = 4;
	//delay(DELAY5);
	}

Das Programm kann also nur dann in die if-Bedingungen springen, wenn die Zeit abgelaufen ist UND die richtige Phase diese Schleife freigibt.
Ich habe mir auch schon seriell die jeweiligen Schleifenwerte ausgeben lassen und dabei festgestellt, daß zwar in die Schleifen verzweigt wird, aber komischerweise die LEDs nicht entsprechend geschaltet werden. Ist ja eigentlich gar nicht möglich, oder?

Edit:
Die Phasenzeiten habe ich bewußt so kurz gehalten, damit ich bei realen Umlaufzeiten nicht einpenne ;)

Nun bräuchte ich euch zum debuggen:(
 
Moin Stephan,

leider lässt das Snippet nur Vermutungen zu.

Also, wie ist die Variable "phase" initialisiert ? Wenn sie nicht bzw. nicht mit 1 initialisiert ist wird die erste if() Anweisung nie ziehen und somit die LEDs niemals an gehen.

In der letzten if() Anweisung setzt die phase = 4, damit passiert nie wieder etwas. Muss es hier nicht eher wieder auf phase = 1 gesetzt werden ?

Für die Abfrage empfehle ich eine andere Vorgehensweise, die - zumindest für mich - übersichtlicher ist.

Code:
void func()
{
	// Phase 1 ROT/GELB folgt auf alles ROT bei Ampel 1
	// 5000 millis hier nicht reingehen, da phase=1 auch nicht in alle anderen Teile
	if (millis() > zeit )
	{
		switch( phase )
		{
			case 1:
				digitalWrite(ledpinRot1, HIGH); //Rot
				digitalWrite(ledpinGelb1,HIGH); //Gelb
				digitalWrite(ledpinGruen1, LOW);
				digitalWrite(ledpinRot2, HIGH); //Rot
				digitalWrite(ledpinGelb2, LOW);
				digitalWrite(ledpinGruen2, LOW);
				zeit = millis() + 3000;
				phase = 2;
				break;
			case 2:
				phase = 3;
				zeit = millis() + 5000;
				break;
			case 3:
				digitalWrite(ledpinRot1, LOW);
				digitalWrite(ledpinGelb1, LOW);
				digitalWrite(ledpinGruen1, HIGH); // Grün
				digitalWrite(ledpinRot2, HIGH); // Rot
				digitalWrite(ledpinGelb2, LOW);
				digitalWrite(ledpinGruen2, LOW);
				zeit = millis() + 5000;
				phase = 4;		//	muss dies nicht phase=1 sein ?0
				break;
		}
	}
}
 
Hi Peter,

ja klar, phase wird im setup mit 1 initialisiert und wird zum Umlaufende auch wieder auf 1 gesetzt.

Deinen Aufbau mit case... finde ich äußerst charmant. Werde das mal umsetzen und dann Bericht erstatten.

:thx
 
Hi Peter,

habe den Sketch jetzt mal vervollständigt. Irgendwo ist da noch ein Würmchen drin.

Die erste Gelphase von Richtung 1 zeigt immer beim Umlaufbeginn 8 Sekunden gelb. Dieser Wert ist, auch durch Addition, nirgendwo definiert.
Gelb ist aber Phase 2 und sollte nur 3 sek dauern...
Komme nicht drauf...

Alle anderen Verhaltensweisen sind so, wie angedacht:

Vor Durchführung des Fußgängerinterrupts muß der Umlauf beendet sein, sonst könnte die Anforderung in jeder Phase erfolgen und würde genau dorthin zurückspringen.
Gleiches gilt für die Not-/Nachtschaltung. Umlauf wird erst beendet.
Bevor die Nachtschaltung aufgehoben wird, zeigt die Ampel für alle Richtungen Dauergelb für 5 Sekunden, bei den Fußgängern bleibt während der Nachtschaltung alles aus. Während der Nachtphase können die Fußgänger kein Grün anfordern.
Ansonsten löppt's.

Hier der Sketch:

Code:
int ledpinRot1 = 3; // rote led Auto 1
int ledpinGelb1 = 4; // gelbe led Auto 1
int ledpinGruen1 = 5; // gruene led Auto 1
int ledpinRot2 = 6; // rote led Auto 2
int ledpinGelb2 = 7; // gelbe led Auto 2
int ledpinGruen2 = 8; // gruene led Auto 2
int ledpinRot3 = 9; // rote led Fuss 3
int ledpinGruen3 = 10; // gruene led Fuss 3
int fussgruen = 5000; // Dauer Grün Fußgänger
int warten1 = 1000; // Pause 1 sek.
int warten2 = 2000; // Pause 2 sek
int warten3 = 3000; // Pause 3 sek
int warten5 = 5000; // Pause 5 sek
int phase = 1; // Zählvariable
long zeit = 0; // Speicher für Sollzeit
int nachtpinStatus; // Auswertung für Nachtschaltung
const int nachtpin = 11; // Pin11 wertet Nachtpin analog aus
volatile int fussStatus = 1; // auf 0, wenn Fußgängergrün angefordert wurde


void setup() {

pinMode(nachtpin, INPUT); // Pin11 als Eingang - Nachtschaltung
pinMode(ledpinRot1, OUTPUT); // Pin3 als Ausgang
pinMode(ledpinGelb1, OUTPUT); // Pin4 als Ausgang
pinMode(ledpinGruen1, OUTPUT); // Pin5 als Ausgang
pinMode(ledpinRot2, OUTPUT); // Pin6 als Ausgang
pinMode(ledpinGelb2, OUTPUT); // Pin7 als Ausgang
pinMode(ledpinGruen2, OUTPUT); // Pin8 als Ausgang
pinMode(ledpinRot3, OUTPUT); // Pin9 als Ausgang
pinMode(ledpinGruen3, OUTPUT); // Pin10 als Ausgang
attachInterrupt(0, fussAnforderung, FALLING); // Interrupt reagiert auf Übergang nach LOW / GND

// Ausgangsposition - alles aus
digitalWrite(ledpinRot1, LOW); // Richtung 1 - rot
digitalWrite(ledpinRot2, LOW); // Richtung 2 - rot
digitalWrite(ledpinRot3, LOW); // Fußgänger - rot
digitalWrite(ledpinGelb1, LOW); // Richtung 1 - gelb
digitalWrite(ledpinGelb2, LOW); // Richtung 2 - gelb
digitalWrite(ledpinGruen1, LOW); // Richtung 1 - Grün
digitalWrite(ledpinGruen2, LOW); // Richtung 2 - Grün
digitalWrite(ledpinGruen3, LOW); // Fußgänger - grün
zeit = millis() + 5000;
}

void loop() 
{

// Nachtschaltung auswerten
  nachtpinStatus = digitalRead(nachtpin);
  
  // definierten Einsprung/Aussprung nur bei Doppelrot (Umlaufstart)
  if (nachtpinStatus == LOW && phase == 1) nachtschaltung();

  // Anforderung Fußgänger auswerten und nur nach dem Umlauf Einsprung ermöglichen
  if (fussStatus == 0 && phase == 1) fussgaenger();

  // Ausgangsposition für Umlauf

  if (millis() > zeit)
  {
      switch ( phase)
      {
          case 1:
                digitalWrite(ledpinRot1, HIGH); // rote led1 einschalten
                digitalWrite(ledpinRot2, HIGH); // rote led2 einschalten
                digitalWrite(ledpinRot3, HIGH); // rote led3 einschalten
                digitalWrite(ledpinGelb1, LOW); // gelbe led1 ausschalten
                digitalWrite(ledpinGelb2, LOW); // gelbe led2 ausschalten
                digitalWrite(ledpinGruen1, LOW); // grüne led1 ausschalten
                digitalWrite(ledpinGruen2, LOW); // grüne led2 ausschalten
                digitalWrite(ledpinGruen3, LOW); // grüne led3 ausschalten
                zeit = millis() + warten3;
                phase = 2;
                break;
          case 2:
                digitalWrite(ledpinRot1, HIGH); //Rot
                digitalWrite(ledpinGelb1,HIGH); //Gelb
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, HIGH); //Rot
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten3;
                phase = 3;
                break;
          case 3:
                zeit=millis() + warten5;
                phase=4;
                break;
          case 4:  
                digitalWrite(ledpinRot1, LOW);
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, HIGH); // Grün
                digitalWrite(ledpinRot2, HIGH); // Rot
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten5;
                phase = 5;
                break;
            case 5:
                zeit = millis() + warten5;
                phase = 6;
                break;
            case 6:
                digitalWrite(ledpinRot1, LOW);
                digitalWrite(ledpinGelb1, HIGH); // Gelb
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, HIGH); //Rot
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten3;
                phase = 7;
                break;
            case 7:
                digitalWrite(ledpinRot1, HIGH); // Rot
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, HIGH); // Rot
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten2;
                phase = 8;
                break;
            case 8:
                digitalWrite(ledpinRot1, HIGH);  // Rot
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, HIGH); // Rot
                digitalWrite(ledpinGelb2, HIGH); // Gelb
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten2;
                phase = 9;
                break;
            case 9:
                 digitalWrite(ledpinRot1, HIGH); // Rot
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, LOW);
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, HIGH); // Grün
                zeit = millis() + warten5;
                phase = 10;
                break;
            case 10:
                digitalWrite(ledpinRot1, HIGH); // Rot
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, LOW);
                digitalWrite(ledpinGelb2, HIGH); // Gelb
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten3;
                phase = 11;
                break;
            case 11:
                digitalWrite(ledpinRot1, HIGH); // Rot
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, HIGH); // Rot
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, LOW);
                //zeit = millis() + warten2;
                phase = 1;
                break;
      }
  }
}

// Nachtschaltung - gelbes Dauerblinken in alle Richtungen
void nachtschaltung()
{
  delay(warten3);  
  // dann alle LED ausschalten
  digitalWrite(ledpinRot1, LOW); 
  digitalWrite(ledpinGelb1, LOW);
  digitalWrite(ledpinGruen1, LOW);
  digitalWrite(ledpinRot2, LOW);
  digitalWrite(ledpinGelb2, LOW);
  digitalWrite(ledpinGruen2, LOW);
  digitalWrite(ledpinRot3, LOW);
  digitalWrite(ledpinRot2, LOW);

  // solange der Nachtpin (11) auf LOW liegt
  while (nachtpinStatus == LOW) {

  digitalWrite(ledpinGelb1, HIGH); // 1. Richtung gelb blinken
  digitalWrite(ledpinGelb2, HIGH); // 2. Richtung gelb blinken
  delay(500);
  digitalWrite(ledpinGelb1, LOW); // 1. Richtung gelb blinken
  digitalWrite(ledpinGelb2, LOW); // 2. Richtung gelb blinken
  delay(500);
  // solange in dieser while-Schleife bleiben, bis nachtpinStatus HIGH ist
  nachtpinStatus=digitalRead(nachtpin);
  }
  // Phase zurücksetzen und vor Umlaufstart kurzzeitig Dauergelb
  phase = 1;
  digitalWrite(ledpinGelb1, HIGH); 
  digitalWrite(ledpinGelb2, HIGH); 
  delay(5000);
}

// Steuerung Fußgängerampel
void fussgaenger()
{
  // 3 sek warten, bis Kreuzung geräumt ist
  delay(warten3);
  // Fußgänger bekommen grün
  digitalWrite(ledpinRot3, LOW);
  digitalWrite(ledpinGruen3, HIGH);
  // Dauer der Grünphase für Fußgänger
  delay(fussgruen);
  // danach Fußgängergrün blinken lassen
  // in DE eigentlich unüblich - wer's mag
  for (int i=0; i<=10; i++)
    { 
      digitalWrite(ledpinGruen3, LOW);
      delay(250);
      digitalWrite(ledpinGruen3, HIGH);
      delay(250);
     }
   // Fußgänger bekommen rot
   digitalWrite(ledpinGruen3, LOW);
   digitalWrite(ledpinRot3, HIGH);
   // Status zurücksetzen
   fussStatus = 1;
   }

// Ausführen bei Interrupt
void fussAnforderung() 
{
  // Im Nachtmodus keine Anforderung grün für Fußgänger
  if (nachtpinStatus != LOW)
    {
  // Flag setzen für Auswertung in LOOP-Schleife
      fussStatus = 0;
     }
  }
// das war's ;-)

Die Phasenvariablen können über die warten-Variablen angepaßt werden
 
Hi Peter,

habe den Fehler gefunden! Die Phasen 3 und 5 sind überflüssig und basieren auf einem Fenkdehler - huch - verbuchsel schon die Wechstaben...

Hier nun der korrekte Sketch:

Code:
int ledpinRot1 = 3; // rote led Auto 1
int ledpinGelb1 = 4; // gelbe led Auto 1
int ledpinGruen1 = 5; // gruene led Auto 1
int ledpinRot2 = 6; // rote led Auto 2
int ledpinGelb2 = 7; // gelbe led Auto 2
int ledpinGruen2 = 8; // gruene led Auto 2
int ledpinRot3 = 9; // rote led Fuss 3
int ledpinGruen3 = 10; // gruene led Fuss 3
int fussgruen = 5000; // Dauer Grün Fußgänger
int warten1 = 1000; // Pause 1 sek.
int warten2 = 2000; // Pause 2 sek
int warten3 = 3000; // Pause 3 sek
int warten5 = 5000; // Pause 5 sek
int phase = 1; // Zählvariable
long zeit = 0; // Speicher für Sollzeit
int nachtpinStatus; // Auswertung für Nachtschaltung
const int nachtpin = 11; // Pin11 wertet Nachtpin analog aus
volatile int fussStatus = 1; // auf 0, wenn Fußgängergrün angefordert wurde


void setup() {

pinMode(nachtpin, INPUT); // Pin11 als Eingang - Nachtschaltung
pinMode(ledpinRot1, OUTPUT); // Pin3 als Ausgang
pinMode(ledpinGelb1, OUTPUT); // Pin4 als Ausgang
pinMode(ledpinGruen1, OUTPUT); // Pin5 als Ausgang
pinMode(ledpinRot2, OUTPUT); // Pin6 als Ausgang
pinMode(ledpinGelb2, OUTPUT); // Pin7 als Ausgang
pinMode(ledpinGruen2, OUTPUT); // Pin8 als Ausgang
pinMode(ledpinRot3, OUTPUT); // Pin9 als Ausgang
pinMode(ledpinGruen3, OUTPUT); // Pin10 als Ausgang
attachInterrupt(0, fussAnforderung, FALLING); // Interrupt reagiert auf Übergang nach LOW / GND
Serial.begin(9600);

// Ausgangsposition - alles aus
digitalWrite(ledpinRot1, HIGH); // Richtung 1 - rot
digitalWrite(ledpinRot2, HIGH); // Richtung 2 - rot
digitalWrite(ledpinRot3, HIGH); // Fußgänger - rot
digitalWrite(ledpinGelb1, LOW); // Richtung 1 - gelb
digitalWrite(ledpinGelb2, LOW); // Richtung 2 - gelb
digitalWrite(ledpinGruen1, LOW); // Richtung 1 - Grün
digitalWrite(ledpinGruen2, LOW); // Richtung 2 - Grün
digitalWrite(ledpinGruen3, LOW); // Fußgänger - grün
zeit = millis() + 5000;
}

void loop() 
{

// Nachtschaltung auswerten
  nachtpinStatus = digitalRead(nachtpin);
  
  // definierten Einsprung/Aussprung nur bei Doppelrot
  if (nachtpinStatus == LOW && phase == 1) nachtschaltung();

  // Anforderung Fußgänger auswerten und nur nach dem Umlauf Einsprung ermöglichen
  if (fussStatus == 0 && phase == 1) fussgaenger();

  // Ausgangsposition für Umlauf

  if (millis() > zeit)
  {
      switch ( phase)
      {
          case 1:
                digitalWrite(ledpinRot1, HIGH); // rote led1 einschalten
                digitalWrite(ledpinRot2, HIGH); // rote led2 einschalten
                digitalWrite(ledpinRot3, HIGH); // rote led3 einschalten
                digitalWrite(ledpinGelb1, LOW); // gelbe led1 ausschalten
                digitalWrite(ledpinGelb2, LOW); // gelbe led2 ausschalten
                digitalWrite(ledpinGruen1, LOW); // grüne led1 ausschalten
                digitalWrite(ledpinGruen2, LOW); // grüne led2 ausschalten
                digitalWrite(ledpinGruen3, LOW); // grüne led3 ausschalten
                zeit = millis() + warten3;
                phase = 2;
                break;
          case 2:
                digitalWrite(ledpinRot1, HIGH); //Rot
                digitalWrite(ledpinGelb1,HIGH); //Gelb
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, HIGH); //Rot
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten3;
                phase = 3;
                break;
          case 3:  
                digitalWrite(ledpinRot1, LOW);
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, HIGH); // Grün
                digitalWrite(ledpinRot2, HIGH); // Rot
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten5;
                phase = 4;
                break;
            case 4:
                digitalWrite(ledpinRot1, LOW);
                digitalWrite(ledpinGelb1, HIGH); // Gelb
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, HIGH); //Rot
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten3;
                phase = 5;
                break;
            case 5:
                digitalWrite(ledpinRot1, HIGH); // Rot
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, HIGH); // Rot
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten2;
                phase = 6;
                break;
            case 6:
                digitalWrite(ledpinRot1, HIGH);  // Rot
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, HIGH); // Rot
                digitalWrite(ledpinGelb2, HIGH); // Gelb
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten2;
                phase = 7;
                break;
            case 7:
                digitalWrite(ledpinRot1, HIGH); // Rot
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, LOW);
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, HIGH); // Grün
                zeit = millis() + warten5;
                phase = 8;
                break;
            case 8:
                digitalWrite(ledpinRot1, HIGH); // Rot
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, LOW);
                digitalWrite(ledpinGelb2, HIGH); // Gelb
                digitalWrite(ledpinGruen2, LOW);
                zeit = millis() + warten3;
                phase = 9;
                break;
            case 9:
                digitalWrite(ledpinRot1, HIGH); // Rot
                digitalWrite(ledpinGelb1, LOW);
                digitalWrite(ledpinGruen1, LOW);
                digitalWrite(ledpinRot2, HIGH); // Rot
                digitalWrite(ledpinGelb2, LOW);
                digitalWrite(ledpinGruen2, LOW);
                //zeit = millis() + warten2;
                phase = 1;
                break;
      }
  }
}

// Nachtschaltung - gelbes Dauerblinken in alle Richtungen
void nachtschaltung()
{
  delay(warten3);  
  // dann alle LED ausschalten
  digitalWrite(ledpinRot1, LOW); 
  digitalWrite(ledpinGelb1, LOW);
  digitalWrite(ledpinGruen1, LOW);
  digitalWrite(ledpinRot2, LOW);
  digitalWrite(ledpinGelb2, LOW);
  digitalWrite(ledpinGruen2, LOW);
  digitalWrite(ledpinRot3, LOW);
  digitalWrite(ledpinRot2, LOW);

  // solange der Nachtpin (11) auf LOW liegt
  while (nachtpinStatus == LOW) {

  digitalWrite(ledpinGelb1, HIGH); // 1. Richtung gelb blinken
  digitalWrite(ledpinGelb2, HIGH); // 2. Richtung gelb blinken
  delay(500);
  digitalWrite(ledpinGelb1, LOW); // 1. Richtung gelb blinken
  digitalWrite(ledpinGelb2, LOW); // 2. Richtung gelb blinken
  delay(500);
  // solange in dieser while-Schleife bleiben, bis nachtpinStatus HIGH ist
  nachtpinStatus=digitalRead(nachtpin);
  }
  // Phase zurücksetzen und vor Umlaufstart kurzzeitig Dauergelb
  phase = 1;
  digitalWrite(ledpinGelb1, HIGH); 
  digitalWrite(ledpinGelb2, HIGH); 
  delay(5000);
}

// Steuerung Fußgängerampel
void fussgaenger()
{
  // 3 sek warten, bis Kreuzung geräumt ist
  delay(warten3);
  // Fußgänger bekommen grün
  digitalWrite(ledpinRot3, LOW);
  digitalWrite(ledpinGruen3, HIGH);
  // Dauer der Grünphase für Fußgänger
  delay(fussgruen);
  // danach Fußgängergrün blinken lassen
  // in DE eigentlich unüblich - wer's mag
  for (int i=0; i<=10; i++)
    { 
      digitalWrite(ledpinGruen3, LOW);
      delay(250);
      digitalWrite(ledpinGruen3, HIGH);
      delay(250);
     }
   // Fußgänger bekommen rot
   digitalWrite(ledpinGruen3, LOW);
   digitalWrite(ledpinRot3, HIGH);
   // Status zurücksetzen
   fussStatus = 1;
   }

// Ausführen bei Interrupt
void fussAnforderung() 
{
  // Im Nachtmodus keine Anforderung grün für Fußgänger
  if (nachtpinStatus != LOW)
    {
  // Flag setzen für Auswertung in LOOP-Schleife
      fussStatus = 0;
     }
  }
// das war's ;-)

So kann's kommen - richtig gedacht, falsch gemacht. Da fehlt Routine ;)
Aber die Idee mit case hat's echt gebracht, Für dich ein kleiner Fisch, für mich eine große Erkenntnis!
Wenn ich sehe, was andere hier so auf die Beine stellen, gibt's noch viel zu tun. Auf geht's
 
Hallo lieber Stefan, bin gerade über deinen Bericht gestolpert. :like
Mal ne Frage, gibt es davon zufällig ein Video?
Ich bin nämlich noch am überlegen ob ich nicht auch mal eine Ampelanlage für ne Kreuzung machen könnte.
 
Hallo lieber Stefan, bin gerade über deinen Bericht gestolpert. :like
Mal ne Frage, gibt es davon zufällig ein Video?
Ich bin nämlich noch am überlegen ob ich nicht auch mal eine Ampelanlage für ne Kreuzung machen könnte.

Hi Werner,

nein, es gibt kein Video darüber. Du kannst das aber mit einem Steckbrett, LEDs und Tastern leicht nachbauen und schauen, wie es läuft.
Das Ganze ist aber auch beliebig erweiterbar, z.B. mit Linksabbiegespur, "Kontaktschleifen" etc. Wichtig ist dabei, sich vorher einen Ablaufplan zu zeichnen, sonst kommt es schnell zu "Unfällen", die ja nicht passieren sollten. Mein Sketch ist sicher der eines Anfängers und läßt sich in vielerlei hinsicht noch optimieren. Aber jeder fängt halt irgendwann mal an ;)
Ich kann dich nur ermuntern, eine Ampelsteuerung zu programmieren. Für die Umsetzung reicht eine schnöde Pappe, es sei denn, du hast entsprechende Fertigkeiten, dann geht's sicher auch auf anderen Materialien. Viel Spaß dabei!
 

Servonaut
Zurück
Oben Unten