Nieprawidłowe działanie programu, przy zmianie czasu timera

0

Witam, próbuję stworzyć w delphi model skrzyżowania, na którym zmieniały by się światła drogowe.
Program wygląda tak, że dodałem sobie elementy geometryczne tworzące skrzyżowanie i światła drogowe, następnie dodałem timery i każdy z timerów odpowiada za zmianę kolorów w sygnalizacji świetlnej.

Problemy są 2:

  1. Gdy tylko włączę program najpierw wykonywane są 2 pierwsze sekwencje, potem leci od początku i potem działa już normalnie tak jak powinno (to jest przypadek gdy wszystkie timery mają te same opóźnienie).

  2. Gdy zmienię opóźnienia np. w 2 timerach program zaczyna wariować, tzn wykonywane są losowe sekwencje.

Dodam, że korzystam z Lazarusa IDE v1.0.14, windows xp.

0

Bez kodu ciężko cokolwiek wywróżyć. Sam napisałem sobie tylko kiedyś prosty symulator z bodajże dwoma przejściamy dla pieszych. Nic wymyślnego. Jeśli poczekasz do jutra wieczora to mogę zapodać swoje wypociny. Tymczasem wrzuć kod to pewnie ktoś spojrzy.

0

fajnie, a czego oczekujesz od nas?

0
unit First;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Shape1: TShape;
    Shape10: TShape;
    Shape11: TShape;
    Shape12: TShape;
    Shape13: TShape;
    Shape14: TShape;
    Shape15: TShape;
    Shape16: TShape;
    Shape17: TShape;
    Shape18: TShape;
    Shape19: TShape;
    Shape2: TShape;
    Shape20: TShape;
    Shape21: TShape;
    Shape22: TShape;
    Shape23: TShape;
    Shape24: TShape;
    Shape25: TShape;
    Shape26: TShape;
    Shape27: TShape;
    Shape28: TShape;
    Shape29: TShape;
    Shape3: TShape;
    Shape30: TShape;
    Shape31: TShape;
    Timer1: TTimer;
    Timer2: TTimer;
    Timer3: TTimer;
    Timer4: TTimer;
    Timer5: TTimer;
    Timer6: TTimer;
    Timer7: TTimer;
    Timer8: TTimer;
    Zielone1: TShape;
    Zolte1: TShape;
    Czerwone1: TShape;
    Zielone2: TShape;
    Zolte2: TShape;
    Czerwone2: TShape;
    Shape38: TShape;
    Shape39: TShape;
    Shape4: TShape;
    Czerwone3: TShape;
    Zolte3: TShape;
    Zielone3: TShape;
    Zielone4: TShape;
    Zolte4: TShape;
    Czerwone4: TShape;
    Shape46: TShape;
    Shape47: TShape;
    Zielonep8: TShape;
    Czerwonep8: TShape;
    Shape5: TShape;
    Shape50: TShape;
    Czerwonep7: TShape;
    Zielonep7: TShape;
    Shape53: TShape;
    Zielonep6: TShape;
    Czerwonep6: TShape;
    Shape56: TShape;
    Czerwonep5: TShape;
    Zielonep5: TShape;
    Shape59: TShape;
    Shape6: TShape;
    Czerwonep1: TShape;
    Zielonep1: TShape;
    Czerwonep2: TShape;
    Zielonep2: TShape;
    Shape64: TShape;
    Zielonep3: TShape;
    Czerwonep3: TShape;
    Shape67: TShape;
    Czerwonep4: TShape;
    Zielonep4: TShape;
    Shape7: TShape;
    Shape70: TShape;
    Shape8: TShape;
    Shape9: TShape;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure Timer3Timer(Sender: TObject);
    procedure Timer4Timer(Sender: TObject);
    procedure Timer5Timer(Sender: TObject);
    procedure Timer6Timer(Sender: TObject);
    procedure Timer7Timer(Sender: TObject);
    procedure Timer8Timer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
//
end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Zielone1.Brush.Color:=clsilver;
  Zielone2.Brush.Color:=clsilver;
  Zolte1.Brush.Color:=clyellow;
  Zolte2.Brush.Color:=clyellow;
  Timer1.Enabled:=false;
  Timer2.Enabled:=true;


