Autor Beitrag
DerCaptain
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 20.11.12 19:23 
Hallo,
Habe Probleme mit meinem Delphi-Code.
Muss eine Ampelschaltung für eine Kreuzung mit einem if-then-else-if code machen und dabei eine RotGelb-Phase einbringen, die allerdings nur nach dem Rot-Signal ausgelöst wird.
Dabei soll die Rot/Grün-Phase von der waagerecht verlaufenden Strasse 10Sek. betragen und die der vertikal verlaufenden 5Sek.
Die Nebenphasen sollen jeweils 1Sek dauern.
Mein Code bis jetzt:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
procedure TForm1.tiAmpelschaltungTimer(Sender: TObject);
begin
  if imAmpelGruen4.Visible = true
    then begin
           imAmpelGelb1.Visible := false;
           imAmpelGelb3.Visible := false;
           imAmpelGruen2.Visible := false;
           imAmpelGruen4.Visible := false;
           imAmpelRot1.Visible := true;
           imAmpelRot3.Visible := true;
           imAmpelGelb2.Visible := true;
           imAmpelGelb4.Visible := true;
           tiAmpelschaltung.Interval := 5000;
         end
    else if imAmpelGelb4.Visible = true
           then begin
                  imAmpelRot1.Visible := false;
                  imAmpelRot3.Visible := false;
                  imAmpelGelb2.Visible := false;
                  imAmpelGelb4.Visible := false;
                  imAmpelRotGelb1.Visible := true;
                  imAmpelRotGelb3.Visible := true;
                  imAmpelRot2.Visible := true;
                  imAmpelRot4.Visible := true;
                  tiAmpelschaltung.Interval := 10000;
                end
            else if imAmpelRot4.Visible = true
                   then begin
                          imAmpelGelb1.Visible := true;
                          imAmpelGelb3.Visible := true;
                          imAmpelRotGelb2.Visible := true;
                          imAmpelRotGelb4.Visible := true;
                          imAmpelRot2.Visible := false;
                          imAmpelRot4.Visible := false;
                          imAmpelRotGelb1.Visible := false;
                          imAmpelRotGelb3.Visible := false;
                          tiAmpelschaltung.Interval := 1000
                        end
                    else if imAmpelRotGelb4.Visible = true
                           then begin
                                  imAmpelGruen1.Visible := true;
                                  imAmpelGruen3.Visible := true;
                                  imAmpelGelb2.Visible := true;
                                  imAmpelGelb4.Visible := true;
                                  imAmpelRotGelb2.Visible := false;
                                  imAmpelRotGelb4.Visible := false;
                                  imAmpelGelb1.Visible := false;
                                  imAmpelGelb3.Visible := false;
                                  tiAmpelschaltung.Interval := 10000;
                                end

Könnte mir irgendjemand helfen?
Komme mit dem Timing noch nicht so ganz klar und manchmal wird noch immer eine Ampelphase übersprungen.
ub60
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 764
Erhaltene Danke: 127



BeitragVerfasst: Di 20.11.12 19:31 
Mein Tipp:
Stelle das Timer-Intervall auf eine Sekunde und zähle im OnTimer-Event einen Zähler jeweils um 1 höher.
Frage dann den erhaltenen Zähler in der Art ab:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
if Zaehler=10
  then ...
  else if Zahler=12 {oder was immer Deine Werte sind}
    then ...
    else

Besser geht das Ganze noch mit case .. of ...
Zeichne Dir auf alle Fälle eine "Timeline", wann die Ampel welche Zustände haben bzw. umschalten soll.

ub60

Für diesen Beitrag haben gedankt: DerCaptain
platzwart
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1054
Erhaltene Danke: 78

Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
BeitragVerfasst: Di 20.11.12 19:39 
Außerdem...

ausblenden Delphi-Quelltext
1:
if imAmpelGruen4.Visible = true then ...					


...muss korrekt lauten:

