Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Ampelschaltung mit Delphi über Com Port (https://www.delphipraxis.net/148177-ampelschaltung-mit-delphi-ueber-com-port.html)

ruebach 24. Feb 2010 09:45


Ampelschaltung mit Delphi über Com Port
 
Hallo ihrs,
ich bzw. wir haben ein Problem.
Wir wollen für den Informatikunterricht eine Ampelschaltung bauen und programmieren.
Das Bauen war kein Problem. Es ist auch schon gelötet.
Unser Problem liegt jetzt bei der Programmierung, da wir nicht wirklich Ahnung davon haben.
Wir haben uns zwar durch viele Foren und Infoseiten gesucht, aber nichts gefunden, was uns wirklich weiterhilft, da es meistens nur in Delphi programmiert und dargestellt wurde oder ein anderes Beispiel für die Portbenutzung genommen wurde, die mit unserem nichts zu tun hat.

Danke im voraus.

haentschman 24. Feb 2010 09:59

Re: Ampelschaltung mit Delphi über Com Port
 
Hallo... :hi:

welche Schnittstelle habt ihr vorgesehen ? (Parallel, Seriell, USB)

ruebach 24. Feb 2010 10:00

Re: Ampelschaltung mit Delphi über Com Port
 
Hi erstmal schon Danke für die Antwort und Aufmerksamkeit :)
Wir wollen über eine serielle gehen. RS232

jfheins 24. Feb 2010 10:02

Re: Ampelschaltung mit Delphi über Com Port
 
Was habt ihr denn für eine Schaltung? Also welche Daten muss man dem Mikrocontroller senden? Oder sind die LED's direkt an die Schnittstelle angeschlossen?

Grundsätzlich würde ich mir an deiner Stelle ein funktionierendes Beispiel hernehmen und die Stelle suchen, an der der neue Zustand der Ampel gesetzt wird und das dann per COM-Port verschicken.

ruebach 24. Feb 2010 10:03

Re: Ampelschaltung mit Delphi über Com Port
 
Die LED's sind direkt angeschlossen.

Jaynder 24. Feb 2010 10:10

Re: Ampelschaltung mit Delphi über Com Port
 
Alle LEDs einzeln? wie viele ComPorts habt ihr denn, weil schaltbar sind höchstens zwei der Leitungen (DTR, DSR)

ruebach 24. Feb 2010 10:14

Re: Ampelschaltung mit Delphi über Com Port
 
Hä?
Also wir haben ne Schaltung, mit einer 4er-Kreuzung, wobei an jeder Seite eine Ampel mit Grün und Rot angebracht ist. Die gegenüberliegenden LEDs haben wir miteinander verbunden, also jeweils die gegenüberliegenden roten und grünen. So haben wir noch 4 Eingänge und 4 Ausgänge. Ich weiß nicht, wie weit man das jetzt dann noch weiter verbinden müsste und könnte. Nutzen wollten wir nur einen ComPort

jfheins 24. Feb 2010 10:22

Re: Ampelschaltung mit Delphi über Com Port
 
4 Ausgänge? Was wollt ihr denn ausgeben?

Also wenn ihr nur rot und grün habt, dann sollte es relativ simpel sein: Ihr könnt ja jeweils 4 LED's in Reihe schalten (2 mal grün für links/rechts und 2 mal rot für oben/unten)
Dann braucht ihr nur noch 2 Pins zu beschalten ;)

Btw.: Ich hoffe ihr habt die nicht direkt angeschlossen sondern einen passenden Vorwiederstand berechnet - ansonsten grillt ihr eure LED's ;)

himitsu 24. Feb 2010 10:26

Re: Ampelschaltung mit Delphi über Com Port
 
Allgemein sollte man das Problem erstmal aufteilen.

- Berechnung/Simulation der Ampelsteuerung
- Ansteuerung der Elektronik

Ampelschaltung gibt es schon einige Fertige, welche eventuell man nur noch an die Hardware anpassen müßte.
- So daß die Simulation die selben Signale und Aufteilung (also die Lämpchen und Co.) besitzt.
Also daß auf dem Monidor das Selbe vorhanden ist, wie eure reale Anlage hat.

Nun braucht man noch Ansteuerung der Anlage.
- Dafür müßte man wissen, was und wie ihr es an den PC angeschlossen habt.

Und nun muß nur noch die Simulation mit der Anlage verbunden werden.
- Praktisch: Wird eine "Lampe" auf dem Monitor als angeschaltet dargestellt, dann muß diese in der Anlage auch angeschaltet werden.