end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin

  Zolte1.Brush.Color:=clsilver;
  Zolte2.Brush.Color:=clsilver;
  Czerwone1.Brush.Color:=clred;
  Czerwone2.Brush.Color:=clred;
  Zielonep5.Brush.Color:=clsilver;
  Zielonep6.Brush.Color:=clsilver;
  Zielonep7.Brush.Color:=clsilver;
  Zielonep8.Brush.Color:=clsilver;
  Czerwonep5.Brush.Color:=clred;
  Czerwonep6.Brush.Color:=clred;
  Czerwonep7.Brush.Color:=clred;
  Czerwonep8.Brush.Color:=clred;
  Timer2.Enabled:=false;
  Timer3.Enabled:=true;
end;

procedure TForm1.Timer3Timer(Sender: TObject);
begin

  Zolte3.Brush.Color:=clyellow;
  Zolte4.Brush.Color:=clyellow;
  Timer3.Enabled:=false;
  Timer4.Enabled:=true;
end;

procedure TForm1.Timer4Timer(Sender: TObject);
begin
  Zielone3.Brush.Color:=cllime;
  Zielone4.Brush.Color:=cllime;
  Zolte3.Brush.Color:=clsilver;
  Zolte4.Brush.Color:=clsilver;
  Czerwone3.Brush.Color:=clsilver;
  Czerwone4.Brush.Color:=clsilver;
  Zielonep1.Brush.Color:=cllime;
  Zielonep2.Brush.Color:=cllime;
  Zielonep3.Brush.Color:=cllime;
  Zielonep4.Brush.Color:=cllime;
  Czerwonep1.Brush.Color:=clsilver;
  Czerwonep2.Brush.Color:=clsilver;
  Czerwonep3.Brush.Color:=clsilver;
  Czerwonep4.Brush.Color:=clsilver;
  Timer4.Enabled:=false;
  Timer5.Enabled:=true;
end;

procedure TForm1.Timer5Timer(Sender: TObject);
begin
  Zielone3.Brush.Color:=clsilver;
  Zielone4.Brush.Color:=clsilver;
  Zolte3.Brush.Color:=clyellow;
  Zolte4.Brush.Color:=clyellow;
  Timer5.Enabled:=false;
  Timer6.Enabled:=true;
end;

procedure TForm1.Timer6Timer(Sender: TObject);
begin
  Zolte3.Brush.Color:=clsilver;
  Zolte4.Brush.Color:=clsilver;
  Czerwone3.Brush.Color:=clred;
  Czerwone4.Brush.Color:=clred;
  Zielonep1.Brush.Color:=clsilver;
  Zielonep2.Brush.Color:=clsilver;
  Zielonep3.Brush.Color:=clsilver;
  Zielonep4.Brush.Color:=clsilver;
  Czerwonep1.Brush.Color:=clred;
  Czerwonep2.Brush.Color:=clred;
  Czerwonep3.Brush.Color:=clred;
  Czerwonep4.Brush.Color:=clred;
  Timer6.Enabled:=false;
  Timer7.Enabled:=true;
end;

procedure TForm1.Timer7Timer(Sender: TObject);
begin
  Zolte1.Brush.Color:=clyellow;
  Zolte2.Brush.Color:=clyellow;
  Timer7.Enabled:=false;
  Timer8.Enabled:=true;
end;

procedure TForm1.Timer8Timer(Sender: TObject);
begin
  Zielone1.Brush.Color:=cllime;
  Zielone2.Brush.Color:=cllime;
  Zolte1.Brush.Color:=clsilver;
  Zolte2.Brush.Color:=clsilver;
  Czerwone1.Brush.Color:=clsilver;
  Czerwone2.Brush.Color:=clsilver;
  Zielonep5.Brush.Color:=cllime;
  Zielonep6.Brush.Color:=cllime;
  Zielonep7.Brush.Color:=cllime;
  Zielonep8.Brush.Color:=cllime;
  Czerwonep5.Brush.Color:=clsilver;
  Czerwonep6.Brush.Color:=clsilver;
  Czerwonep7.Brush.Color:=clsilver;
  Czerwonep8.Brush.Color:=clsilver;
  Timer8.Enabled:=false;
  Timer1.Enabled:=true;
end;

end.

Dodam tylko dla podpowiedzi, że skrzyżowanie składa się z 4 sygnalizatorów dla samochodów i 8 dla pieszych. Prosze o wyrozumiałość to mój pierwszy program.

dodanie znacznika <code class="delphi"> + usunięcie źródła pliku *.dfm - fp

1

