LPT1 mit C++ ansteuern?

  • Hallo zusammen, ich möchte ein Lauflicht basteln, an die 8 Ports des LPTs kommt je eine LED, leider tut mein Programm nicht so wirklich... Vielleicht kann mir ja einer von euch weiter helfen :)


    Also er geht in die Schleife rein.. mehr aber auch nicht

    Für Tipps bin ich echt dankbar :)

  • Meine Main Geräte

    Spoiler anzeigen


    Main PC

    MSI X99-pro-Gaming-Carbon
    Intel XEON E5 2630 V4 20 Threads, 36 MB L3 Cache 2,21 Ghz 2,8 Ghz Turbo
    64 GB DDR4 2400 Mhz Quad Channel (8*8GB)
    2* AMD RX 580 8 GB Crossfire X (Pulse Bios 1250 Core 1950 MEM,) (Dual Bios)
    Samsung 960 pro 500 GB NVME @PCIE X4
    Samsung 2 TB SATA III HDD
    Crucial MX 500 1 TB SSD
    Sandisk pro 250 GB SSD
    Soundblaster Z @PCIE x2
    NEC USB 3.1 COntroller Card @ PCIE x2
    Corsair Obsidian 800D Case
    2* EIZO 4K S-IPS TFT + Oculus Rift CV1

    Notebook primär

    HP Zbook 14 G2
    Intel I5 5300U 4 Threads, 1,9 Ghz Turbo bis 2,66 Ghz
    16 GB DDR 3 1600 Mhz Ram
    Intel HD 5500 + AMD Fire pro MV4150 1GB
    Sandisk SSD 500 GB 2,5 Zoll SATA III
    Transcend SSD NVME 256 GB 2260
    14 Zoll S-VA Samsung Panel 1600*900
    LTE 150 Mbits, Intel AC WIFI Gigabit Lan, BT 4.1, NFC
    4* USB 3.0, 1 Smartcard, 1*PCIE SD card Reader, Sound, DP, Dockport, NT
    4 Cell primär Akku 45 WH + Unterschnall Akku 4 Cell 59 WH bis 14,5H



  • Also er geht in die Schleife rein.. mehr aber auch nicht

    Welche, die for oder die while? Kann dein Problem nicht reproduzieren, wenn ich
    if (drucker != NULL) durch if(true) ersetze (hab kein LTP Port hier), tuts dass was man erwarten würde.

    „Zitate von sich selbst in der Signatur sind doof.“ Chrisse, 2009
    „Hmm... mal was aus 2010 reinnehmen“ Chrisse, 2010
    „Ach, wie die Zeit vergeht...“ Chrisse, 2011
    „Bin immernoch dagegen“ Chrisse, 2012
    „Jetzt auch mit 2013“ Chrisse, 2013
    „2021 ich komme“ Chrisse, 2014
    „Ab jetzt wieder länger“ Chrisse, 2015
    „Gut Ding will Weile haben“ Chrisse, 2016
    „Meine Signatur: Öfter geupdated als mein Windows“ Chrisse, 2017
    „Klicken sie weiter, hier gibt es nichts zu lesen“ Chrisse, 2018
    „Dieser Post kann Spuren von Sarkasmus enthalten“ Chrisse, 2019
    „Reinstate Chiaki“ Chrisse, 2020
    „2021 ist eine Coverstory der Moderation und nie passiert!“, Chrisse, 2022

  • Woher hast du den Code? Du wirst damit nicht erreichen können was du willst.

    Mit fopen("LPT1", "w") macht nämlich das Betriebssystem die Ansteuerung der Pins, in dem es ein Byteprotokoll fährt, was abhängig von den Daten alle möglichen Pins setzt und liest; und auch erwartet da auch dass der Drucker Befehle ordentlich bestätigt. Im schlimmsten Fall ist hinter dem Port "LPT1" gar kein Parallelport-Drucker angeschlossen, sondern irgend ein virtueller Drucker der gar nicht erst Pins hat.

    In deinem Fall hast du ja aber keinen Drucker angeschlossen, sondern eine eigene Schaltung ohne Logik. Das heisst du musst die Pin auch selber setzen, und das geht dann nicht mit einem Byteprotokoll, sondern auf PCs klassischerweise mit den INP/OUT Befehlen.

    Lass dich von folgendem Text nicht abschrecken, klingt und sieht alles furchtbar kompliziert aus, das hier ist eher eine grobe Zusammenfassung; ich erkläre aber gerne alles nochmals im Detail:

    Spoiler anzeigen


    Die Idee dahinter ist, dass jeder Pin ein Bit einer Addresse zugewiesen bekommt. Für LPT1 sind das klassischerweise die Adressen 0x378-0x37f (kann aber variieren). Hier die Übersicht, welcher Pin welche Addresse hat: https://en.wikipedia.org/wiki/Parallel_port#Port_addresses

    Die Idee ist also, dass wenn du z.B. den Pin Nr. 5 (D3) ansprechen willst, dass du in der Tabelle da nachschlägst, und dann siehst: Pin Nr. 5 ist in der Base-Adresse (also 0x378) das das 4. Bit.

    Der Code um das Bit zu setzen würde dann in etwa so aussehen (Pseudocode, hab weder Windows, noch C++ oder gar nen Parallelport hier):

    short base = 0x378; // Base-Adressechar byte = 1 << 3; // schreibt die Eins von der 1. Stelle 3x nach rechts, so dass sie an 4. Stelle stehtOut32(base, byte); // setzt Pin Nr. 5 (D3) auf 1, alle anderen auf 0

    Das Auslesen der Pins funktioniert ähnlich mit inp32, ist allerdings etwas mehr Bitfiddling. Beispiel Pin Nr. 10 (ACK) =Adresse base+1, Bit 7:
    char data = !!(Inp32(base+1) & (1 << 6));

    Unter modernen Windows Versionen funktioniert das leider aus Sicherheitsgründen leider nicht mehr direkt, aber es gibt extra Treiber namens "inpout32.dll" dafür, siehe: http://logix4u.net/parallel-port/…dows-982000ntxp (kitsunes Link verwendet den ebenfalls, da hast du auch den Code drin wie man den Laden muss).

    Einmal editiert, zuletzt von gandro (27. April 2013 um 11:48)

  • Welche, die for oder die while? Kann dein Problem nicht reproduzieren, wenn ich
    if (drucker != NULL) durch if(true) ersetze (hab kein LTP Port hier), tuts dass was man erwarten würde.

    Sorry, mein Fehler! das if (drucker != NULL) meine ich, da geht er rein!



    Woher hast du den Code? Du wirst damit nicht erreichen können was du willst.

    Von meinem programmieren Lehrer.......


    Danke für die Hilfe, ich werde es nun mal eben testen und mich danach melden!

  • ich habe es nun versucht, bin aber irgendwie gescheitert, keine ahnung.
    Ich hab dieses Treiber "installiert", habe auch die header file included:

    Code
    #import "inpout32.h"

    Bekomme aber folgende Fehler:

    Spoiler anzeigen



    Bei Line 32 der Fehler: hatte das Oup32 nur zum testen mal groß geschrieben!


    Ich bin der totale c/c++ Noob und habe wirklich absolut keinen Plan was ich tun soll.

  • Ich kenn mich mit dem Linkern unter Windows und C++ nicht aus. Generell gehen aber die meisten Codebeispiele die ich gefunden habe davon aus, dass man die DLL händisch nachlädt. Hier C-Code von der Treibseite, stelle sicher dass die Datei inpout32.dll im gleichen Verzeichnis liegt, wie die Exe deines komplierten Codes.

    Hab mich beim obigen Beispiel übrigens vertippt, der Befehl müsste Out32 bzw. Inp32 lauten.

    Einmal editiert, zuletzt von gandro (26. April 2013 um 21:19)

  • So ich habe es nun mal so getestet, ich habe auch die DLL Datei in das Verzeichnis kopiert, und die andere Datei (so wie es in der Anleitung steht) nach system32/drivers kopiert!

    Diesen Fehler gibt er nicht aus, also scheint er die Library laden zu können:

    Code
    if (hLib == NULL) {
              fprintf(stderr,"LoadLibrary Failed.\n");
              return -1;
         }

    Ich habe zum testen einfach mal deinen Beispielcode benutzt, er kommt auch bis dahin, denn ich habe zum testen noch was hinzugefügt:

    Code
    ////////////////// Hier nun dein Code //////////////////////
    
    
         short base = 0x378; // Base-Adresse
         char byte = 1 << 3; // schreibt die Eins von der 1. Stelle 3x nach rechts, so dass sie an 4. Stelle steht
         Out32(base, byte); // setzt Pin Nr. 5 (D3) auf 1, alle anderen auf 0
         printf("test");
         getchar();

    Das test gibt er auch aus! :)

    Aber es scheinen alle pins auf high stehen zu bleiben, ich habe testweise 2 leds angeschlossen und beide bleiben an..

  • Okay.. ich kenn mich wie gesagt unter Windows da nicht sonderlich aus, hab das zuletzt mit DOS und später mit Linux gemacht.

    Da er den Treiber grundsätzlich zu laden scheint wären die nächsten Schritte mal rauszufinden was denn die wirkliche Basis-I/O-Adresse deines Paralleports ist. Das Interweb schlägt vor, man solle das im Gerätemanager nachschlagen:

    Meiner Meinung müsst da bei deinem Parallelport im eingekreisten sowas stehen wie 0378 oder 0278.. das ist deine Basis-Addresse, die du für short base = 0x0278 verwenden musst in deinem Code (hier jetzt für den Fall dass da 0278 steht, die führende Null wäre egal). An welchen Pins hast du die LEDs denn angeschlossen?

    Einmal editiert, zuletzt von gandro (27. April 2013 um 11:58)

  • Es ist wie du gesagt hast:

    Demnach müsste es doch richtig sein, oder?

    Die eine LED ist an D0 (2) und Masse (18) angeschlossen.
    Die andere LED ist an D1 (3) und Masse (21) angeschlossen.

    Habe im Moment nur 2 LEDs angeschlossen, weils nur zum testen ist, hinterher kommen 8 LEDs dran.

  • Ja, "eigentlich" müsste das funktionieren. :D

    Kannst ja nochmal versuchen Out32(base, 0x00); und nach nach einer Pause oder Tastendruck dann Out32(base, 0xFF); aufzurufen. Das setzt dir alle Datenbits (D0-D7) erst auf 0, dann auf 1 (müssten dann +5V sein). Wenn sich die LEDs dann nicht verändern, dann ist wohl echt was mit dem Treiber im Argen.

    Hab mich auch noch bisschen durch den Sourcecode der inpout32.dll durchgewühlt, aber die scheint schon wirklich den Kerneltreiber (die hwinterface.sys, die du ja nach System32/Drivers kopiert hast) nachdrücklich zu laden. Bin da etwas ratlos. Betriebsystem? Auf dem einen Screenshot sieht man ne OS X Menübar.. Virtuelle Maschine?

    Einmal editiert, zuletzt von gandro (27. April 2013 um 13:10)

  • Es ist ein echter Windows Server 2008 R2 (64Bit), der steht direkt neben mir, da ich aber keinen 2. Monitor habe verbinde ich mich via RDP darauf.

    Ich teste mal eben das andere und berichte danach

    Einmal editiert, zuletzt von Basstra (27. April 2013 um 13:18)

  • Hm.. Windows Server 2008 R2 ist Windows 7 basiert. Verwendest du die 32bit oder die 64bit Version? Für letzteres brauchst du nämlich nen gesonderten Treiber. Auch bin ich nicht sicher ob der alte WinNT Treiber mit Win7 wirklich tut.. aber müsste vermutlich schon.

  • Gerade noch korregiert, ist die 64Bit Version, habe auch dafür die DLL (inpoutx64.dll) auch dafür die files nach system32/drivers und auch nach sysWOW64/drivers kopiert, wenn ich die 64 bit dll benutze kommt aber der Fehler, dass er den Treiber nicht laden kann..

  • Ach, erst jetzt deine Bearbeitung gesehen..

    64Bit Treiber: http://www.highrez.co.uk/downloads/inpout32/default.htm

    Lade dir unten das "Binaries only - x86 & x64 DLLs and libs" Archiv. Führe die Win32\InstallDriver.exe aus.
    Verwende auch unbedingt die inpout32.dll aus dem neuen Treiber. Falls du eine 64bit EXE erzeugst, musst du die inpoutx64.dll verwenden (auch den Namen im Code nicht vergessen zu ändern). Wenn du eine 32bit EXE erzeugst, dann sollte obiger Code funktionieren.

    Auf der Seite hats übrigens auch ne Beispiel C++ Applikation. Versuche ggf. die mal zu kompilieren.

    Einmal editiert, zuletzt von gandro (27. April 2013 um 13:35)

  • Ich habe, wie du gesagt hast den installer aus Win32 genommen, doch habe folgendes Bild bekommen:

    Spoiler anzeigen


    Ist das so richtig?
    Es irritiert mich, weil da halt doch wieder 64 bit steht.


    Funktionieren tut es dennoch nicht.. :(

    Hier die Fehlerausgabe von dem Beispiel (habe überall ein getch(); hingesetzt damit er mir die Ausgabe auch anzeigt)

    Spoiler anzeigen


    Ich glaube, ich muss auch die Hex-Werte anpassen, oder?

    Einmal editiert, zuletzt von Basstra (27. April 2013 um 14:09)

  • Der Installer liegt in Win32, steht aber irgendwo dass der dir die 64bit Version installiert auf 64bit Systemen. Die Installation scheint jedenfalls zu klappen.

    Die Test-Applikation kannst du mit Parametern aufrufen, in der Kommandozeile z.B. mit

    Alle Datenpins auf Low: InpoutTest.exe write 888 0
    Alle Datenpins auf High: InpoutTest.exe write 888 255

    888 ist die Dezimalschreibweise von 0x0378.

    Nachtrag: Falls das nicht klappt, versuche auch mal in der Test-Applikation LoadLibrary("InpOutx64.DLL") zu verwenden, für denn Fall dass deine Applikation 64bit ist.

    Einmal editiert, zuletzt von gandro (27. April 2013 um 14:16)

  • Wenn ich den 32 Bit Treiber nehme bekomme ich keinen Fehler! :)
    Aber aus gehen die LEDs trotzdem nicht! :(


    Spoiler anzeigen


    Wenn ich den 64 Bit Treiber benutze komme ich erst garnicht so weit:

    Spoiler anzeigen


Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!