ausblenden Delphi-Quelltext
1:
 if imAmpelGruen4.Visible then ...					


Niemals auf true oder false prüfen (bei false dann not verwenden).

_________________
Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)

Für diesen Beitrag haben gedankt: DerCaptain
DerCaptain Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 20.11.12 20:24 
Habe einen neuen Quelltext aufgesetzt,
bei dem ich diesmal die If-Bedingungen mit den Timer-Werten erstellt habe und alles genau nach plan gemacht habe.
Diesmal allerdings Springen Ampelreihe1 und Ampelreihe4 von Gelb auf Rot auf Rotgelb auf Gelb auf Rot und auch bei der Ampelreihe 2 und 3 wird grün übersprungen.
Code:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
procedure TfmKreuzung.tiAmpelschaltungTimer(Sender: TObject);
begin
   if tiAmpelschaltung.Interval = 1000
     then begin
            imAmpelGruen2.Visible := false;
            imAmpelGruen3.Visible := false;
            imAmpelGelb2.Visible := true;
            imAmpelGelb3.Visible := true;
            imAmpelGelb1.Visible := false;
            imAmpelGelb4.Visible := false;
            imAmpelRot1.Visible := true;
            imAmpelRot4.Visible := true;
            tiAmpelschaltung.Interval := 5000
          end
     else if tiAmpelschaltung.Interval = 5000
            then begin
                   imAmpelGelb2.Visible := false;
                   imAmpelGelb3.Visible := false;
                   imAmpelRot2.Visible := true;
                   imAmpelRot3.Visible := true;
                   imAmpelRot1.Visible := false;
                   imAmpelRot4.Visible := false;
                   imAmpelRotGelb1.Visible := true;
                   imAmpelRotGelb4.Visible := true;
                   tiAmpelschaltung.Interval := 10000;
                 end
            else if tiAmpelschaltung.Interval = 10000
                   then begin
                          imAmpelRot2.Visible := false;
                          imAmpelRot3.Visible := false;
                          imAmpelRotGelb2.Visible := true;
                          imAmpelRotGelb3.Visible := true;
                          imAmpelRotGelb1.Visible := false;
                          imAmpelRotGelb4.Visible := false;
                          imAmpelGelb1.Visible := true;
                          imAmpelGelb4.Visible := true;
                          tiAmpelschaltung.Interval := 1000;
                        end
                   else if tiAmpelschaltung.Interval = 1000
                          then begin
                                 imAmpelRotGelb2.Visible := false;
                                 imAmpelRotGelb3.Visible := false;
                                 imAmpelGelb2.Visible := true;
                                 imAmpelGelb3.Visible := true;
                                 imAmpelGelb1.Visible := false;
                                 imAmpelGelb4.Visible := false;
                                 imAmpelGruen1.Visible := true;
                                 imAmpelGruen4.Visible := true;
                                 tiAmpelschaltung.Interval := 5000;
                               end



Edit: Mir ist gerade aufgefallen, dass das eventuell 'was damit zutun haben könnte, dass ich ganz am Ende nochmal die Interval-Eigenschaft verändere?
Werde zunächst den Tipp des Vorposters ausprobieren.

Edit2: Keine Veränderung der Lage.
Besagte Phasen werden immernoch übersprungen.

Moderiert von user profile iconNarses: Beiträge zusammengefasst

Habe es geschafft.
Der Fehler lag darin, dass Delphi immer beim letzten Schritt das die erste Klammerung ausgeführt hat.
Doch ich konnte das Problem lösen indem ich einfach ein Objekt erstellt habe desses Eigenschaften eingebracht habe, um Bedingungen zu erzielen, die sich unterscheiden.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 20.11.12 23:37 
Moin und :welcome: in der EE!

Hast du Interesse das vernünftig zu machen? Oder möchtest du weiter mit dem if-then-else-Intervall rumhampeln? :nixweiss:

Wenn du das ordentlich machen möchtest, sag bescheid, dann ziehen wir das eben in ein paar Minuten durch. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 22.11.12 12:43 
Moin!

Nunja, Beratungsresistenz ist halt eine Anfänger-Krankheit... :| Egal, dann halt für die Nachwelt die Musterlösung:

Zunächstmal machen wir uns einen Plan, wann welche Lampe leuchten soll:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
          R1  Y1  G1  R2  Y2  G2  Dauer
Phase 0   X           X            1
Phase 1   X   X       X            1
Phase 2           X   X           15
Phase 3       X       X            1
Phase 4   X           X            1
Phase 5   X           X   X        1
Phase 6   X                   X   10
Phase 7   X               X        1
Hier steht Y für Gelb, sonst kann man das ja nicht auseinanderhalten. ;)

Dann legen wir ein Demo-Projekt an:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
type
  TForm1 = class(TForm)
    imAmpelRot1: TImage;
    imAmpelGelb1: TImage;
    imAmpelGruen1: TImage;
    imAmpelRot2: TImage;
    imAmpelGelb2: TImage;
    imAmpelGruen2: TImage;
    Timer1: TTimer;
  private
    FPhase: Integer;
    FTakt: Integer;
Wie man sieht, werden 6 Images gebraucht, anlegen und passend benennen, so dass das zwei Ampeln ergibt. Die beiden Klassen-Eigenschaften brauchen wir, um uns die aktuelle Phase und den Takt innerhalb der Phase zu merken.

Hier jetzt der Kern der Sache, der Timer-Ereignishandler:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.Timer1Timer(Sender: TObject);
  const
    TaktSoll: array[0..7of Integer = (
      1115111101
    );
begin
  Inc(FTakt); // nächster Takt
  if (FTakt = TaktSoll[FPhase]) then begin // Laufzeit erreicht?
    FPhase := (FPhase +1mod 8// nächste Phase (8->0)
    FTakt := 0// aber erster Takt in dieser Phase
    // pro Lampe aufzählen, wann sie leuchten soll:
    imAmpelRot1.Visible   := FPhase in [014567];
    imAmpelGelb1.Visible  := FPhase in [13];
    imAmpelGruen1.Visible := FPhase in [2];
    imAmpelRot2.Visible   := FPhase in [012345];
    imAmpelGelb2.Visible  := FPhase in [57];
    imAmpelGruen2.Visible := FPhase in [6];
  end;
Wir zählen in FTakt die Anzahl Timer-Ereignisse. Wenn die Anzahl der Vorgabe für diese Phase entspricht, dann wird zur nächsten Phase geschaltet. Beim Phasenübergang ist dann die Sichtbarkeit der Lampen anzupassen. Dazu liest man die Tabelle einfach Spaltenweise für die entsprechende Lampe ab. :idea:

Und noch etwas Kosmetik für die Initialisierung:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.FormCreate(Sender: TObject);

  procedure SetColor(AImage: TImage; const AColor: TColor; const AVisible: Boolean = TRUE);
  begin
    AImage.Picture.Bitmap.Canvas.Brush.Color := AColor;
    AImage.Picture.Bitmap.Width := AImage.Width;
    AImage.Picture.Bitmap.Height := AImage.Height;
    AImage.Picture.Bitmap.Canvas.Rectangle(AImage.Canvas.ClipRect);
    AImage.Visible := AVisible;
  end;

begin
  SetColor(imAmpelRot1, clRed);
  SetColor(imAmpelRot2, clRed);
  SetColor(imAmpelGelb1, clYellow, FALSE);
  SetColor(imAmpelGelb2, clYellow, FALSE);
  SetColor(imAmpelGruen1, clLime, FALSE);
  SetColor(imAmpelGruen2, clLime, FALSE);

Bei Fragen - fragen! ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.

Für diesen Beitrag haben gedankt: ub60