Kod programu jest nieco krótszy niż moje pierwsze kółko i krzyżyk, ale to nie powód do dumy.
Ta aplikacja cię przerasta na tym poziomie wiedzy - dokończ kurs/książkę podstaw języka, przede wszystkim funkcje/procedury.
Zrób sobie procedurę do zmiany świateł 1 sygnalizatora i podawaj jako parametr tylko komponent lub płótno czy identyfikator tego właśnie sygnalizatora oraz rodzaj zmiany np. czerwone, żółte, zielone, żółte z czerwonym.
Kolejna sprawa to to, że po starcie aplikacji wszystkie timmery zaczynają "tykać" równocześnie (są domyślnie ustawione na true) a chyba twoją intencją jest aby początkowo tylko timer 1 był enabled. Kodu nie mam zamiaru analizować bo jest do kitu.

0

Ja to może i nice ponarzekam, ale według mnie każdy sygnalizator powinien być klasą, w której będzie dostępna metoda np. Step, która zmieni stan świateł na kolejne; Timer mógłby być jeden, który każdemu sygnalizatorowi co pewien czas wywoła tę metodę, przez co całość będzie się idealnie zgrywać; Będzie to taki prosty pokaz pracy świateł - nic skomplikowanego;

Podsuwam ten pomysł dlatego że nie sądzę, aby pytacz chciał zrobić coś bardziej skomplikowanego, jak np. różny czas palenia się zielonego czy czerwonego światła itd.; Choć i tak z klasami świateł będzie problem...

@zibi687 - wydaje mi się, że wybrałeś sobie za trudny program na Twój stan wiedzy dotyczącej programowania w OP.

0

zastosuj wyłączanie timerów...

często przy niskim czasie intervala następuje po prostu "samowzbudzenie"

timer zaczyna działać od początku zanim zdąży wykonać procedury zawarte w OnTimer

spróbuj np tak

przy początku procedury (onTimer) wyłączamy timer

Timer1.Enabled := False;

przy koncu procedury OnTimer

dajemy

Timer1.Enabled := True;

zapobiega to "wznowieniu" wykonywania procedury OnTimer zanim zakonczy się wykonywać

a na pewno progs będzie działał stabilnie

dodanie znaczników <code class="delphi"> - fp

1

Zibi, przerób program tak, aby użyć tyko jednego timera.
W procedurze ontime sprawdzaj ile czasu mineło od ostatniej zmianty świateł - jeśli nastał czas kolejnej zmiany świateł - zmiana.
Czas ostatniej zmianay świateł, jakie to były światła (jakie mają być następne) zapamiętaj w jakichś zmiennych.
Im mniej timerów tym lepiej.

0

Poniżej jest przedstawiony ABSOLUTNIE CAŁY kod z dowolną logiką, wystarczy wypełnić tabelkę:

var Sem:array[0..7]of record R,Y,G:TShape; end; // to ma być w klasie

const Tb:array[0..7]of record time:Integer; Sem:array[0..7]of record R,Y,G:Boolean; end; end= // całość logiki masz w tej tablice - trzeba z głową wytpełnić
  (
   (time:2000;Sem:((R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false))),
   (time:2000;Sem:((R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false))),
   (time:2000;Sem:((R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false))),
   (time:2000;Sem:((R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false))),
   (time:2000;Sem:((R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false))),
   (time:2000;Sem:((R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false))),
   (time:2000;Sem:((R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false))),
   (time:2000;Sem:((R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false),(R:false;Y:false;G:true),(R:true;Y:false;G:false),(R:false;Y:true;G:false)))
  );
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Sem[0].R:=Czerwone1;
  Sem[0].Y:=Zolte1;
  Sem[0].G:=Zielone1;

  Sem[1].R:=Czerwone2;
  Sem[1].Y:=Zolte2;
  Sem[1].G:=Zielone2;

... // reszta tak samo, można też w pętli przez findcomponent

  Sem[7].R:=Czerwone8;
  Sem[7].Y:=Zolte8;
  Sem[7].G:=Zielone8;
  Timer.Tag:=0;
  Timer.Interval:=50;
  Timer.Enabled:=true;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var T,I:Integer;
begin
  T:=Timer.Tag;
  T.Interval:=Tb[T].Time;
  for I:=0 to 7 do
  begin
     if Tb[T].Sem[I].R then Sem[I].R.Brush.Color:=clRed else Sem[I].R.Brush.Color:=clSilver;
     if Tb[T].Sem[I].Y then Sem[I].Y.Brush.Color:=clYellow else Sem[I].Y.Brush.Color:=clSilver;
     if Tb[T].Sem[I].G then Sem[I].G.Brush.Color:=clLime else Sem[I].G.Brush.Color:=clSilver;
  end; 
  Timer.Tag:=(T+1)and(7); // można (T+1)mod(8);
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1