AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Parellelport-Tutorial
Tutorial durchsuchen
Ansicht
Themen-Optionen

Parellelport-Tutorial

Ein Tutorial von Matze · begonnen am 15. Jun 2006 · letzter Beitrag vom 5. Okt 2006
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Matze
Matze
Registriert seit: 7. Jul 2003
Dieses Tutorial wird unter der freundlichen Genehmigung von Martin Vogel hier veröffentlicht. Ich habe es in die BBCode-Fassung gebracht, da ein Word-Dokument hier nicht unbedingt geeignet war. Kleinere Dinge wurden von mir angepasst und Syntax-Fehler behoben.

Das Tutorial und die Grafiken stammen von Martin Vogel. Leider funktioniert der Code nicht unter Windows 2000/XP, da diese Windows-Versionen keine direkten Port-Zugriffe gestatten.

__________________________________________________ _________


Vorwort

Seit langer Zeit suche ich nach einer schnellen Datenerfassung per PC. Ein USB Experimentierplatinchen von Conrad ist zwar leicht zu integrieren und lässt eine kleine Steuerung für eine Eisenbahn zu, aber soll's denn etwas einfaches und schnelles sein, dann fällt mir nur der Druckerport ein. Nix gegen Mikro-Controler, aber da hab ich noch keine Erfahrung mit und ich kann den Aufwand nicht abschätzen, um zum Ergebnis zu gelangen. Da ich auch das Problem habe, dass meine Anwendung nur bis Win98 taugt, (dann braucht's Treiber) , hab ich mich entschlossen, einen alten PC herzunehmen, ihn zu vernetzen und dann die Experimente halt auf dem "Billigteil" durchzuführen.
Also, ich hätt da schon Lust, ein wenig Elektronikpraxis und auch Programmiertechnik zu vermitteln. Wobei letzteres, der Informatiker möge es mir nachsehen, nicht auf einem Studium an der Uni basiert, sondern auf autodidaktische Fleißarbeit gründet. Da sind dann schon mal kleine formelle Ausrutscher möglich. An solchen Stellen bin ich dankbar für Hinweise.
Aber nun zum eigentlichen Thema. Auf der Suche nach brauchbaren Treibern für NT, XP oder 2000 hab ich die vielen Probleme beim Zugriff auf den Parallelport zu lesen bekommen und habe mich entschlossen, sowohl bei Hard- als auch bei Softwarefragen zu helfen. Allerdings. Wer von mir einen "vernünftigen" Treiber erwartet, Fehlanzeige. Im Moment bin ich nicht in der Lage, weder von der Software als auch vom Wissen her, dieses anzubieten. Daher verweise ich immer bei solchen "Experimenten" mit der Hardware, nehmt einen alten PC mit Win95 oder 98. Da gibt’s dieses Problem nicht und ihr lauft auch nicht Gefahr, euren neuesten PC zu erden.
Treiber wie IOPort , IO.Dll oder ähnliche haben scheinbar ein paar Nachteile, die den Experten die Nackenhaare zu Berge stehen lassen..... , allerdings weiß ich nicht, was gegen diesen Einsatz spricht,
wo die meisten doch sowieso keine professionellen Programme schreiben, bzw. dies auch aufgrund ihrer Lizenz nicht können. Und was ich privat mit meinem Blechdiener anfange....
Egal, ich wollt halt das mal kurz erwähnen, damit man mir nicht gleich mein Zusammengeschriebenes um die Ohren haut....
Dieser Text soll ja auch nur einen kleinen Einblick in die elektrischen Vorgänge und Hintergründe geben, ohne gleich mit der gesamten Bandbreite zu verwirren. Ich hoffe, doch verständlich geblieben zu sein und euch nachvollziehbare Hinweise gegeben zu haben. Falls nicht, fragt nach, aber erwartet nicht immer gleich eine Antwort, da ich nebenbei noch'n bisschen arbeiten muss.....
 
Benutzerbild von Matze
Matze

 
Turbo Delphi für Win32
 
#2
  Alt 15. Jun 2006, 17:37
Tutorial

Etwas Theorie

Der Wunsch, Experimente mit dem Druckerport durchzuführen, setzt ein wenig Kenntnis der Elektrik voraus und so werde ich mit einem kleinen Kurs die "elektrische Digitaltechnik" ansprechen. Und ohne Grundsatz geht auch da gar nix, also bitte merken:
  • 1.Grundsatz:
    Der Strom fließt immer im Kreis, daher der Name "Stromkreis".
    Dies bedeutet: Wo ein Plus, da muss auch ein Minus her.
  • 2.Grundsatz:
    Die Höhe der Spannungsquelle ist immer die Maximalspannung in einer Schaltung.
    Es geht nicht, durch Verschaltung mehrerer Leitungen eine höhere Spannung zu erzeugen.
  • 3.Grundsatz:
    Auch wenn es im Moment vielleicht nicht so klar ist, es gibt 3 elektrische Zustände:
    an Plus gebunden, an Minus gebunden und ! elektrisch neutral.

Bevor mich die Elektriker jetzt eine dumme Nuss nennen, ich habe absichtlich Begriffe wie Plus, Minus und neutral verwendet, zumal ich nicht die Absicht habe, Wechselstromtechnik einfließen zu lassen.
Die Bezeichnung aus Schaltungen wie Vcc (Plus) und Gnd (Minus) sind auch nicht unbedingt besser.

Nun ein wenig Praxis:

Wir nehmen einen Wechselschalter und schließen wie folgt an:


http://dp.matthias-hielscher.de/tuto...llel_tut_1.gif

Es ist erkennbar, das die Leitung S (Signal) entweder ein Plus-
oder ein Minuspotential hat.Bei dieser Schalung ist es egal, wie
der Schalter steht, es leuchtet immer eine Lampe, und so ist es,
die Leitung S führt entweder einen H(igh) oder L(ow) Potential.



Nun nehmen wir einen 3 stufigen Schalter:


http://dp.matthias-hielscher.de/tuto...llel_tut_2.gif

Und schon ist's Essig mit entweder oder.... es gibt einen
Zustand, da ist nix auf der Leitung. Und So sieht's dann auch
in der Praxis aus, es gibt einen Zustand, der ist nicht H(igh)
oder L(ow). Der ist "neutral". Und diese 3 Schaltzustände nennt
man "tristate", weil's englisch halt besser klingt.



Aber warum ist nun dieser "tristate" so wichtig ? Nun, ich zeichne die Schaltung mal etwas anders:


http://dp.matthias-hielscher.de/tuto...llel_tut_3.gif

Und wir korrigieren etwas die Bezeichnungen, und schon haben
wir ein tristate-Element. Egal wie der Wechselschalter steht,
erst mit CS (Chipselect) wird das Signal durchgeschaltet. Aber
was macht das eigentlich für einen Sinn? Nicht unbedingt beim
Einmaleins des kleinen Elektrikers, aber in der Computertechnik.



Ich zeig's euch:


http://dp.matthias-hielscher.de/tuto...llel_tut_4.gif

Sind zwar nur zwei Nibble, aber mit ein wenig Vorstellungskraft
kann man sich bis zu ein paar Millionen solcher Schaltungen 8 Bit
breit auf einem gemeinsamen Leitungsbus vorstellen, oder......



Aber wir wollen ja gar nicht Millionen Speicherzellen anschließen, lediglich mal 8 oder 16 Relais steuern und vielleicht ein paar Schalter abfragen und deshalb reicht so eine kleine Einführung auch schon fast aus, um mit der Bastelei zu beginnen.
Wir kennen die Bedeutung von H(igh) und L(ow) Signalen sowie den "dritten" Signalzustand. Wir sollten uns noch merken, dass eine Anzahl von Leitungen mit gemeinsamer Bedeutung "Bus" genannt wird.
z.B. Datenbus, Adressbus, Steuerbus um die wichtigsten beim Namen zu nennen. Und damit hat jede Leitung eine Wertigkeit aufgrund ihrer eigenen Position in der Rangordnung.
Machen wir einen kleinen Step zur dualen Mathematik. Diese kennt nur 2 Zahlen. Die "0" und die "1"
analog zu den Spannungspotentialen der Leitung L(ow) und H(igh).
Gerechnet wird also mit der Basis 2 entsprechend der Potentialzustände L und H sowie dem Exponenten angegeben in der Nummer der Leitung. Und wir beginnen die Zählung der Leitungen mit "0".
Eine Regel der Mathematik sagt, dass x hoch 0 immer 1 ist. So sieht die Formel für Leitung mit der Nummer 0 wie Folgt aus: 2 hoch 0 mal Signalzustand (1 oder 0).
Verallgemeinern wir es etwas: Basis (ist wie wir wissen 2) hoch Leitungsnummer mal Signalzustand.

Nehmen wir an:

4 Leitungen:
Leitung 0 = 1, Leitung 1 = 0, Leitung 2 = 1 und Leitung 3 = 1 ('1101')

Code:
So lautet die Rechnung: 2 hoch 0*1 + 2 hoch 1*0 + 2 hoch 2*1 +  2 hoch 3*1
Ist                       1*1     +    2*0     +    4*1     +     8*1      = 13
Wer Spaß an Mathe hat, der kann ja mal 8 Leitungen (ab jetzt Bit), 16 Bit oder gar 32 Bit berechnen.
So, jetzt wissen wir auch, wie die Zahlen in den Computer kommen.
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze

 
Turbo Delphi für Win32
 
#3
  Alt 15. Jun 2006, 17:41
Machen wir folgenden Versuch:

Angenommen wir haben auf die Datenbits im Parallelport Schalter angeklemmt, diese von 0 bis 7 nummeriert, und wollen nun wissen, wie ich den Schalter im Computer zuordnen kann. Gehen wir davon aus, jeder hat schon mal auf den Port zugegriffen und weiß, wie das geht und er hat nun einen Wert in der Variablen ReadLPTPort stehen.

ReadLPTPort wie folgt deklariert

ReadLPTPort: Byte Kleines Beispiel:

Delphi-Quellcode:
asm
  Mov DX, $378h // Portadresse in DX Register schreiben
  In AL, DX // Port in AL Register lesen
  Mov ReadLPTPort, AL // Wert aus AL Register in Variable eintragen
end;
Natürlich kann man davon auch eine Function machen und den Wert darüber einlesen, aber das machen wir später. Hier geht es um etwas anderes.
Wie kann ich erkennen, welche Schalter hinter dem Wert 163 z. B. stehen.
Und jetzt geb ich euch eine Function.

function Byte_To_Str(ByteWert: Byte): string; Na, ist das was? Na gut, geb ich euch eben den zugehörigen Quellcode.

Delphi-Quellcode:
function Byte_To_Str(Byte_Val: Byte): string;
var
  CalcWert : Integer;
  Ausg : string;
begin
  Ausg := '';
  CalcWert := Byte_Val;

  repeat
    if CalcWert / 2 = Trunc(CalcWert / 2) then
      Ausg := '0' + Ausg
    else
      Ausg := '1' + Ausg; // Darauf achten: Der String wächst von hinten !
    Calcwert := Trunc(CalcWert / 2);
  until Calcwert = 0;

  while Length(Ausg) < 8 do // Wir wollen doch den ganzen Port also 8 Bit
    Ausg := '0' + Ausg;

  Byte_To_Str := Ausg;
end;
Also, die Integerzahl 163 wird durch 2 geteilt und geprüft, ob sie gerade oder ungerade war. Bei einer ungeraden Zahl ergibt sich ein Rest von 1 bzw. bei einer geraden eben ein Rest 0. Diese Werte werden von hinten in einen String eingetragen und die Rechnung mit dem ganzen halben Wert wiederholt. Solange, bis nur noch 0 übrigbleibt.

Klartext:

Code:
163 / 2 = 81 Rest 1     String ="1"               ("1")
81 / 2  = 40 Rest 1     String = "1" + String     ("11")
40 / 2  = 20 Rest 0     String = "0" + String     ("011")
20 / 2  = 10 Rest 0     String = "0" + String     ("0011")
10 / 2  = 5 Rest 0     String = "0" + String     ("00011")
5 / 2   = 2 Rest 1     String = "1" + String     ("100011")
2 / 2   = 1 Rest 0     String = "0" + String     ("0100011")
1 / 2   = 0 Rest 1     String = "1" + String     ("10100011")
Die Abfrage nach der Länge des String ist nur bei kleineren Zahlen notwendig, um den String mit vorstelligen "0"en aufzufüllen. Der String zeigt nun, dass Schalter S7, S5, S1 und S0 geschaltet sind. Das ist doch was, oder....

Wenn ihr wollt:

Edit1.Text := Byte_To_Str(ReadLPTPort); Und weil ich es schon hab und ihr es auch wollt, gleich die Kehrseite, nämlich die "1" aus einem String

zum Ansteuern von irgendwas nehmen:

Delphi-Quellcode:
function Str_To_Byte(Str_Val: string): Byte;
var
  i : Integer;
  Ausg : Real;
begin
  Ausg := 0;
  for i := 0 to Length(Str_Val) - 1 do
    if Str_Val[Length(Str_Val) - i] = '1then
      Ausg := Ausg + Power(2, i); // dies ist die Function 2 hoch n (uses Math)
  Str_To_Byte := Trunc(Ausg);
end;
Funktioniert folgendermaßen:

String hat den Wert "10100011", sagen wir mal, den Wert der eingelesenen Schalter.
Um ein bisschen unabhängig von der Stringlänge zu sein, lassen wir die Schleife bis zur Länge des Strings laufen, und da wir bei 0 anfangen, muss es natürlich auch Length(String)-1 lauten.

for i := 0 to Length(Str_Val) - 1 do ... Beachte:

Bei längeren Strings ist die Function mit anderem Typ zu deklarieren, weil Bytewerte nur bis 255 gehen, nicht, dass mir dann unterstellt wird, meine Function könnte nicht rechnen....

Also: Ist das letze Zeichen-Laufzähler (im String = 1 dann ist die die Summenvariable = Summenvariable + 2 hoch Laufzähler. Dies erledigt die

Function Power(Basis, Exp).
Delphi-Quellcode:
if Str_Val[Length(Str_Val) - i] = '1then
  Ausg := Ausg + Power(2, i); ...
Sie liefert allerdings einen Realwert, daher muss der Ausgang letztlich mittels Trunc-Function zugewiesen werden.
So, damit haben wir schon die Möglichkeit in einem Textfeld Bits anzusehen oder zu setzen. Vereinbaren wir nun ein Ausgabe-Byte für den Port.

WriteLPTPort: Byte; Dann könnte die Ausgabe eines Textfeldes an den LPT1 folgendermaßen lauten:

Delphi-Quellcode:
WriteLPTPort := Str_To_Byte(Edit1.Text);
asm
  Mov DX, $378
  Mov AL, WriteLPTPort
  Out DX, AL
end;
So, hat doch was.
Ich hab jetzt Schalter, die über einen komplizierten und teuren Rechner und einem mit einem nicht minder teuren Entwicklungstool geschriebenen Programm Relais schalten.....
Wer's einfacher haben will, der sollte direkt mit den Schaltern sein Licht an- und ausknipsen....
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze

 
Turbo Delphi für Win32
 
#4
  Alt 15. Jun 2006, 18:04
Wir haben aber noch lange nicht fertig, denn jetzt wird's ja erst interessant......
Zuerst trennen wir mal den gelesenen Wert und den Ausgabewert, indem wir für den Ausgabewert ein zweites Editfeld einbauen und der Ausgabe dieses übergeben:

Delphi-Quellcode:
WriteLPTPort := Str_To_Byte(Edit2.Text);
asm
  Mov DX, $378
  Mov AL, WriteLPTPort
  Out DX, AL
end;
Deklarieren wir weitere globale Variablen

Delphi-Quellcode:
Work_Str_In : string;
Work_Str_out : string; // In CreateForm wird Wert "00000000" zugewiesen
So, und nun kann ich auf dem Weg, Relais anzusteuern mit den gelesenen Bit einiges anstellen....
z.B.

Delphi-Quellcode:
Work_Str_In := Edit1.Text;

if ((Work_Str_In[2] = '1') and (Work_Str_In[5] = '1') or (Work_Str_In[7] = '1')) and (FormatDateTime('hh:nn:ss', Time) = '11:00:00') then Work_Str_Out[1] := '1else ... ???
(neee, else hier bitte nicht, da ihr sonst u.U. aufgrund der Zeitabfrage nix zu sehen bekommt)....
besser ist da die eigene Rücksetzbedingung.....

if (Work_Str_In[2] = '0') then Work_Str_Out[1] := '0'; Aber da könnt ihr euch ja nun mächtig austoben und allemöglichen Kreuz- und Knüppelschaltungen ausprobieren. Nur nicht vergessen:

Delphi-Quellcode:
Edit2.Text := Work_Str_Out;
WriteLPTPort := Str_To_Byte(Edit2.Text);

asm
  Mov DX, $378
  Mov AL, WriteLPTPort
  Out DX, AL
end;
Ach ja, ich glaube, hier ist es angebracht, WriteLPTPort zur Procedure zu machen....

Delphi-Quellcode:
procedure WriteLPTPort(Port: Word; Byte_Out: Byte);
begin
  asm
    Mov DX, Port
    Mov AL, Byte_Out
    Out DX, AL
  end;
end;
... und ReadLPTPort zur Function

Delphi-Quellcode:
function ReadLPTPort(Port: Word): Byte;
begin   
  asm
    Mov DX, Port // Portadresse in DX Register schreiben
    In AL, DX // Port in AL Register lesen
    Mov ReadLPTPort, AL // Wert aus AL Register in Variable eintragen
  end;
end;
Jetzt heißt es :

Delphi-Quellcode:
WriteLPTPort($378, Str_to_Byte(Edit2.Text));
  ..........
Edit1.Text := Byte_To_Str(ReadLPTPort($378));
  ..........
Tja, wenn da nicht...
Der Parallelport von Hause aus ein Ausgabeport wäre und es ist nicht immer gesagt, das ReadLPTPort

($378)
das gewünschte Ergebnis bringt. Aber der Hersteller hat sich etwas einfallen lassen und in

den meisten Fällen sollte es funktionieren....
Man setze Bit 5 im Steuerregister auf '1'. Nicht jedes teure Buch verrät diesen Trick, aber wie sonst sollte ein Scanner der alten Generation z. B. Daten über den Parallelport in den PC schieben...

So setzt man vor die Zeile

Edit1.Text := Byte_To_Str(ReadLPTPort($378)); Eine Anweisung:

WriteLPTPort($37A, Str_to_Byte('00100xx1')); Diese 2 'x' sind Bits, mit denen ich den Eingabekanal adressiere, also das CS-Signal bilde, und die Portbuffer in Richtung zum Parallelport durchschalte. Um zu verhindern, das der Portbuffer gegen den Parallelport durchschaltet, gibt es 2 Möglichkeiten:
Einmal: Ich schalte den Portbuffer immer auf Ausgabe, nur für die kurze Zeit zum Einlesen gebe ich die
Richtung zum Port frei, oder ich lege 100 Ohm – Widerstände in die Datenleitung zwischen Portbuffer und Parallelport. Das brät mir wenigstens den Portbaustein nicht weg, falls die Signale mal gegeneinander stehen....

So, nun mal ein kompletter Einlesevorgang:

Delphi-Quellcode:
WriteLPTPort(37Ah, Str_to_Byte('00100xx1'));
Edit1.Text := Byte_To_Str(ReadLPTPort($378));
WriteLPTPort(378h, Str_to_Byte('00000xx0'));
Aber wieso muss nun Bit 5 und Bit 0 gesetzt, bzw. zurückgesetzt werden. Ganz einfach, Bit 5 steht am Parallelport nicht zur Verfügung und ist intern zur Steuerung im Portchip verschaltet. Bit 0 hat aber für Drucker die Bedeutung, dass Daten abgeholt werden können. Wir müssen dem Portchip sagen, es kommen
Daten von außen und die Portbuffer in die Richtung schalten.
Also, Bit 5 für den Portchip und Bit 0 für die Portbuffer.
Mit den Bit 1 und 2 werden die Kanäle selektiert. Die Erklärung und Beispiele folgen später.

Da es mit einem Interrupt auf dem LPT-Port nicht ganz so einfach ist, muss die Funktion ReadLPTPort zyklisch von einer Timerroutine aufgerufen werden. Also, 10ms sollten nicht unterschritten werden, damit das Programm nicht zu sehr ausgebremst wird. Für viele Anwendungen reicht
eine 100ms Abtastung völlig aus. Die Zuweisung eines Ausgangs wird vom Programm ausgelöst.

Um mal ein Beispiel zu nennen, Steuerungen von Maschinen lesen zuerst die Eingangskarten und legen die Information in einem Speicher ab. Dann erfolgt die Bearbeitung mit Ablage der Ergebnisse in einem weiteren Speicherbereich. Nach Abarbeitung wird der gesamte bearbeitete Speicher zu den Ausgangskarten
übertragen.

Kurz:
- Eingänge lesen
- Programm bearbeiten
- Ausgänge schreiben

Und wieder erneut
- Eingänge lesen
...........

und genau dies können wir auch mit einem Programm erreichen, aber ein PC ist nun mal keine Maschinensteuerung und da kommt's schon mal vor, die Festplatte möchte sich mal wieder drehen, die Grafik hätte auch gern wieder etwas Bewegung im Speicher und auch sonst sind diverse nützliche und unnütze Treiber lustig dabei, Zeit für sich zu beanspruchen. Aus diesem Grund ist es Sinnvoll, einen Timer zu benutzen und in regelmäßigen Zeitspannen auf Änderungen der gelesenen Information zu reagieren.
Schließlich soll der Zug ja im Bahnhof anhalten und nicht zufällig auf irgendeinem Teilstück der riesigen Modelbahnanlage......
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze

 
Turbo Delphi für Win32
 
#5
  Alt 15. Jun 2006, 18:07
Um nun nicht jedesmal alle Bits vom Eingang testen zu müssen, ist es sinnvoll, abzufragen, ob überhaupt eine Änderung stattgefunden hat. Dies erledigt eine Function und liefert die Bits, die sich geändert haben.
Wir brauchen uns nur merken, wie der alte gelesene Wert war. Für die nun kommenden Prüfungen benötigen wir weitere globale Variable

Delphi-Quellcode:
Old_In_Val : Byte; // In CreateForm wird Wert 0 zugewiesen
Event_Byte : Byte; // In CreateForm wird Wert 0 zugewiesen
Event_Flag_High : Byte; // In CreateForm wird Wert 0 zugewiesen
Event_Flag_Low : Byte; // In CreateForm wird Wert 0 zugewiesen
Und für die Abarbeitung und Anzeige ein paar Strings

Delphi-Quellcode:
High_Flag_Str : string; // In CreateForm wird Wert '00000000' zugewiesen
Low_Flag_Str : string; // In CreateForm wird Wert '00000000' zugewiesen
Und nun geht es los. Mit der Function Bit_Changed bekommen wir die geänderten Bits, unabhängig von der Signallage;

Delphi-Quellcode:
function Bit_Changed(Old_Byte, New_Byte: Byte): Byte;
var
  Ausg: Byte;
begin
  Ausg := (Old_Byte xor New_Byte);
  Bit_Change := Ausg;
end;
Beispiel:

Code:
alt = '10011011'
neu = '10101100'
Xor – Wahrheitstabelle:

Code:
  Bit A   Bit B   Ergebnis
------------------------------
    0        0         0
    1        0         1
    0        1         1
    1        1         0
Anhand der Wahrheitstabelle erkennt man, wie's funktioniert: nur ungleiche Bit ergeben eine '1'. Bei der Anweisung Old_Byte xor New_Byte werden beide Bytes Bit für Bit verglichen.

Und so sieht's aus:

Code:
alt     = '10011011'      
neu     = '10101100'
---------------------   
geändert = '00110111'
Mit dem Aufruf Bit_Is_Changed ( alter gelesenen Wert , EventByte) erhalte ich die Bits 1 nach 0
sowie mit Bit_Is_Changed ( neuer gelesenen Wert , EventByte) erhalte ich die Bits 0 nach 1

Delphi-Quellcode:
function Bit_is_Changed(Change_Byte, Ref_Byte: Byte): Byte;
var
  Ausg: Byte;
begin
  Ausg := Change_Byte and Ref_Byte;
  Bit_is_Changed := Ausg;
end;
Auch hier wieder die Erklärung:

And – Wahrheitstabelle:

Code:
  Bit A   Bit B   Ergebnis
------------------------------
    0        0         0
    1        0         0
    0        1         0
    1        1         1
Erinnern wir uns:

Code:
alt     = '10011011'
neu     = '10101100'
geändert = '00110111'
Schauen wir mal

Code:
was ist von '0' nach '1'       und von '1' nach '0' gewechselt:

neu     = '10101100'          alt     = '10011011'
geändert = '00110111'          geändert = '00110111'
---------------------           ---------------------
Ergebnis = '00100100'          Ergebnis = '00010011'
Logisch, da 5 Bit geändert wurden muss Ergebnis Änderung '0' -> '1' und '1' -> '0' in der Summe 5 ergeben.
Also 2 Änderungen '0' -> '1' und 3 Änderungen '1' -> '0'.
Passt !

Also, das neue Bit mit '1' und dem zugehörigen Änderungs – Bit mit '1' muss einen Wechsel von logisch '0' nach '1' und das alte Bit mit '1' und dem zugehörigen Änderungs – Bit mit '1' muss einen Wechsel von logisch '1' nach '0' gehabt haben.

Diese Ergebnisbytes lassen sich nun abarbeiten und die auf '1' gesetzten Bit nach Bearbeitung löschen.
Dadurch reagiere ich nur auf die Ereignisse und kann mir ständige if... then ... Anweisungen sparen.
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze

 
Turbo Delphi für Win32
 
#6
  Alt 15. Jun 2006, 18:10
Und los geht's:

Es macht Sinn, eine globale Variable für gelesene Bytewerte zu deklarieren

Work_ In: Byte; Jetzt aber.... hier der relevante Teil derTimerroutine......
......ein Beispiele einer solchen Ereignisbearbeitung

Delphi-Quellcode:
begin
  WriteLPTPort(37Ah, Str_to_Byte('00100xx1'));
  Work_In := ReadLPTPort(378h);   
  WriteLPTPort(378h, Str_to_Byte('00000xx0'));
  Event_Byte := Bit_Changed(Old_In_Val, Work_In);

  if Pos('1', Event_Byte) <> 0 then // ab hier weiß ich, aha, eine Änderung
  begin
    Event_Flag_Low := Bit_is_Changed(Old_In_Val, Event_Byte); // hier geht was aus
    Event_Flag_High := Bit_is_Changed(Work_in, Event_Byte); // und hier was an

    Work_Str_In := Byte_To_Str(Work_In);
    Edit1.Text := Work_Str_In; // Eingang zur Anzeige bringen
    Edit3.Text := ByteToStr(EventByte); // geänderte Bits anzeigen
    High_Flg_Str := ByteToStr(Event_Flag_High); // für Ereignisroutine High
    Low_Flg_Str := ByteToStr(Event_Flag_Low); // für Ereignisroutine Low
    Edit4.Text := High_Flg_Str; // zum Ansehen.....
    Edit5.Text := Low_Flg_Str; // zum Ansehen.....
    Old_In_Val := Work_In; // nicht vergessen, sonst funzt es nicht
  end;

  if Pos('1', High_Flg_Str) > 0 then
    Action_Is_High;
  if Pos('1',Low_Flg_Str) > 0 then
    Action_Is_Low;
end;
Mit WriteLPTPort(37Ah, Str_to_Byte('00100xx1')) wird der Port auf "lesen" geschaltet und die Harwarebausteine selektiert. xx steht hier für die Chip-Adresse (Chipselect). Anschließend wird
das Eingangsregister in die Work_In-Variable geschrieben und der Port wieder in den Ursprung zurückgesetzt.
Nun kann aus dem abgelegten alten Eingangsbyte und dem Neuen ein Ereignisbyte gebildet werden. Sind in diesem Ereignisbyte einzelne Bit auf '1' gesetzt, hat eine Änderung stattgefunden. Aus der Information altes Eingangsbyte, neues Eingangsbyte und Ereignisbyte werden die Ereignisflags Wechsel von '0' -> '1' und Wechsel von '1' -> '0' gesetzt und in eine String-Variable geschrieben.
Einerseits kann man leicht ein Bild der Ereignisse in einem TEdit-Objekt anzeigen lassen, andererseits
ist auch eine leichte Verarbeitung in den Prozeduren Action_Is_High und Action_Is_Low möglich. Zum Zeichen der erfolgten Verarbeitung werden die '1'-Zeichen aus dem Flag-String zu '0' gesetzt.

Und so sehen die entsprechenden Ereignisroutinen aus:

Delphi-Quellcode:
procedure Action_Is_High;
var
  xPos: Integer;
begin
  repeat
    XPos := Pos('1', High_Flg_Str);

    if xPos > 0 then
    begin
      Set_ActionBit(xPos); // diese Procedure müsst ihr aber mal selber schreiben !
      High_Flg_Str[xPos] := '0'; // Bit ist bearbeitet, also brauchen wir's nicht mehr
    end;
   until xpos = 0;
end;
Und hier die andere Reaktion...

Delphi-Quellcode:
procedure Action_Is_Low;
var
  xPos: Integer;
begin
  repeat
    XPos := Pos('1', Low_Flg_Str);

    if xPos > 0 then
    begin
      ReSet_ActionBit(xPos); // und die auch, da steht dann drin, was geschehen soll
      Low_Flg_Str[xPos] := '0'; // Bit ist bearbeitet, also brauchen wir auch nicht mehr
    end;
  until xpos = 0;
end;
das nehm ich euch noch ab, aber den Rest macht auch mal......

Delphi-Quellcode:
procedure Set_ActionBit(Bit_Number: Integer);
begin

end;

procedure ReSet_ActionBit(Bit_Number: Integer);
begin

end;
So, das war schon eine ganze Menge Software und auch ein wenig Einleitung in Hardware. Aber wer noch nicht damit gebastelt hat, der weiß nicht, wovon ich rede. Also, Bastelexperten, ihr könnt euch nun freien Lauf der Gedanken lassen und die Umsetzung in Programmierung vollziehen.
Jetzt gibt's wieder Bastelstunde....

Wir haben bei der Erklärung der "tristate"-Ausgänge aufgehört. Dem möchte ich noch eines hinzufügen: Leitungen, an welchen "tristate"-Ausgänge hängen, müssen mit einem Widerstand (100k) entweder an – oder + geschaltet werden. Ich nehm immer +, weil die meisten TTL-IC mehr Strom abgeben, wenn sie Low sind.
Die Erklärung spar ich mir jetzt mal, es ist einfach wichtig zu wissen, bei Low kann mehr Strom fließen. Das heißt unter anderem Leuchtdioden sind heller, wenn sie gemeinsam an Plus und vom IC den Minus bekommen.
Und damit sind wir mal bei etwas, was nicht zu vernachlässigen ist. Ein Standard-TTL IC Ausgang kann ca. 10 – 20 Eingänge beschalten. Werden mehr Eingänge mit einem Ausgang beschaltet, so ist es ratsam,
Bustreiber zu verwenden. Diese gibt es invertierend oder direkt. Und diese Aussage trifft speziell auf
den Parallelport zu. Die Schaltung funktioniert vielleicht 10..15 Minuten, dann setzt mal hier oder da
was aus und plötzlich ist's Essig mit dem tollen Experiment.
Also, kommt nicht auf die Idee, ein Relais direkt am Port zu schalten und Experimente mit LED, na ja, besser ist da schon, vorher zu puffern. Könnt euch ja mal ein Datenblatt eines Standard-TTL-ICs aus dem Netz laden z.B. Bei Google suchenSN7400 und mal schaun, was da in den Datenblättern außer der Beschaltung noch so drinsteht....
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze

 
Turbo Delphi für Win32
 
#7
  Alt 15. Jun 2006, 18:14
Aber da ihr ja Daten nicht nur ausgeben sondern auch einlesen wollt, müsst ihr sowieso ein klein wenig Aufwand treiben.
So eignen sich Buspuffer mit tristate-Ausgang hervorragend für einfache Zwecke:
z.B. 74 LS 244 oder 74 LS 245
Schaut in die Datenblätter und überlegt, was euch mehr nutzt. Ich glaub, der 245 invertiert die Signale. Diese Bausteine beherbergen 8 tristate Buffer in einem 20 poligen Gehäuse. Die Buffer sind jeweils zu 4 Stk in 2 Gruppen selektierbar. Und damit bin ich beim CS Signal. Oft ist über der Signalbezeichnung ein Strich. Dieser bedeutet, das ein Low-Signal die Funktion auslöst. (Low-aktiv)
CS ist in vielen Fällen eines dieser Signale, die einen Datenübertrag vom Eingang (Dn) zum Ausgang (Qn) bei Low-Pegel (0-Signal) freigeben.
Um den Parallelport von der Eingabe und Ausgabe zu trennen, braucht man für alle 8 Bit 2 Bausteine, wobei die Struktur des 74 LS 244 genau diese Funktion unterstützt.


http://dp.matthias-hielscher.de/tuto...llel_tut_5.gif

Die Skizze zeigt zwei gegensinnig geschaltete Buffer. Man stelle
sich vor, 4 solcher Gruppen sind in einem Baustein vorhanden, CS 1
geht auf alle in Richtung "Auf" und CS 2 auf alle in Richtung "Ab".


http://dp.matthias-hielscher.de/tuto...llel_tut_6.gif

Nun muß ich nur noch CS1 mit '0' und CS2 mit 1 belegen, um Daten
zum Port zu schalten und umgekehrt CS1 mit '1' und CS2 mit '0' um
den Ausgang zu schalten. Da der Ausgang hier ein tristate ist, sollte
man ihn vor Weiterverarbeitung mit einem Widerstand 100 K an + schalten.


http://dp.matthias-hielscher.de/tuto...llel_tut_7.gif


Nun wollen wir ein CS-Signal erzeugen.

Sinnvoll ist es, ein Bit zu nehmen und festzulegen: bei '1' will ich lesen, bei '0' schreiben. Da ich dafür nicht den Datenbus benutzen möchte, bietet mir die parallele Schnittstelle ein paar weitere Signale, die sie sonst zum Handshaking mit dem Drucker benutzt.
Ein Signal ist Strobe auf Pin 1. Dieses Signal bedeutet, es liegen Daten zur Ausgabe an z.B. Drucker bereit. Dieses Strobe-Signal kann über die Portadresse 37Ah zum Parallelport Pin 1 ausgegeben werden.
Das zugehörige Registerbit ist Bit 0. Und genau dieses benutzen wir zur Selection der Ein- oder Ausgabe (Bit 0 = 0 -> Daten zur Ausgabe bereit).

Hinweis: Dieses Bit wird Invers zum logischen Zustand geschaltet, d.h. wenn Bit = 0 dann Leitung (Pin) = 5V und wenn Bit = 1 dann Leitung (Pin) = 0V!
Schließe ich nun CS1 direkt und CS2 über einen Inverter an Pin 1 vom Parallelport, habe ich schon einmal ein Richtungsbit.

Mit

WriteLPTPort(37Ah, Str_To_Byte('xxxxxxx1')); // 'xx1xxxx1' Bit 5 ist Steuerbit für Bidirektional wird Pin 1 vom Parallelport auf '0' gelegt.
Somit wird CS1 = '0' und dadurch der Eingabekanal durchgeschaltet.

Mit

WriteLPTPort(37Ah, Str_To_Byte('xxxxxxx0')); // 'xx0xxxx0' wird Pin 1 vom Parallelport auf '1' gelegt.
CS1 bekommt High-Pegel und durch den Inverter CS2 Low-Pegel.
Der Ausgabekanal wird durchgeschaltet.

Es lassen sich nun mit den ersten 3 Bits der Portadresse bis zu weiteren 8 CS Signale erzeugen, die sowohl Ein- oder Ausgabekanäle freigeben können.
Das heißt im Klartext: ich kann eine Schaltung entwerfen, die mir 8 Kanäle mit jeweils 8 Bit also 64 Ein- und 64 Ausgänge bietet.
Ein wenig beachten sollte man die Signallage zu Potentiallage. Dies ist beim Steuerregister nicht immer gleich und deshalb werde ich jetzt Pin 1 und 14 mit Invertern Beschalten. Damit habe ich wieder Bit = Signallage. (siehe Hinweis !)


http://dp.matthias-hielscher.de/tuto...llel_tut_8.gif

Diesen 3 Leitungen kann ich eine diskrete Schaltung verpassen,
oder einen 3 zu 8 Decoder benutzen. SN 74 irgendwas, ich krieg
das noch heraus.



Nun Kann ich wirklich sagen:

Code:
'00000000' schreibt Kanal 0
'00000010' schreibt Kanal 1
'00000100' schreibt Kanal 2
'00000110' schreibt Kanal 3
'00001000' schreibt Kanal 4
'00001010' schreibt Kanal 5
'00001100' schreibt Kanal 6
'00001110' schreibt Kanal 7
und:

Code:
'00010001' liest Kanal 0
'00010011' liest Kanal 1
'00010101' liest Kanal 2
'00010111' liest Kanal 3
'00011001' liest Kanal 4
'00011011' liest Kanal 5
'00011101' liest Kanal 6
'00011111' liest Kanal 7
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze

 
Turbo Delphi für Win32
 
#8
  Alt 15. Jun 2006, 18:23
Wer nicht gleich so riesig aufbauen will, hier eine Schaltung mit einem 74LS00 (4 -fach Nand) und 2 zusätzlichen Invertern 74LS06 (6-fach Inverter) zum Beispiel für 4 Kanäle In und 4 Kanäle Out.



Na ja, Zeichnungstechnisch nich so pralle, aber was nutzt euch eine tolle Zeichnung in EPlan oder Autosketch, wenn ihr dafür diese Zeichnung nicht zu Gesicht bekommt. Ich glaube auch so, das ihr erkennen könnt, worauf es ankommt.

Auch hier gibt's für die NAND eine Wahrheitstabelle:

Code:
  Bit A   Bit B   Ergebnis
------------------------------
    0        0         1
    1        0         1
    0        1         1
    1        1         0
Hier die Wahrheitstabelle für die gesamte Schaltung und den Bits 1 und 2 des Steuerregisters:

Code:
Bit 1     Bit 2     Sel 0   Sel 1   Sel 2   Sel 3   Sel 0   Sel 1   Sel 2   Sel 3
Reg Pin  Reg Pin  A  B  A  B  A  B  A  B  Ausg   Ausg   Ausg   Ausg
---------------------------------------------------------------------------------
 0   1     0   1    1   1   1   0   0   1   0   0     0       1       1       1
 1   0     0   1    0   1   1   1   0   0   1   0     1       0       1       1
 0   1     1   0    1   0   0   0   1   1   1   0     1       1       0       1
 1   0     1   0    0   0   0   1   1   0   1   1     1       1       1       1
In den Ausg. Sel 0 bis Sel 3 ist dem Eingangsbitmuster entsprechend immer nur 1 Ausgang auf Low und damit habe ich das benötigte CS invers Signal.


http://dp.matthias-hielscher.de/tuto...lel_tut_10.gif

Dieses muss nur noch mit dem Bit 0 für Ein- oder Ausgabe verknüpft
werden um eine saubere Trennung der Ein- und Ausgangskanäle zu bekommen.



So, das war ja nun eine Menge Theorie, und vielleicht fragt sich der ein oder andere, toll, aber wie bastel ich nun die Elemente auf eine Platine und wie löte ich die Verbindungen zusammen.
Also, auch ich ätz nich gleich ein paar Leiterbahnen aus einem Kupferblech. Für sowas, wo man noch gar nicht so richtig weiß, ob das überhaupt das ist, was man will und ob's so funzt, wie man es sich vorstellt, nehme ich eine Lochrasterplatine mit nur Lötaugen. Da kommen dann entsprechend der Schaltung, die ich mir ausgedacht habe, Fassungen drauf. Nicht zu eng, ruhig ein bißchen Luft lassen. Die Verdrahtung (na ja, vielleicht nicht unbedingt der Bringer, aber durchaus praktikabel) ist die Verwendung einer alten Trafowicklung. Der dünne Kupferdraht ist durch seine Lackierung isoliert, lässt sich auch ganz gut löten und durch die freien Löcher der Lochrasterplatine stecken. Allerdings gibt's auch Kupferlackdraht in verschiedenen Stärken bei Conrad oder anderen Elektronikhändlern. Zum Lötkolben, da benutze ich eine Lötstation von Obi. Die Temperatur der Lötspitze lässt sich gut regeln, und die Spitzen verbrauchen sich nicht zu schnell. Ganz wichtig ist ein gutes Lötzinn. Lasst die Finger von Lötpasten aller Art. Saubere Lötstellen werden mit einem guten dünnen Elektroniklot mit eingebetteten Fließmittel erreicht. Es ist zwar nicht billig, aber man muss eh nicht sonderlich damit umherschlampen und weniger ist oft Masse genug. Wenn die Lötspitze an einem nassen Silikonschwamm regelmäßig gereinigt wird, gibt es auch fast immer gleich einen sauberen Wärmeschluß und man kann das Lötzinn für die Lötstelle exakt dosieren.
Jetzt die Frage: Welche Spannungen werden für Experimente benötigt und wo baue ich die Schaltung hin.
Also, da die alten Rechner sowieso nicht viel bringen, wenn man diese loswerden will, habe ich sie erstmal behalten. Mit dem Erfolg, nun gleich 3 alte Schätzchen herumstehen zu haben. Aber selbst, wenn kein Alter mehr verfügbar ist, die Zeitungen bieten immer mal einen ausrangerten Oldie.
So habe ich meine Schaltung auf alte Slotabdeckungsbleche sowie den 25pol. Verbindungsstecker für den Parallelport geschraubt. Muss man aber nicht, nur meine Slotbleche hatten bereits die Stecker vorgesehen. Platz ist auch für einen Haufen an Relais und sonstigem Schnickschnack und eine pannungsversorgung für 12 V und 5 V ist auch greifbar. Und wenn der max. Ausbau für den LPT Port nich reicht, dann rüstet eben einen 2. 3. oder 4. nach. Vielleicht gibt es noch welche, aber bitte, betreibt damit kein Kernkraftwerk..... oder ein Fließband einer Autoproduktionsanlage.....

Hier eine Darstellung der Anschaltung an den Parallelport mit dem Datenbusbuffer SN 74 LS 244.

Auch die Anschaltung der Ein- oder Ausgabebausteine ist in der nachfolgenden Skizze angegeben. Bei den Selektions-Signalen der Ausgabe ist es notwendig, diese mit der Schreibrichtung zu verknüpfen.



So, noch ein bißchen Schalttechnik. Also, TTL-Signale können wir ja schon ganz gut erzeugen, aber wie steht es mit Ansteuerungen von Relais oder Motoren. Wie bringe ich Signale in den Rechner, die nicht von einem Schalter stammen, so z. B. Licht oder Wärme. Wie sieht's aus mit analogen Werten so im Bereich von 0 bis 10 V oder gar negative Potentiale –10 V bis +10 V.
Genug der Frage, fangen wir an, Probleme zu lösen. Also, mal ganz ehrlich, anloge Werte über Parallelport würd ich nicht machen, da geb ich den Ball ganz gern an weitere Experten, die vielleicht schon mal was mit den seriellen Port angestellt haben. Vielleicht werd ich zum Schluß eine kleine Applikation bringen....
Ich liebe die Digitaltechnik. Da weiß man, was einem blüht. Entweder geht oder geht nicht, ein geht vielleicht oder nur ein bißchen ist da ausgeschlossen. Licht an oder aus. So isses.
So können wir jetzt ohne Probleme sagen, komm PC, mach mal den Pin 3 vom LPT auf 5 V und die Pin's 2, 4, 5, 6, 7, 8, 9 auf 0 V.
Das geht. Aber um ein Relais zu schalten, grad die, die in der Bastelkiste sind oder ein Elektronikladen für'n €uro fünfzig im Sonderangebot verscherbelt mit 12 V Spule, ne das geht nich. Oder nur durch Vorschalten eines schweineteuren 5V TTL-Relais, welches trotzdem noch sowas wie'n Treiber vorgeschaltet kriegen sollte.
Ich kann euch nur sagen, wenn ihr sowieso schon bei den Elektronikbuden einkauft, dann schaut euch mal
richtig um. Es braucht für das Schalten einer 12 V Spule lediglich ein paar Cents für einen Transistor, eine Diode (Freilauf, ich erklär's später) und einen Widerstand. In der Regel reicht's schon.
Aber wie krieg ich 5 V TTL Pegel auf 12 V für'n Relais. Dafür nun nochmal zurück zum Anfang...
  • 1. Grundsatz:
    Der Strom fließt immer im Kreis, daher der Name "Stromkreis".
    Dies bedeutet: Wo ein Plus, da muß auch ein Minus her. Bitte merken.

Ich will euch nicht schon wieder mit viel Theorie zuquatschen, aber schaut euch mal folgende Schaltung an:



Gut, nix besonderes, aber sie funktioniert. Die Stromkreise mit dem 5 V TTL-Pegel und der 12 V Lastspannung sind verbunden mit einer gemeinsamen Masse. Der Transistor kann leitend werden, wenn in seinem Emitter ein Strom fließt und das Relais zum anziehen bringen. Oder so ähnlich. Auch hier sind bestimmt nicht alle meiner Meinung, aber so komplizierte Dinge wie Arbeitspunkt und Emitter-Basisstrom und was so ein Transistor sonst noch so alles hat, ich lass es hier weg. Wer will, der kann da gern ein paar Zeilen zu schreiben. Mir geht's nur darum: Das Relais muss anziehen, wenn ein High TTL-Pegel anliegt und bei Low TTL-Pegel V abfallen oder evtl. umgekehrt. Wichtig ist, mein Relais reagiert auf meine Ausgabe per Programm auf die Signale am Port.
Da ein Relais eine Spule hat, in der ein Magnetfeld erzeugt wird, wird auch vom Relais eine Spannung erzeugt, wenn der Magnet sich abschaltet. Und die ist nicht zu ignorieren. Sie kann ein vielfaches von dem haben, was die Elektronik dieser Schaltung abkann. (Kein Mensch käme auf die Idee, diese Schaltung an 50, 80 oder gar 120 V zu hängen....)
Tja, die arme Diode, sie ist nun dazu da, diese Spannung kurzzuschließen und unwirksam zu machen. Gut,
sie kann es und der Rest der Schaltung erfreut sich eines ungestörten Elektroniklebens....
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze

 
Turbo Delphi für Win32
 
#9
  Alt 19. Jun 2006, 19:12
Natürlich haben sich die Experten der Halbleiterindustrie auch da etwas einfallen lassen.
Der ULN 2803 beherbergt 8 Schaltkreise, die mit TTL- Pegeln versorgt und im Ausgang Relais bis 30V schalten können. Freilaufdioden sind schon drin.



Damit nun die Ausgänge bei einer Selektierung eines anderen Kanales nicht ihren Wert verlieren, ist für Ausgänge ein 8-Daten-Latch geeignet. Man legt die Daten 8 Bit breit an und schickt einen Schreibimpuls über die Lesen/Schreiben Leitung. Fedisch.
Es ist für Experimente sowieso besser, man teilt die Hardware auf. Z.B. In eine Portkarte mit der Aufbereitung der Kanalselektion und einen Portpuffer, um den LPT vor unbeabsichtigter Zerstörung zu sichern.
Nun können simple Relaiskarten gebaut werden, die am Portpuffer hängen, eine Selektion erhalten und das Schreibsignal für die Data-Latches.
Die Ausgänge der Data-Latches können direkt auf den ULN und an diesen wiederum direkt die Relais.
Nun noch Klemmen für die Relaikontakte und ab geht er der Peter......

Eingangsmäßig ebenso. Hier verwenden wir keine Data-Latches sondern die Portpuffer. Jeder wird komplett als Eingang geschaltet, d.h. CS1 und CS2 kommen an die gleiche Kanal-Selektion.
Wichtig ist: Alle Eingänge sind mit 100k an + zu binden, da sonst unbeschaltete Eingänge kein eindeutiges Logiksignal liefert. Dies kann die gesamte Schaltung beeinflussen, ja sogar Bausteine zerstören.
Jeder Eingangskanal kann nun den Bedürfnissen angepasst werden. Z.B. ein Analog-Digitalwandler, eine Anpassung um einen Hell-Dunkel-Wechsel auf einem LDR(Lichtempfindlicher Widerstand) einzulesen oder ganz einfach eine Abfrage eines mechanischen Kontaktes.

Wichtig ist:
Der Signalpegel zur Schnittstelle ist TTL Norm (Low = 0 V, High = 5 V)



Es sei noch bemerkt, das ein Low-Pegel nicht ganz 0 V hat und ein High-Pegel auch nicht ganz 5 V, nur dass ihr euch beim Messen nicht wundert........
Sollte es euch nun gelungen sein, mit Hilfe meiner "flachmännischen" Beratung doch tatsächlich Werte aus- bzw. in den Computer zubekommen, und zwar über eine eigens dafür zurechtgestrickte Hardware, fernab von Tastatur und Monitor, ja dann werdet ihr auch Vertrauen haben in die weiteren Programmfragmente, welche ich euch noch vorstellen möchte.

Aber zuerst ein paar Gedanken dazu:
Was will ich mit den eingelesenen Informationen in Form von Bits und Bytes anfangen und was mit der Möglichkeit, doch das ein oder andere Relais zum anziehen zu bringen ?
Machen wir wieder ein paar kleine Steps und versuchen, visuelle Objekte zu indizieren. So z.B. eine TCheckbox einem Bit im String zuzuordnen. Z.B. Durch Anklicken erreichen, das ein Relais schaltet. Natürlich kann ich hergehen und im Code fest verankern

Tcheckbox.Name = 'CB_Bit_0'; Nehmen wir einen String mit Namen Work_Out, der in Formcreate mit '00000000' initialisiert ist.
Durch die Abfrage

Delphi-Quellcode:
if CB_Bit_0.Checked then
  Work_Out[8 - 0] := '1'
else
  Work_Out[8 - 0] := '0';

if CB_Bit_1.Checked then
  Work_Out[8 - 1] := '1'
else
  Work_Out[8 - 1] := '0';

// ...
Etc.
Sehr mühselig und steif. Auch eine Schleife bringt so nicht viel:

Delphi-Quellcode:
for i := 0 to Length(Work_Out) - 1 do
begin
  if i = 0 then
    if CB_Bit_0.Checked then
      Work_Out[8 - i] := '1
    else
      Work_Out[8 - i] := '0';

  if i = 1 then
    if CB_Bit_0.Checked then
      Work_Out[8 - i] := '1'
    else
      Work_Out[8 - i] := '0';   

  // ...
end;
Viel eleganter ist doch dies....

Delphi-Quellcode:
for i := 0 to Length(Work_Out) - 1 do
begin
  if TCheckbox(FindComponent(' CB_Bit_' + IntToStr(i))).Checked then
    Work_Out[8 - i] := '1
  else
    Work_Out[8 - i] := '0';
end;
Klar ist natürlich, das die Checkboxobjekte auch entsprechend angeordnet sind, damit auch Bit 0 zur Checkbox mit dem Namen 'CB_Bit_0' passt.
Geht natürlich auch umgekehrt, um die "gesetzten Bit" in einem String in Checkboxen zu übertragen:

Delphi-Quellcode:
for i := 0 to Length(Work_In) - 1 do
begin
  if Work_In[8 - i] = '1then
    TCheckbox(FindComponent('CB_Bit_' + IntToStr(i))).Checked := true
  else
    TCheckbox(FindComponent('CB_Bit_' + IntToStr(i))).Checked := false;
end;
Ah ja, jetzt können wir auch direkt über einen Index auf ein visuelles Objekt zugreifen, bzw. dessen Eigenschaften ändern.Zum Beispiel die Farbe von TPanel ändern:

Delphi-Quellcode:
for i := 0 to Length(Work_In) - 1 do
begin
  if Work_In[8 - i] = '1then
    TPanel(FindComponent('PN_Bit_' + IntToStr(i))).Color := clRed
  else
    TPanel(FindComponent('PN _Bit_' + IntToStr(i))).Color := clGreen;
end;
Manch einem erzähl ich hier nix neues, nun ja, für Fortgeschrittene sollte dieser kleine Kurs ja auch nicht sein, da brauch ich selber einen. Aber so ein paar Raffinessen und Zugriffsmethoden, nun, die möchte ich hier schon erklären, weil ich gleich so richtig ausholen werde.......

Also, wir haben eine Hardware gebastelt.
Wir haben ein Programmrumpf, um Informationen über den Parallelport zu lesen und zu schreiben. Wir können Relais schalten. Und nun......
Schreiben wir für jede Anwendung ein Programm in Delphi. Jedesmal, wenn ein Relais geschaltet werden soll, rufe ich ein Programm x, y oder z auf ?
Geht es nicht eleganter ?

Jo, es geht...... Vielleicht in einem späteren Beitrag
  Mit Zitat antworten Zitat
oldmax
 
#10
  Alt 20. Jun 2006, 05:55
Hi Matze
Vielen Dank für deine Mühe. Ich hoffe, es wird einigen eine Hilfe sein.
Gruß oldMax
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:23 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