[HowTo] LPT1 Ansteuern mit Programmbeispiel

sNiff3ls

Neuling
Thread Starter
Mitglied seit
14.07.2008
Beiträge
223
Ort
Gräfenberg (Nähe Nürnberg)
Servus liebe Community,

ich habe mir überlegt, ein HowTo zum Ansprechen des LPT1 zu schreiben.
Dabei werde ich versuchen mich so kurz wie möglich zu halten und das Programm so einfach wie möglich zu halten.
Es ist mein erstes HowTo in dieser Form und ich würde mich über ein Feedback freuen.

Achtung: Für schäden an Hardware oder Software übernehme ich keine Verantwortung!
Ihr macht alles auf eigene Gefahr!


LED1.jpg

Fangen wir an:

1. Das Drucker Kabel
2. Setzen der Bits unter Windows
3. Das Programm

1.Das Drucker Kabel

Code:
Printer Cable

25 PIN D-SUB MALE to the Computer
 _1________________________13_
 \ o o o o o o o o o o o o o / 
  \_o_o_o_o_o_o_o_o_o_o_o_o_/
   14                     25
   
36 PIN CENTRONICS MALE to the Printer.
_______1__________________________________________________18________
\                                                                  /
 \    -[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-     /
  \  |                                                       |   /
   \  -[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-   /
    \__________________________________________________________/
       19                                                 36

Bezeichnung		25-DSub		36-Cen
Strobe			1		1
Data Bit 0		2		2
Data Bit 1		3		3
Data Bit 2		4		4
Data Bit 3		5		5
Data Bit 4		6		6
Data Bit 5		7		7
Data Bit 6		8		8
Data Bit 7		9		9
Acknowledge		10		10
Busy			11		11
Paper Out		12		12
Select			13		13
Autofeed		14		14
Error			15		32
Reset			16		31
Select			17		36
Signal Ground		18		33
Signal Ground		19		19,20
Signal Ground		20		21,22
Signal Ground		21		23,24
Signal Ground		22		25,26
Signal Ground		23		27
Signal Ground		24		28,29
Signal Ground		25		30,16
Shield	Shield		Shield+17

Für unsere Zwecke sind nur Data Bit 0 bis Data Bit 7 sowie Signal Ground wichtig.
Auf D0 bis D7 können +5V anligen, auf Signal Ground liegen 0V an.

Ich habe ein Altes Druckerkabel genommen und die Stecker-Gehäuse entfernt.
Danach habe ich die Kontakte vom 36-Pin-Cen weggelötet und mir die Farben mit den Dazugehörigen namen aufgeschrieben. Danach kam das ganze in ne Aufputzdose und an die D0 - D7 kommen Lüsterklemmen, sodass das ganze flexibel bleibt. Zum besseren verständnis ein paar bilder:

offen.jpgnahaufhme.jpgDose.jpgLED1.jpg

2.Setzen der Bits unter Windows

Da es unter Windows 2k sowie XP nicht möglich ist die Hardware direkt anzusprechen benötigen wir dazu einen Treiber.
Ich benutze hierfür die inpout32.dll (http://www.logix4u.net/inpout32.htm).
Dies ist ein einfach zu handhabender Treiber, mit dem wir unter allen Windows Versionen eine Schnittstelle ansprechen können.
Das gehschieht folgendermaßen:
Wir laden in unserem Programm eine Funktion aus der DLL.
Danach Rufen wir die Funktion auf und Übergeben ihr 2 Integer werte.
Der 1. Wert ist die Addresse Der Schnitstelle (Bei LPT1 zu 99% entweder 632, 888 oder 956.
Der 2. Wert ist Der Dezimalwert der zu Setzenden Bits.

Zum besseren verständnis ein Beispiel:
Wollen wir auf D0, D4,D5 sowie D6 Strom haben, so müssen wir
01110001 (von hinten lesen!)
setzen.
Da der 2. Wert der Funktion ein Dezimal Wert sein muss, müssen wir den Binärwert erst umrechnen.
Dies geschieht Folgendermaßen:
Code:
 _________________________
|                         |
| 01110001                |
| ||||||||_2^0 * 1 =  1   |
| |||||||__2^1 * 0 =  0   |
| ||||||___2^2 * 0 =  0   |
| |||||____2^3 * 0 =  0   |
| ||||_____2^4 * 1 =  16  |
| |||______2^5 * 1 =  32  |
| ||_______2^6 * 1 =  64  |
| |________2^7 * 0 =  0   |
|                 +______ |
|           Dezimal:  113 |
|_________________________|
Kleiner Tipp Der Windows Rechner kann das auch, wenn man ihn Unter Ansicht auf Wissenschaftlich stellt.

Soviel zur Theorie fangen wir mit dem Programmieren an:

3. Das Programm

Als Programmiersprache habe ich C# gewählt und als IDE (Integrated Development Environment == Entwicklungsumgebung)
Microsoft Visual C# 2005 Express Edition (http://www.microsoft.com/express/2005/download/default.aspx).

Wir erstellen ein neues Projekt
Datei -> Neues Projekt... -> Windows Anwendung -> (Bei Name: den gewünschten Namen für das Programm eingeben) -> OK

Danach sollten wir einfach nur eine Leere Windows Form sehen.

Nun ziehne wir aus der Toolbox

01x MenuStrip
01x GroupBox
08x CheckBox
10x Label
01x Button
02x TextBox

auf unsere Form und Ordnen sie Folgendermaßen an:
IDE1.jpg

Danach Geben wir den Objekten über das Eigenschaften Fenster (falls nicht vorhanden über Strg + W + P einbleden) einen EntwurfsNamen
sowie einen Text.
Der Text (wie im Bild markiert) ist die Beschriftung des Objekts, der Entwurfsname ist nicht Sichtbar, sondern wird später bei der Programmierung
benötigt. (Sinnvolle Namen!!!)

Danach gehts ans Eingemachte: Programmieren
Als erstes machen wir einen Doppelklick auf Unsere Form und landen im Code (Form1.cs).
Es sollte nun ungefähr so aussehen:
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
		
        }
    }
}

Wir Deklarieren (=Erstellen) 9 Variablen:
(Variablen kann man sich als Platzhalter vorstellen, welche man mit beliebigen inhalt füllen kann. Sie bestitzen jedoch einen
festen Typ z.B int = nur ganzzahlen oder string = nur text)

Dies geschieht folgendermaßen:

private typ name;
z.B. private int D0;

So Deklarieren wir 9 Integer (int) mit den Namen D0 - D7 und address.

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private int D0;
        private int D1;
        private int D2;
        private int D3;
        private int D4;
        private int D5;
        private int D6;
        private int D7;

        private int address;

        private void Form1_Load(object sender, EventArgs e)
        {
        
        }

    }
}