haentschman 24. Feb 2010 10:28

Re: Ampelschaltung mit Delphi über Com Port
 
Hallo...

ich würde euch da in etwa so etwas Relaiskarte empfehlen.
Vorteile:
- galvanische Trennung vom Computer
- mehrere Möglichkeiten zum Schalten
- Lastunabhängig (Schalten von größeren Lasten)

Edit: Softwarebeispiele dabei :thumb:

ruebach 24. Feb 2010 12:46

Re: Ampelschaltung mit Delphi über Com Port
 
Also Vorwiderstand haben die LED ^^ gegrillt werden sie also beim Anschluss an den Computer (hoffentlich) nicht, zu mindestens nicht, nach unseren Versuchen und Berechnungen.

Die Idee das ganze erstmal intern in Delphi zu machen, bzw. da auch anzeigen zu lassen finde ich gut. Hatte ich heute auch mal der Gruppe vorgeschlagen. So haben wir im Notfall mindestens etwas ^^ interne Programmierung läuft ja einigermaßen.
Ein Problem wird dann aber glaube ich weiterhin sein, wie wir das ganze dann als Signal an die LEDs bekommen.

Die Sache mit den Relaiskarte finde ich jetzt nicht so gut. Es kann zwar sein, dass ich den Mund jetzt zu voll nehme, aber es sollte laut unseren Informationen auch ohne diese gehen.
Aber trotzdem danke.

himitsu 24. Feb 2010 13:05

Re: Ampelschaltung mit Delphi über Com Port
 
Wenn ihr das Ganze OOP-mäßig gestaltet, dann könntet ihr euch einige Objekte erstellen

z.B.
Delphi-Quellcode:
type TAmpelStatus = (asRot, asRotGelb, asGelb, asGruen, asGelbBlinkend);
  TAmpel2 = class
  private
    x, y:     Integer; // die Koordinaten, wo sie auf dem Bildschirm gezeichnet wird
    PortRot:  Integer; // die Adressen der entsprechenden LED
    PortGruen: Integer; //
    Status:   TAmpelStatus;
  public
    Constructor Erstelle(x, y: Integer; PortRot, PortGruen: Integer);
    Procedure Umstellen(NeuerStatus: TAmpelStatus);
    Prozedure Zeichne(Zeichenflaeche: TCanvas);
  end;
  TAmpel3 = class
  private
    x, y:     Integer; // die Koordinaten, wo sie auf dem Bildschirm gezeichnet wird
    PortRot:  Integer; // die Adressen der entsprechenden LED
    PortGelb: Integer; //
    PortGruen: Integer; //
    BlinkerAn: Boolean; // einfach bei jedem Zeichnen umschalten und zusammen
    Status:   TAmpelStatus;      // mit asGelbBlinkend auf das Gelb anwenden
  public
    Constructor Erstelle(x, y: Integer; PortRot, PortGelb, PortGruen: Integer);
    Procedure Umstellen(NeuerStatus: TAmpelStatus);
    Prozedure Zeichne(Zeichenflaeche: TCanvas);
  end;
Die Komponenten wissen wie sie selber aussehn und welche LEDs sie ansteuern müssen.
Somit muß sich das Steuerprogramm nicht darum kümmern.

Jetzt könnt ihr im Programm einfach alle nötigen Ampeln erzeugen und jede Ampel kann sich dann selber auf eine Zeichenfläche malen und die zugehörigen LEDs ansteuern.
Dann braucht ihr nur noch das Programm erstellen, welches diese Komponenten ansteuert.

Jaynder 24. Feb 2010 13:19

Re: Ampelschaltung mit Delphi über Com Port
 
@ruebach
Zitat:

Die Sache mit den Relaiskarte finde ich jetzt nicht so gut. Es kann zwar sein, dass ich den Mund jetzt zu voll nehme, aber es sollte laut unseren Informationen auch ohne diese gehen.
Wird es nicht, COM ist eine Datenschnittstelle für serielle Bit-Sequenzen, und außer den beiden Steuerleitungssignalen DTR und DSR mit +/-12V kannst du dort nichts schalten, und die auch nur, wenn du den Steuerchip der Schnittstelle direkt per Assembler ansprichst, normalerweise werden die von der Treibersoftware intern entsprechend des Datenflusses dynamisch ein und ausgeschaltet. Nimm die Relaiskarte und du hast 'ne Chance.

Tonic1024 24. Feb 2010 13:43

Re: Ampelschaltung mit Delphi über Com Port
 
Also als Ex-Elektroniker und Informatiker möchte ich nur ganz kurz was dazu sagen.

Ein paar Fakten:
  • Die Serielle Schnittstelle benötigt ein Schieberegister oder Microcontroller um sinnvoll signale raus zu bekommen.
  • Beim vergewaltigen der DSteuerleitungen solltet ihr bedenken, dass zwar gut Spannung aber quasi kein Strom bereitgestellt wird. Könnte sein, dass die LEDs so schwach leuchten, dass sie faktisch immer aus sind/bleiben.
  • Sch**ß auf die ollen LEDs. Ohne ordentliche Trennung der Signale vom PC habt ihr ruck zuck eier Board gegrillt.
  • genau darum hat man früher den Parallelport für solche Spielchen verwendet. Da musste man aber trotzdem einen Treibertransistor verwenden und ne externe Spannungsversorgung weil auch hier die Power nicht reichte.
  • Unter Vista/Win7 kann man den Parallelport nicht mehr direkt ansteuern. XP bin ich nicht sicher.

Nehmt ne billige Schnittstellenkarte. Mit Relais oder ohne spielt keine Rolle.


Gruß,

Toni

himitsu 24. Feb 2010 13:47

Re: Ampelschaltung mit Delphi über Com Port
 
Über den seriellen und vorallem den parallelen (Drucker) Port könnte man zwar direkt Signale abgreifen, aber wenn da was schief läuft, dann könnte man sich auch schnell mal das Mainboard zerschießen.

[edit]
das Internet ist heute komisch ... vorhin war der Beitrag von Tonic1024 noch nicht da,
aber ich kann ihm nur vollkommen zustimmen und rate von soeinem Vorhaben ab.

gammatester 24. Feb 2010 14:10

Re: Ampelschaltung mit Delphi über Com Port
 
Zitat:

Zitat von Jaynder
Wird es nicht, COM ist eine Datenschnittstelle für serielle Bit-Sequenzen, und außer den beiden Steuerleitungssignalen DTR und DSR mit +/-12V kannst du dort nichts schalten, und die auch nur, wenn du den Steuerchip der Schnittstelle direkt per Assembler ansprichst, normalerweise werden die von der Treibersoftware intern entsprechend des Datenflusses dynamisch ein und ausgeschaltet.

Ich weiß zawr nicht, was Du benutzt, aber zB mit TComport kann man schon seit ewigen Zeiten auf darauf zugreifen
Delphi-Quellcode:
    property FlowControl: TFlowControl read GetFlowControl write SetFlowControl stored False;
    property OutCTSFlow: Boolean read FOutCTSFlow write SetOutCTSFlow;
    property OutDSRFlow: Boolean read FOutDSRFlow write SetOutDSRFlow;
    property ControlDTR: TDTRFlowControl read FControlDTR write SetControlDTR;
    property ControlRTS: TRTSFlowControl read FControlRTS write SetControlRTS;
    property DSRSensitivity: Boolean
      read FDSRSensitivity write SetDSRSensitivity default False;

Jaynder 24. Feb 2010 14:14

Re: Ampelschaltung mit Delphi über Com Port
 
Oh, gut zu wissen. Habe nur so eine asbach-Komponente namens TSerialPort. Aber das ganze Thema ist zum Glück inzwischen komplett out.

martin_ 25. Feb 2010 09:07

Re: Ampelschaltung mit Delphi über Com Port
 
Zitat:

Zitat von himitsu
Wenn ihr das Ganze OOP-mäßig gestaltet, dann könntet ihr euch einige Objekte erstellen

z.B.
Delphi-Quellcode:
type TAmpelStatus = (asRot, asRotGelb, asGelb, asGruen, asGelbBlinkend);
  TAmpel2 = class
  private
    x, y:     Integer; // die Koordinaten, wo sie auf dem Bildschirm gezeichnet wird
    PortRot:  Integer; // die Adressen der entsprechenden LED
    PortGruen: Integer; //
    Status:   TAmpelStatus;
  public
    Constructor Erstelle(x, y: Integer; PortRot, PortGruen: Integer);
    Procedure Umstellen(NeuerStatus: TAmpelStatus);
    Prozedure Zeichne(Zeichenflaeche: TCanvas);
  end;
  TAmpel3 = class
  private
    x, y:     Integer; // die Koordinaten, wo sie auf dem Bildschirm gezeichnet wird
    PortRot:  Integer; // die Adressen der entsprechenden LED
    PortGelb: Integer; //
    PortGruen: Integer; //
    BlinkerAn: Boolean; // einfach bei jedem Zeichnen umschalten und zusammen
    Status:   TAmpelStatus;      // mit asGelbBlinkend auf das Gelb anwenden
  public
    Constructor Erstelle(x, y: Integer; PortRot, PortGelb, PortGruen: Integer);
    Procedure Umstellen(NeuerStatus: TAmpelStatus);
    Prozedure Zeichne(Zeichenflaeche: TCanvas);
  end;

Hallo,
nachdem ich den Code gelesen habe, ergibt sich für mich folgende Frage:
Der Unterschied zwischen den beiden Klassen ist nur das eine blinken kann und die andere nicht.
Also für weitere Betrachtungen wird die erste Klasse verwendet. Wie funktioniert das mit dem Typ TAmpelStatus und der Procedure umstellen?

himitsu 25. Feb 2010 09:46

Re: Ampelschaltung mit Delphi über Com Port
 
Nja, der Unterschied war jetzt eher Fußgängerampel mit Rot/Grün und eine Ampel mit Rot/Gelb/Grün.

Ideal wäre natürlich, wenn alle Ampeln von einem Basisobjekt abgeleitet werden, damit man für alle die selbe Schnittstelle hat.

Das Umschalten wäre jetzt einfach durch Zuweisen eines der Stati möglich.
Das Objekt würde dann in der Prozedur entsprechend des Wertes seine Anzeige/Ausgänge/LEDs umstellen.



Delphi-Quellcode:
type
  TAmpelStatus = (asAllesAus, asRot, asRotGelb, asGelb, asGruen, asGelbBlinkend);
  TAmpelBasis = class
    procedure Umstellen(NeuerStatus: TAmpelStatus); virtual; abstract;
    procedure ZeichneNeu; virtual; abstract;
  end;
  TAmpelRotGruen = class(TAmpelBasis)
  private
    fBild:     TCanvas;
    fX, fY:    Integer;   // die Koordinaten, wo sie auf dem Bildschirm gezeichnet wird
    fGeraet:   TIrgendwas; // Schnittstelle zum Ausgabegerät;
    fPortRot:  Integer;   // die Adressen der entsprechenden LED
    fPortGruen: Integer;   //
    fStatus:   TAmpelStatus;
  public
    constructor Erstelle(Zeichenflaeche: TCanvas; x, y: Integer;
      Geraet: TIrgendwas; PortRot, PortGruen: Integer);
    procedure Umstellen(NeuerStatus: TAmpelStatus); override;
    procedure ZeichneNeu; override;
  end;
  TAmpelRotGelbGruen = class(TAmpelBasis)
  private
    fX, fY:    Integer; // die Koordinaten, wo sie auf dem Bildschirm gezeichnet wird
    fPortRot:  Integer; // die Adressen der entsprechenden LED
    fPortGelb: Integer; //
    fPortGruen: Integer; //
    fBlinkerAn: Boolean; // einfach bei jedem Zeichnen umschalten und zusammen
    fStatus:   TAmpelStatus;      // mit asGelbBlinkend auf das Gelb anwenden
  public
    constructor Erstelle(Zeichenflaeche: TCanvas; x, y: Integer;
      Geraet: TIrgendwas; PortRot, PortGelb, PortGruen: Integer);
    procedure Umstellen(NeuerStatus: TAmpelStatus); override;
    procedure ZeichneNeu; override;
  end;

constructor TAmpelRotGruen.Erstelle(Zeichenflaeche: TCanvas; x, y: Integer;
  Geraet: TIrgendwas; PortRot, PortGruen: Integer);
begin
  fBild     := Zeichenflaeche;
  fX        := x;
  fY        := y;
  fGeraet   := Geraet;
  fPortRot  := PortRot;
  fPortGruen := PortGruen;
  fStatus   := asAllesAus;
  Zeichne;
end;

procedure TAmpelRotGruen.Umstellen(NeuerStatus: TAmpelStatus);
begin
  fStatus := NeuerStatus;
  case fStatus of
    asAllesAus: begin
      fGeraet.Aus(fPortRot);
      fGeraet.Aus(fPortGruen);
    end;
    asRot: begin
      fGeraet.An(fPortRot);
      fGeraet.Aus(fPortGruen);
    end;
    asGruen: begin
      fGeraet.Aus(fPortRot);
      fGeraet.An(fPortGruen);
    end;
    else raise Exception.Create('diesen Status gibt es hier nicht');
  end;
  Zeichne;
end;

procedure TAmpelRotGruen.Zeichne;
begin
  ZeichneRahmenUndWasSonstNochBenötigtWird(fBild);
  case fStatus of
    asRot: ZeichneRotesLicht(fBild);
    asGruen: ZeichneGruenesLicht(fBild);
  end;
end;

// Ampel erstellen
Liste.Add(TAmpelRotGruen.Erstelle(Canvas, 100, 50, Geraet, 1, 2));

// erste Ampel umstellen
Liste[0].Umstellen(asRot);

// alles neu zeichnen
for i := 0 to Liste.Count - 1 do
  Liste[i].Zeichne;

// alles auf Grün stellen (bitte nicht nachmachen)
for i := 0 to Liste.Count - 1 do
  Liste[i].Umstellen(asGruen);
Vorteil ist eben, daß man jetzt einfach für jedes Ampel, welche es in "real" gibt, ein passendes Objekt erstellt, diesem mittteilt welche LEDs zu ihm gehören und so das Steuerprogramm nicht wissen muß, wie es welche LEDs ansteuert.

Im Steurprogramm wird dann z.B. über einen Timer das Programm gefahren und einfach nur noch die Objekte angesteuert
Delphi-Quellcode:
Liste[0].Umstellen(asRot);
Liste[2].Umstellen(asRot);
'ne Sekunde später dann noch
Liste[1].Umstellen(asGruen);
Liste[3].Umstellen(asGruen);
...
(z.B. 'ne Kreuzung mit 4 Ampeln)

martin_ 25. Feb 2010 10:55

Re: Ampelschaltung mit Delphi über Com Port
 
Danke. Die Sache mit der Vererbung ist mir klar. Nur wie kommt man auf die Idee sich für die Zustände eigene Typen zu erstellen? Als Zustände eigenen sich nur Konstanten, die immer gleich sind und an verschiedenen Stellen im Projekt (auch mit unterschiedlichen Ausprägungen) benötigt werden. Gibt es sonst noch eine allgemein anwendbare Regel, wann ein eigener Typ (wie TAmpelStatus) verwendet werden kann? Bzw. wie geht man vor um sie zu finden?

himitsu 25. Feb 2010 11:15

Re: Ampelschaltung mit Delphi über Com Port
 
Soein Enumerator/Typ hat den Vorteil, daß er leicht verständliche Werte besitzt und er gleichzeitig vom Programm einfach verarbeitet werden kann.

Statt TAmpelStatus könnte man sich auch einen Integer nehmen und dann alle Zustände jeweils einzeln als Konstante anlegen, aber so hatt man alles zusammengehörend und der Compiler mekert, wenn da was Falsches angegeben wird.
Die Konstanten weglassen und überall einfach nur Zahlen verwenden ginge auch, aber am nächsten Tag weiß dann keiner mehr, was z.B. eine "123" irgendwo zu bedeuten hatte.

Gut, TAmpelStatus als String und alles als Text ist auch möglich, aber es ist dann auch schwerer/umständlicher ausuwerten.

Alternativ könnte man den Objekten auch getrennte An/Aus-Funktionen für die einzelnen LEDs verpassen, aber dann muß das Steuerprogramm mehrere Eingänge ansteuern und so hat es nur einen Zugang pro Objekt.

gemeinsamer LED-Status:
+ nur ein Wert anzusteuern
- man muß vorher Festlegen welche Kombinationen der LEDs es pro Ampel gibt

getrennte LED-Stati
+ man kann vom Steuerprogramm jede LED gezielt steuern ohne Kombinationsmuster (Status-Werte) anlegen zu müssen
- man muß mehrere Eingänge ansteuern, welches die Ansteuerung aufwändiger macht


Im Prinzip ist es ein Abwegen der Vor- und Nachteile
und danach entscheidet man sich für einen Weg.

Je stärker die einzelnen Module voneinander getrennt sind, um so einfacher lassen sich diese unabhängig voneinander entwickeln und testen.
Ist alles sehr stark miteinander verbunden und voneinander abhängig, dann geht sowas nicht.

So könnte man z.B. erstmal die Ampelmodule erstellen und kann dann z.B. TAmpelRotGruen zusammen mit einer realen Ampel ganz alleine Testen, oder auch nur einen Code vom Steuerprogramm fertig zu haben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz