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



BeitragVerfasst: So 08.04.12 17:56 
Habe mit dem Velleman Board K8055 mit Delphi ein Programm geschrieben für eine Ampelsteuerung, nun möchte ich das die CheckBox1 automatisch auf CheckBox2, dann auf CheckBox3 im 5sec. Takt wandert und am Ende auf CheckBox1 wieder stehen bleibt. Hab an den CheckBoxen am Velleman Board meine LEDs angeschlossen, also meine Ampel ROT GELB GRÜN, sie leuchten auch, wenn ich CheckBox1 anklicke, aber irgendwie bekomme ich es nicht zum wandern, wie bei einer Richtigen Ampel, brauche eure Hilfe !
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 08.04.12 22:33 
Moin und :welcome: in der EE!

Schonmal in die Suche geschaut? Suche in: Delphi-Forum, Delphi-Library AMPELSTEUERUNG :les: :think:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
FinnO
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Mo 09.04.12 13:01 
Moin,

Mich beschleicht auch irgendwie das Gefühl, dass man das Board nicht direkt über die Checkboxen steuert, sondern eher, dass im OnClick der Checkboxen irgendeine Funktion aufgerufen wird, die die Ausgänge des Boards schaltet. Aber das ist natürlich nur Spekulation, man müsste schon wissen, welches Board du benutzt und wie dein bisheriger Code aussieht.

LG
runnersteffen Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Sa 14.04.12 22:39 
Hab es hinbekommen, es geht auch über die CheckBoxen ! Aber Danke für eure Hilfe…
haentschman
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 285
Erhaltene Danke: 33


DX10 Berlin Professional
BeitragVerfasst: So 15.04.12 11:09 
Moin...
Zitat:
Hab an den CheckBoxen am Velleman Board meine LEDs angeschlossen

Da mich das technisch interessiert...kannst du mal ein Foto davon machen ? :roll:

Für diesen Beitrag haben gedankt: Blawen, Narses
runnersteffen Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Fr 11.05.12 19:44 
Es geht... hier mein Code von der ersten Ampel !!!
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:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
//Timer 1 für Ampel1
procedure TForm1.Timer1Timer(Sender: TObject);
begin
    CheckBox9.Checked := ReadDigitalChannel(1);

if (CheckBox1.Checked=true) and (CheckBox2.Checked=false) and (Checkbox3.Checked=false) Then
Begin
    //Ampel 1 und 3 schaltet von Rot auf Gelb
    CheckBox1.Checked :=true;
    CheckBox2.Checked :=true;

    CheckBox3.Checked :=false;
    timer1.interval:=1000;

    //Ampel 2 und 4 schaltet von Grün auf Gelb
    CheckBox4.Checked :=false;
    CheckBox5.Checked :=true;
    CheckBox6.Checked :=true;
    timer1.interval:=1000;

end
    else if(CheckBox2.Checked=true) and (CheckBox1.Checked=true) and (Checkbox3.Checked=false)
            then begin
                //Ampel 1 und 3 steht auf Grün
                CheckBox1.Checked :=false;
                CheckBox2.Checked :=false;
                CheckBox3.Checked :=true;
                timer1.interval:=2000;

                //Ampel 2 und 4 steht auf Rot
                CheckBox4.Checked :=true;
                CheckBox5.Checked :=false;
                CheckBox6.Checked :=false;
                timer1.interval:=2000;

              end
              else if(CheckBox3.Checked=true) and (CheckBox1.Checked=false) and (Checkbox2.Checked=false)
                   then begin
                    //Ampel 1 - 4 schalten auf Gelb
                    CheckBox1.Checked :=false;
                    CheckBox2.Checked :=true;
                    CheckBox3.Checked :=false;
                    timer1.interval:=1000;

                    CheckBox4.Checked :=false;
                    CheckBox5.Checked :=true;
                    CheckBox6.Checked :=false;
                    timer1.interval:=1000;

                   end

                   else begin

                        //Ampel 1 und 3 schaltet auf Rot
                        CheckBox1.Checked :=true;
                        CheckBox2.Checked :=false;
                        CheckBox3.Checked :=false;
                        timer1.Interval:=2000;

                        //Ampel 2 und 4 schaltet auf Grün
                        CheckBox4.Checked :=false;
                        CheckBox5.Checked :=false;
                        CheckBox6.Checked :=true;
                        timer1.Interval:=2000;

                        Timer1.Enabled :=False; //schaltet die Schleife aus
                        end

end;


Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt
Moderiert von user profile iconNarses: BMP->PNG
Einloggen, um Attachments anzusehen!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Sa 12.05.12 00:37 
Moin!

user profile iconrunnersteffen hat folgendes geschrieben Zum zitierten Posting springen:
die Ampelkreuzung habe ich auf einer Pappschachtel aufgebaut und mit LEDs bestückt...
Davon hätte ich ja gerne mal das Foto gesehen, weil:
user profile iconhaentschman hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Hab an den CheckBoxen am Velleman Board meine LEDs angeschlossen
Da mich das technisch interessiert...kannst du mal ein Foto davon machen ? :roll:
Ich glaube kaum, dass man an einer Checkbox (die es auf dem Velleman-Board auch gar nicht gibt) eine LED anschließen kann... :zwinker: ;)


user profile iconrunnersteffen hat folgendes geschrieben Zum zitierten Posting springen:
Es geht... hier mein Code von der ersten Ampel !!!
Da du offensichtlich Anfänger bist, aber Hardware dabei ist, kannst du eigentlich nur aus der technischen Richtung (irgend eine technische Fachschule oder sowas) kommen. Mich wundert aber, dass man dich derart alleine oder offensichtlich ohne jegliche Vorbereitung auf so ein Projekt loslässt. :?

Du hast da einige Probleme im Code, auch wenn für dich vermutlich erstmal nur das "geht-doch"-Prinzip zählt. Lass dir einen Rat geben: nach dem "geht-doch"-Prinzip programmieren, wird dir irgendwann den Hals brechen (und wenn du mal Aufzugsteuerungen oder Airbuscomputer baust, vielleicht sogar uns allen :lol:)... :|

Da ich an meinem Hals hänge, hier ein paar Tipps, was man besser machen kann: :idea: :)

user profile iconrunnersteffen hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
if (CheckBox1.Checked=trueand (CheckBox2.Checked=falseand (Checkbox3.Checked=falseThen					
Niemals (zumindest in Delphi) Booleans auf TRUE oder FALSE vergleichen, sondern direkt als logischen Wert verwenden. Willst du auf FALSE vergleichen, dann nimm ein NOT dazu:
ausblenden Delphi-Quelltext
1:
if (CheckBox1.Checked and NOT CheckBox2.Checked and NOT Checkbox3.Checked) then					


user profile iconrunnersteffen hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
    CheckBox3.Checked :=false;
    timer1.interval:=1000;
    //...
    timer1.interval:=1000;
Mehrfaches Zuweisen des selben Wertes bringt nix. :nixweiss:

user profile iconrunnersteffen hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
Timer1.Enabled :=False; //schaltet die Schleife aus					
Das ist keine Schleife, sondern ein Timer, also eine Komponente, die in einstellbaren Zeitabständen ein Ereignis produziert. Eine Schleife ist ein Sprachkonstrukt, also z.B: for oder repeat-until. :idea:


Gut, sind genau genommen Kleinigkeiten. Was ich aber wirklich bedenklich finde, ist die Tatsache, dass du offensichtlich noch nichts von einer Zustandssteuerung gehört hast (oder wenn, erfolgreich ignoriert). :shock: Und das bei so starkem Technikbezug. :gruebel: Dein Ansatz ist auf dem Level "geht so grade", aber das kann doch nicht das Ziel gewesen sein. Ich würde mich als Betreuer mit dieser "Lösung" nicht zufrieden geben, das ist ineffizient und fehleranfällig. :!:

Nunja, Meckern ohne Besser-Machen geht nicht, also hier mein Vorschlag, wie man das lösen könnte. ;) Ich hatte allerdings keinen Bock, das Velleman-Board vom Boden zu holen und auf dem Steckbrett mit LEDs zu hantieren, also mal nur der programmtechnische Teil, die Hardware wirst du hoffentlich alleine angesteuert bekommen (ich schätze nämlich mal, du hast dir die (grauslige) Demo-Anwendung von Velleman genommen und "umgebaut", die ist aber so schlecht gemacht, davon brauchst du eigentlich nur die Hardware-Connect/Disconnect-Prozeduren, der Rest kann getrost weg).

Zunächst mal, ohne irgendetwas anderes zu betrachten, machen wir uns mal einen Gedanken, was denn da passieren soll:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
// Codierungstabelle
// Wert: 128  64  32  16   8   4   2   1
// Bit:    7   6   5   4   3   2   1   0
// LED:    ?   ?  G2  Y2  R2  G1  Y1  R1   :Dezimalwert
// State0:         0   0   1   0   0   1   :   8+1= 9
// State1:         0   0   1   0   1   1   : 8+2+1=11
// State2:         0   0   1   1   0   0   :   8+4=12
// State3:         0   0   1   0   1   0   :   8+2=10
// State4:         0   0   1   0   0   1   :   8+1= 9
// State5:         0   1   1   0   0   1   :16+8+1=25
// State6:         1   0   0   0   0   1   :  32+1=33
// State7:         0   1   0   0   0   1   :  16+1=17
// State0:         0   0   1   0   0   1   :   8+1= 9
const
  ChannelData: array[0..8of Integer = ( 911121092533179 );
Du hast dich dafür entschieden, die LEDs an die Ausgänge wie oben abgebildet anzuschließen, wobei die über kreuz stehenden Ampeln vermutlich parallel aufgeschaltet sind, so dass jeweils 2 LEDs gegenüberliegend gleich leuchten. Guter Ansatz. ;)

Du hast in deinem Code vermutlich die Checkboxen und -Handler von der Velleman-Demo drin gelassen und dann deinen Ansatz zur Ansteuerung dazu geschrieben. Das ist allerdings "suboptimal". :? Es ist wesentlich effizienter, die Methode WriteAllDigital() zu verwenden und damit gleich alle Ausgänge auf einmal umzuschalten. :idea: Wozu sollte es auch gut sein, die LEDs nacheinander umzuschalten (auch wenn das so schnell geht, dass man es mit dem bloßen Auge nicht sieht)? Es erzeugt unnötig viele Hardwarezugriffe und damit nutzlos Last auf dem Bus. :nixweiss:


In der Tabelle haben wir einfach notiert, welche LED wann an sein soll, dann die Bitwerte addiert und als Dezimalzahl einem Status zugeordnet. In der Konstantendeklaration unter der Tabelle zählen wir einfach nur die ermittelten Werte für das Steuerregister auf. Das war schon der schwierigste Teil! :D

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
type
  TForm1 = class(TForm)
    Button1: TButton; // startet einen Ampel-Zyklus
    Timer1: TTimer; // Zeitgeber (.Enabled = FALSE, .Interval=1000)
    Edit1: TEdit; // Ausgabe-Simulation
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    FAmpelState: Integer; // hier merken wir uns den aktuellen Ampel-Zustand
  public
    { Public-Deklarationen }
  end;
Das ist mein Demo-Formular, da liegt nur ein Button, ein Editfeld als Hardware-Simulation und ein Timer als Zeitgeber drauf. Kann man natürlich nach Belieben weiter dekorieren... ;)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
// Einen Ampel-Zyklus starten
procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1.Enabled := FALSE; // solange ein Zyklus läuft, ist der Button aus
  FAmpelState := 0// beim ersten Status anfangen
  Timer1Timer(Self); // direkt den ersten Status setzen, sonst 1 Interval warten
  Timer1.Enabled := TRUE; // Zeitgeber aktivieren
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  WriteAllDigital(ChannelData[FAmpelState]); // Daten an die Hardware geben
  Inc(FAmpelState); // nächster Ampel-Status
  if (FAmpelState > High(ChannelData)) then begin // Ende erreicht?
    Timer1.Enabled := FALSE; // Timer ausschalten
    Button1.Enabled := TRUE; // Button wieder an machen
  end;
end;
Jetzt zu den spannenden Sachen: Beim Button-Klick passiert noch nicht viel, hier wird der Startzustand 0 gesetzt, direkt einmal der Timer-Handler aufgerufen (sonst wird die erste Ausgabe erst verzögert gemacht) und dann der Timer aktiviert, so dass der Handler regelmäßig wieder aufgerufen wird.

Die eigentliche "Arbeit" passiert aber im Timer-Ereignis-Handler: Als erstes wird er aus der Tabelle ermittelte Zustand der Digitalkanäle auf einmal an die Hardware übertragen (es gibt eine entsprechende Prozedur beim dem Velleman-Zeugs dazu, solltest du direkt so übernehmen können). Dann wird der nächste Zustand der Ampel bestimmt (simpel: +1) und geschaut, ob es diesen Zustand überhaupt noch gibt. Wenn nicht, ist der Zyklus abgelaufen, also den Timer stoppen, damit keine weiteren Ereignisse mehr erzeugt werden und den Button wieder aktivieren.

Ich sehe allerdings gerade, dass du unterschiedliche Zeiten für die Ampelphasen verwendet hast. Das habe ich jetzt nicht umgesetzt, aber ein bischen was kannst du ja auch selbst noch ergänzen, oder? :zwinker: :zustimm:
Tipp: Einfach ein zweites, konstantes Array anlegen, dass die Zeit zu dem Zustand speichert. Wenn du es ganz schick machen willst, kannst du auch ein record definieren, dass Status und Zeit enthält und daraus ein konstantes Array machen. Das ist aber schon nicht mehr ganz simpel. 8)

cu
Narses
Einloggen, um Attachments anzusehen!
_________________
There are 10 types of people - those who understand binary and those who don´t.