Nun lassen wir die Variable "address" beim Programmstart mit "888" füllen:
(888 ist die Adresse von LPT1; Diese kann unter Arbeitsplatz -> Rechsklick -> Verwalten -> Gerätemanager -> Anschlüsse (COM und LPT) -> Druckeranschluss (LPT1) -> Rechtsklick -> Eigenschaften -> Ressourcesn -> E/A Bereich. Dort ist ein Wert wie z.B. 0378 - 037F eingetragen. Die erste Zahl (Vorsicht HEXADEZIMAL!) ist die Adresse. Diese einfach mithilfe des Windowsrechners in Dezimal Umrechnen. (378Hex -> 888Dez; 278Hex -> 632Dez; 3BCHex -> 956))

Code:
        private void Form1_Load(object sender, EventArgs e)
        {
			address = 888;
        }

Nun die Chckboxen:
(Als Entwurfsnamen habe ich für die Checkboxen chkD0 - chkD7 gewählt)
Auf jede Checkbox jeweils Doppelklick und dann den Code so erweitern:

Code:
        private void chkDX_CheckedChanged(object sender, EventArgs e)
        {
            DX = Convert.ToInt16(chkDX.Checked);
            FillBin();
        }
(das X jeweils mit der entsprechenden nummer ersetzen)

Nun wollen wir, dass sobald man bei einer Checkbox den haken setzt bzw wegmacht der Text in der Textbox neben dem "Binary"-Label ändern.
Dies geschieht mit einer neuen Funktion:

Code:
        private void FillBin()
        {
            txtBin.Text = D7.ToString() + D6.ToString() + D5.ToString() + D4.ToString() + D3.ToString() +
                            D2.ToString() + D1.ToString() + D0.ToString();
        }
Kurze erklärung: txtBin ist der Entwurfsname der Textbox. Mit txtBin.Text können wir die Eigenschaft Text also das was in der Textbox steht verändern. Da D0 - D7 Integer sind und die Eigenschaft txtBin.Text einen String erwartet müssen wir D0 - D7 erst zu String konvertieren. Dies geschieht mit DX.ToString(). Danach können wir die Werte einfach mit "+" zusammenfügen.

Da wir aber, wie Unter Punk 2. schon erwähnt, für die Funktion Dezimal Werte brauchen und keine Binär Werte müssen wir den Binärwert aus txtBin.Text in Dezimal konvertieren.

Das ganze passiert Folgendermaßen:
Wir machen Doppelklick auf txtBin. Dadurch entsteht eine Funktion mit Event. Diese Funktion wird aufgerufen sobald sich der Text in txtBin.Text ändernt.
In diese Funktion schreiben wir FillDec(); rein.
Danach erstellen wir einen neue Funktion in die wir
txtDec.Text = Convert.ToString(D0 * 1 + D1 * 2 + D2 * 4 + D3 * 8 + D4 * 16 + D5 * 32 + D6 * 64 + D7 * 128);
Das sieht dann folgendermaßen aus:
Code:
        private void FillDec()
        {
            txtDec.Text = Convert.ToString(D0 * 1 + D1 * 2 + D2 * 4 + D3 * 8 + D4 * 16 + D5 * 32 + D6 * 64 + D7 * 128);
        }

        private void txtBin_TextChanged(object sender, EventArgs e)
        {
            FillDec();
        }

Nun fügen wir unserem MainMenu noch einen Menu eintrag mit dem namen "Menu" und zwei Button mit den Namen "Set Value" und "Exit" hinzu.
Danach Doppelklick auf Exit und zwischen die beiden geschweiften Klammern folgendes schreiben:
Code:
this.Close();
Nun Doppelklick auf Set Value und folgendes zwischen die beiden geschweiften Klammern schreiben:
Code:
btnSet.PerformClick();
(btnSet ist der Entwurfsname meines Buttons auf der Form rechts unten.
Soweit sogut.
Nun kommen wir zum einbinden der inpout32.dll:

Dazu erstellen wir eine neue Klasse:
Projekt -> Klasse hinzufügen... -> Name: "WritePort.cs" -> Ok.
Danach gehen wir im Projektmappenexplorer (Strg + w + s) doppelklick auf Writeport.cs und ergänzen den Code Folgendermaßen:

Code:
using System;
using System.Runtime.InteropServices;

namespace WindowsApplication1
{
    public class WritePort
    {
        [DllImport("inpout32.dll", EntryPoint = "Out32")]
        public static extern void Out(int add, int value);
    }
}

Nun können wir über WritePort.Out(int add, int value); den LPT1 Ansprechen.
Dies soll natürlich geschehen wenn wir auf den Button "Set Value" klicken.
Dazu machen wir wieder doppelklick auf den Button "Set Value" und ergänzen den Code so:
(bei mir ist der Entwurfsname des buttons "btnSet")
Code:
        private void btnSet_Click(object sender, EventArgs e)
        {
            WritePort.Out(address, Convert.ToInt32(txtDec.Text));
            
            lblD0.Text = chkD0.Checked.ToString();
            lblD1.Text = chkD1.Checked.ToString();
            lblD2.Text = chkD2.Checked.ToString();
            lblD3.Text = chkD3.Checked.ToString();
            lblD4.Text = chkD4.Checked.ToString();
            lblD5.Text = chkD5.Checked.ToString();
            lblD6.Text = chkD6.Checked.ToString();
            lblD7.Text = chkD7.Checked.ToString();
        }

Durch WritePort.Out(address, COnvert.ToInt32(txtDec.Text)); setzen wir die Werte und durch
lblDX.Text = chkDX.Checked.ToString(); werden die Labels jeweils mit True oder False beschriftet, jenachdem wie die Bits sind.

Nun nurnoch das Projekt Abspeichern (Datei -> Alle Speichern)
und die inpout32.dll (http://logix4u.net/inpout32_source_and_bins.zip) in das Debug verzeichnis ( C:\Dokumente und Einstellungen\NAME\Eigene Dateien\Visual Studio 2005\Projects\PROJEKTNAME\PROJEKTNAME\bin\Debug) kopieren.
Geschafft! Nun könnt ihr das Programm durch einen Klick auf Debuggen -> Debuggen starten.. erstellen und ausfürhen.
Nachdem ihr es einmal Debuggt habt liegt im verzeichnis Debug das Programm als .exe Datei.

Hier nochmal der Gesammte Code:
Form1.cs:
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private int D0;
        private int D1;
        private int D2;
        private int D3;
        private int D4;
        private int D5;
        private int D6;
        private int D7;

        private int address;

        private void chkD0_CheckedChanged(object sender, EventArgs e)
        {
            D0 = Convert.ToInt16(chkD0.Checked);
            FillBin();
        }

        private void chkD1_CheckedChanged(object sender, EventArgs e)
        {
            D1 = Convert.ToInt16(chkD1.Checked);
            FillBin();
        }

        private void chkD2_CheckedChanged(object sender, EventArgs e)
        {
            D2 = Convert.ToInt16(chkD2.Checked);
            FillBin();
        }

        private void chkD3_CheckedChanged(object sender, EventArgs e)
        {
            D3 = Convert.ToInt16(chkD3.Checked);
            FillBin();
        }

        private void chkD4_CheckedChanged(object sender, EventArgs e)
        {
            D4 = Convert.ToInt16(chkD4.Checked);
            FillBin();
        }

        private void chkD5_CheckedChanged(object sender, EventArgs e)
        {
            D5 = Convert.ToInt16(chkD5.Checked);
            FillBin();
        }

        private void chkD6_CheckedChanged(object sender, EventArgs e)
        {
            D6 = Convert.ToInt16(chkD6.Checked);
            FillBin();
        }

        private void chkD7_CheckedChanged(object sender, EventArgs e)
        {
            D7 = Convert.ToInt16(chkD7.Checked);
            FillBin();
        }

        private void FillBin()
        {
            txtBin.Text = D7.ToString() + D6.ToString() + D5.ToString() + D4.ToString() + D3.ToString() +
                            D2.ToString() + D1.ToString() + D0.ToString();
        }

        private void FillDec()
        {
            txtDec.Text = Convert.ToString(D0 * 1 + D1 * 2 + D2 * 4 + D3 * 8 + D4 * 16 + D5 * 32 + D6 * 64 + D7 * 128);
        }

        private void txtBin_TextChanged(object sender, EventArgs e)
        {
            FillDec();
        }

        private void btnSet_Click(object sender, EventArgs e)
        {
            WritePort.Out(address, Convert.ToInt32(txtDec.Text));
            
            lblD0.Text = chkD0.Checked.ToString();
            lblD1.Text = chkD1.Checked.ToString();
            lblD2.Text = chkD2.Checked.ToString();
            lblD3.Text = chkD3.Checked.ToString();
            lblD4.Text = chkD4.Checked.ToString();
            lblD5.Text = chkD5.Checked.ToString();
            lblD6.Text = chkD6.Checked.ToString();
            lblD7.Text = chkD7.Checked.ToString();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            address = 888;
        }

        private void setValueToolStripMenuItem_Click(object sender, EventArgs e)
        {
            btnSet.PerformClick();
        }
    }
}

WritePort.cs:
Code:
using System;
using System.Runtime.InteropServices;

namespace WindowsApplication1
{
    public class WritePort
    {
        [DllImport("inpout32.dll", EntryPoint = "Out32")]
        public static extern void Out(int add, int value);
    }
}

Das war mein HowTo ich hoffe es war gut verständlich auch für jemanden der sich mit der Materie 0 auskennt.

Über Feedback würde ich mich sehr freuen und falls jemand einen fehler findet bitte umgehend sagen!

Für Hilfe beim Programmieren stehe ich auch gerene in ICQ zur verfügung (ICQ#338008669)

Bei Interesse kann ich auch das C# Projekt hochladen.

Mfg sNiff3ls
 
Zuletzt bearbeitet:
Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.
Das hört sich alles wahnsinnig Interessant an und hat sicher auch eine Zeit gedauert um das zu lernen, nur ich hab kein einziges Wort verstanden. :eek:
Weckt mich der PC nun pünktlich oder kann er nun Kaffee kochen? Oder leuchtet nun mit Hilfe eines alten Druckerkabels eine Lampe? :confused:

Ich schätze, für das was du da gemacht hast gibt es auch einfachere Lösungen, oder?
 
:d Das hab ich mir fast gedacht.
Im erklären bin ich nicht so ganz gut ^^

Das ganze ist eher aus einer Spielerei entstanden.
Ich versuchs nochmal zu verdeutlichen:
Das Druckerkabel hat 25 Adern. Davon sind 8 für Daten und 8 GND.
Die 8 Daten Adern kann man direkt ansteuern. Sprich ich kann für jede der 8Datenadern entscheiden ob Strom (+5V) anliegen sollen oder nicht.
Das mit der LED war nur ein einfaches Beispiel.

oder kann er nun Kaffee kochen?

Befüll deine Kaffemaschine mit Wasser und Kaffe und bau ein relais ein.
Das Relais kannst du dann über das Druckerkabel bzw. über eine der 8Datenandern Steuern. Schon kannste Kaffee kochen ^^

Das ganze lässt sich ja nach deinen eigenen Ideen ausbaun ^^

Gruß sNiff3ls
 
Hallöchen

Da ich auf eine HTL gehe (Programmieren) verstehe ich das ganze sehr gut :)
Nur hat mein Mainboard (P5Kr) kein LPT Port :(
Funktioniert dies auch mit dem Com Port und hat das P5Kr überhaupt einen :p Ich komm gerade nicht an meinem PC.

cheers
dmk

EDIT: Ich sollte mir angewöhnen genau zu lesen ^^ habe die textstelle jetzt gefunden :d hoffe es funktioniert, aber welche zahl muss ich nun senden für die ansteuerung
 
Zuletzt bearbeitet:
Sehr interessant geschrieben!!

Beim COM-Port dürfte das ähnlich funktionieren, allerdings hat der glaube ich nicht so viele Datenleitungen, oder?
 
Nein hat er nicht.
Der COM (RS232) Port hat meines Wissens 4 oder?

cheers
dmk
 
Hallo,

freut mich dass es doch jemanden gibt, der mein how-to versteht :P

aber welche zahl muss ich nun senden für die ansteuerung

Also das Prinzip mit den Zahlen:(Auf LPT1 bezogen)
Ich hab` ja 8 Datenadern somit kann ich 8 mal I/O (Strom an / Strom aus) schicken.
Da ein PC bekanntlich dumm ist und nur 1 und 0 versteht müssen wir zunächst ein bisschen mit Binär hantieren:
Code:
 _________________________
|                         |
| 01110001                |
| ||||||||_2^0 * 1 =  1   |
| |||||||__2^1 * 0 =  0   |
| ||||||___2^2 * 0 =  0   |
| |||||____2^3 * 0 =  0   |
| ||||_____2^4 * 1 =  16  |
| |||______2^5 * 1 =  32  |
| ||_______2^6 * 1 =  64  |
| |________2^7 * 0 =  0   |
|                 +______ |
|           Dezimal:  113 |
|_________________________|
01110001 = Acht Stellen.
In diesem Beispiel wären also die Datenadern 0,4,5 und 6 unter Strom. (Binär von hinten lesen 1 = strom, 0 = kein strom)

Ungerechnet in Dezimal ergibt das, wie oben gezeigt die Zahl 113.

Somit schicken wir 113 an unseren Port.

Vom Prinzip her sollte es genauso mit dem COM gehen. Ich bin zZ leider nur unter Linux unterwegs (Windows PC im Umbau siehe mein Casecon projekt Mesh Cube)
Wegen der belegung der Kabel kann ich nur HWB empfehlen (Hardware Book) dazu gibt es auch eine windows hilfe datei zum herunterladen.

Wenn ich wieder unter Windows und meinem geliebten Netframework unterwegs bin kann ich, sollte Interesse bestehen, ein Code-Snippet für den COM port schreiben.

Gruß
 
sehr gute geschriebenes Tutorial! für jemanden er einigermaßen programmieren kann kein Problem es zu verstehen!! Kompliment an den Autor für die einfach Darstellung der doch nicht so einfach Materie...
Nur weis ich leider nicht was ich mit dem nun gewonnen Wissen anfangen kann... hast du ein Beispiel für was man das verwenden kann???

MFG ritter-sebo
 
Verwendung...für alles ;)
wie zB das oben genannte Bsp mit der Kaffemaschine.

Also könnte man eigendlich jedes Gerät im Haushalt per Relais ein und ausschalten.

cheers
dmk
 
Exakt @ dmk.

Du kannst das ganze für ziemlich vieles verwenden umd elektrische geräte ein/aus zu schalten.
Ich z.B habe das relais in meinen Lichtschalter eingebaut ^^ Ich weiss ich bin faul :d

@ritter-sebo:
Danke für das Kompliment, freut mich dass dir das Tutorial gefällt.

Gruß
 
naja mit der ansterung des COM-ports ist das nicht ganz so einfach:

Der drucker port (lpt) ist parallel. dh es liegen an den 8 datenleitungen die signale die ich ausgebe gleichzeitig an.
der com port ist seriell, dh er besitzt nur 2 leitungen

für genaueres einfach mal wiki fragen ...
 
mhm dh ich muss wieder auf den LPT port zurückgreifen -.

lg
 
Hallo zusammen,
Bekomme es nicht zum laufen.
Könnte ich das fertige C# Projekt bekommen?
mfg
 
Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh