Seite 1 von 1

Parallelinterface

Verfasst: 02 Jun 2014, 09:10
von andi1965
Hallo, ich habe noch das parallel-Interface.
Kann ich das in C programieren ?
Wenn ja, können Sie mir Software dazu empfehlen?

Es grüßt Andreas Kempf

Re: Parallelinterface

Verfasst: 07 Jul 2014, 08:23
von Dirk Haizmann ft
Hallo Andreas,

hier wird wohl eher der Anschluss das Problem werden. Wenn du wirklich noch einen alten Rechner hast, an welchen du das Parallel Interface anschliessen kannst, dann kannst du es auch mit C programmieren.

ft

Re: Parallelinterface

Verfasst: 08 Jul 2014, 10:28
von steffalk
Tach auch!

Vielleicht hilft's ja ergänzend: Ich hatte damals das Protokoll zum Parallel-Interface aus dem im Begleitheft abgedruckten Assembler-Listing reverse-engineered und in ein Modula-2-Modul gegossen. Lesbar müsste es auch für C-Programmierer sein, sonst einfach fragen:

Code: Alles auswählen

DEFINITION MODULE FischerInterface;

  (* Low-Level-Hardwareschnittstelle zum fischertechnik-computing-
     Interface. *)

  PROCEDURE Init;

    (* Schaltet alle Ausg„nge inaktiv. *)

  CONST
    Motors = 4;
      (* Anzahl der ansteuerbaren Motoren. *)

  TYPE
    Motor = [1..Motors];
      (* Die Nummer eines Motors. *)

    Direction = (* Die Richtung, in der sich ein Motor dreht. *)
      (off,
         (* Der Motor (der Ausgang) ist abgeschaltet. *)
       left,
         (* Der Motor wird zum Rechtsdrehen eingeschaltet (abh„ngig von der
            Verkabelung am Modell). *)
       right);
         (* Der Motor wird zum Linksdrehen eingeschaltet (abh„ngig von der
            Verkabelung am Modell). *)

  PROCEDURE SetMotor (n: Motor;
                      Dir: Direction);

    (* Schaltet einen der Motoren.

       in:   n     Die Nummer des anzusteuernden Motors.
             Dir   Die gewnschte Drehrichtung bzw. Polung des Ausgangs.
     *)

  CONST
    Switches = 8;
      (* Anzahl der abfragbaren Taster/Schalter. *)

  TYPE
    Switch = [1..Switches];
      (* Die Nummer eines Schalters. *)

  PROCEDURE SwitchStatus (n: Switch): BOOLEAN;

    (* Fragt einen Schalter ab.

       in:   n           Die Nummer des abzufragenden Schalters.
       out:   (RETURN)   TRUE genau dann, wenn der Schalter auf Durchgang
                         geschaltet ist bzw. die entsprechende
                         Eingangsleitung des Interfaces auf +5 V liegt).
     *)

  CONST
    AnalogInputs = 2;
      (* Anzahl analoger Eingabekan„le. *)

  TYPE
    AnalogInput = [1..AnalogInputs];
      (* Die Nummer eines Analog-Eingangs. *)

  PROCEDURE AnalogStatus (n: AnalogInput): CARDINAL;

    (* Fragt einen der Analog-Eing„nge ab.

       in:    n          Die Nummer des abzufragenden Eingangs.
       out:   (RETURN)   Eine Zahl, deren H”he in einem linearen Zusammenhang
                         mit dem an dem Analogeingang n anliegenden
                         Widerstand steht. Sonst ist ber diese Zahl nichts
                         bekannt.

       Bevor diese Funktion fr eine Steuerung verwendet werden kann, muá der
       m”gliche Wertebereich durch geeignete Maánahmen des Anwenderprogramms
       kalibriert werden.
     *)

END FischerInterface.

Code: Alles auswählen

IMPLEMENTATION MODULE FischerInterface;

  (* Low-Level-Hardwareschnittstelle zum fischertechnik-computing-
     Interface. *)

  (* UPDATES:
     14.07.1989 sf   SwitchStatus f„llt nicht mehr so leicht auf prellende
                     Schalter herein, da ein Schalterzustand erst dann als
                     gltig angesehen wird, wenn zweimal sofort hintereinander
                     der selbe Zustand gemessen wird.
     15.07.1989 sf   Erkennung von Schalterprellung verbessert.
     22.07.1989 sf   InstallTermProc (Init) eingefhrt.
     24.02.1990 sf   Portadressen fr Geosoft-Laptop ge„ndert. Die Motoren
                     und Schalter waren verkehrt herum durchnumeriert;
                     korrigiert.
     09.04.1992 sf   Anpassung an Modula-2 V4.0.
     13.10.1992 sf   Die Port-Adressen werden selbst berechnet. Das Interface
                     kann an eine beliebige parallele Schnittstelle von LPT1:
                     bis LPT4: angeschlossen sein. Dies wird ber ein IniFile
                     gesteuert.
     02.08.1994 sf   Beim 486/66DX2 festgestellt: Die Schalter werden nicht
                     sauber abgefragt - der in Modula-2 programmierte PC ist
                     (selbst in einer Windows-DOS-BOX) zu schnell fr das
                     Interface. Im IniFile ist eine neue Variable
                     "ProcessorSpeed" mit einem LONGINT-Wert definiert.
                     Die neue Prozedur KleineVerzoegerung bremst das ganze
                     damit ein biáchen.
   *)

  FROM SYSTEM IMPORT DISABLE, ENABLE, INB, OUTB;

  FROM RTSTerm IMPORT InstallTermProc;

  FROM Delay IMPORT Delay;

  FROM IniFiles IMPORT ReadIniFileAlone, IniMessage, IniAction;

  FROM Strings IMPORT CompareStr;

  FROM NumberConversion IMPORT StringToLongInt;

  TYPE
    BitInByte = [0..7];
    Byte = SET OF BitInByte;

  VAR
    PrinterPort, BusyPort: CARDINAL;
      (* Adresse des Printerports und des Busy-Ports der verwendeten
         Parallel-Schnittstelle. *)
    MotorStatus: Byte;
      (* Angaben ber den aktuellen Zustand aller Ausg„nge. *)
    ProcessorSpeed: LONGINT;
      (* Je h”her die Zahl (aus FISCHERI.INI), desto l„nger wird dem
         Interface an manchen Stellen ber die Prozedur KleineVerzoegerung
         Zeit gelassen. *)

  PROCEDURE KleineVerzoegerung;

    (* Wartet ein kleines biáchen. *)

    VAR i: LONGINT;

  BEGIN
    i := 0;
    WHILE i < ProcessorSpeed DO
      INC (i)
    END
  END KleineVerzoegerung;

  PROCEDURE SetOutput (Status: Byte);

    (* Setzt Ausgaberegister entsprechend Status.

       in:   Status   Die Information ber den gewnschten Zustand aller
                      Ausg„nge.
     *)

    VAR Bit: BitInByte;

  BEGIN
    MotorStatus := Status;
    DISABLE;
    FOR Bit := 0 TO 7 DO
      IF Bit IN Status THEN
        OUTB (Byte {5, 4, 2}, PrinterPort);
        OUTB (Byte {5, 4, 3, 2}, PrinterPort)
      ELSE
        OUTB (Byte {5, 4}, PrinterPort);
        OUTB (Byte {5, 4, 3}, PrinterPort)
      END
    END;
    OUTB (39H, PrinterPort);
    ENABLE
  END SetOutput;

  (* Exportierte Prozeduren: *)

  PROCEDURE Init;

    (* Schaltet alle Ausg„nge inaktiv. *)

  BEGIN
    SetOutput (Byte {})
  END Init;

  PROCEDURE SetMotor (n: Motor;
                      Dir: Direction);

    (* Schaltet einen der Motoren.

       in:   n     Die Nummer des anzusteuernden Motors.
             Dir   Die gewnschte Drehrichtung bzw. Polung des Ausgangs.
     *)

    VAR MotorIndex, DirByte: Byte;

  BEGIN
    CASE n OF
      1:
        MotorIndex := Byte {7, 6} |
      2:
        MotorIndex := Byte {5, 4} |
      3:
        MotorIndex := Byte {3, 2} |
      4:
        MotorIndex := Byte {1, 0}
    END;
    CASE Dir OF
      off:
        DirByte := Byte {0..7} |
      left:
        DirByte := Byte {1, 3, 5, 7} |
      right:
        DirByte := Byte {0, 2, 4, 6}
    END;
    SetOutput ((MotorStatus + MotorIndex) / (DirByte * MotorIndex))
  END SetMotor;

  PROCEDURE SwitchStatus (n: Switch): BOOLEAN;

    (* Fragt einen Schalter ab.

       in:   n           Die Nummer des abzufragenden Schalters.
       out:   (RETURN)   TRUE genau dann, wenn der Schalter auf Durchgang
                         geschaltet ist bzw. die entsprechende
                         Eingangsleitung des Interfaces auf +5 V liegt).
     *)

    PROCEDURE ActualStatus (n: Switch): BOOLEAN;

      (* Fragt den Schalterzustand ab. *)

      VAR
        Bit: BitInByte;
        SwitchByte, InputByte: Byte;

    BEGIN (* ActualStatus *)
      SwitchByte := Byte {};
      DISABLE;
      OUTB (32H, PrinterPort);
      KleineVerzoegerung;
      OUTB (3AH, PrinterPort);
      FOR Bit := 7 TO 0 BY -1 DO
        KleineVerzoegerung;
        INB (InputByte, BusyPort);
        IF 7 IN InputByte THEN
          INCL (SwitchByte, Bit)
        END;
        OUTB (30H, PrinterPort);
        KleineVerzoegerung;
        OUTB (38H, PrinterPort)
      END;
      ENABLE;
      RETURN n - 1 IN SwitchByte
    END ActualStatus;

    VAR s1, s2: BOOLEAN;

  BEGIN
    (* Prellen abfangen: *)
    s1 := ActualStatus (n);
    s2 := ActualStatus (n);
    WHILE s1 # s2 DO
      Delay (1);
      s1 := s2;
      s2 := ActualStatus (n)
    END;
    RETURN s2
  END SwitchStatus;

  PROCEDURE AnalogStatus (n: AnalogInput): CARDINAL;

    (* Fragt einen der Analog-Eing„nge ab.

       in:    n          Die Nummer des abzufragenden Eingangs.
       out:   (RETURN)   Eine Zahl, deren H”he in einem linearen Zusammenhang
                         mit dem an dem Analogeingang n anliegenden
                         Widerstand steht. Sonst ist ber diese Zahl nichts
                         bekannt.

       Bevor diese Funktion fr eine Steuerung verwendet werden kann, muá der
       m”gliche Wertebereich durch geeignete Maánahmen des Anwenderprogramms
       kalibriert werden.
     *)

    CONST max = MAX (CARDINAL);

    VAR
      count: CARDINAL;
      InputByte: Byte;

  BEGIN
    count := 0;
    DISABLE;
    CASE n OF
      1:
        OUTB (0A0H, PrinterPort) |
      2:
        OUTB (090H, PrinterPort)
    END;
    OUTB (38H, PrinterPort);
    REPEAT
      INB (InputByte, BusyPort);
      INC (count)
    UNTIL NOT (7 IN InputByte) OR (count = max);
    ENABLE;
    RETURN count
  END AnalogStatus;

  PROCEDURE UseLPTPort (PortNumber: CHAR);

    (* Berechnet die Portadressen des angegebenen LPT-Ports ("1" - "4"). *)

    VAR LPTPorts [40H:08H]: ARRAY ["1".."4"] OF CARDINAL;

  BEGIN
    PrinterPort := LPTPorts [PortNumber];
    BusyPort := PrinterPort + 1
  END UseLPTPort;

  PROCEDURE HandleIniMessage (VAR E: IniMessage);

    (* Behandelt das IniFile. *)

    VAR ok: BOOLEAN;

  BEGIN
    WITH E DO
      CASE Action OF
        StartSectionRead:
          interested := CompareStr (OldSection, "FischerInterface") = 0 |
        ReadEntry:
          IF (CompareStr (EntryName, "LPTPort") = 0)
            AND (EntryInfo [0] >= "1") AND (EntryInfo [0] <= "4")
            AND (EntryLen = 1) THEN
            UseLPTPort (EntryInfo [0])
          ELSIF CompareStr (EntryName, "ProcessorSpeed") = 0 THEN
            StringToLongInt (EntryInfo, ProcessorSpeed, ok);
            IF NOT ok THEN
              ProcessorSpeed := 0
            END
          END
      END
    END
  END HandleIniMessage;

  PROCEDURE InitPortAddresses;

    (* Bestimmt die zu verwendenden Portadressen. *)

    VAR ok: BOOLEAN;

  BEGIN
    UseLPTPort ("1");
    ProcessorSpeed := 0;
    ok := ReadIniFileAlone ("FISCHERI.INI", HandleIniMessage)
  END InitPortAddresses;

BEGIN (* FischerInterface *)
  InitPortAddresses;
  Init;
  InstallTermProc (Init)
END FischerInterface.
CARDINAL ist ein nicht vorzeichenbehaftetes 16-Bit-Integer. OUTB (Byte {5, 4, 2}, PrinterPort) sendet ein Byte mit gesetzten Bits 2, 4, 5 (also ein 00110100 aka int 52) über das I/O-Chip vom Parallelport an den entprechenden I/O-Port. ENABLE/DISABLE erlauben bzw. verhindern andere Software-Interrupts. In SetOutput ((MotorStatus + MotorIndex) / (DirByte * MotorIndex)) findet bitweise Arithmetik statt: + ist logisches ODER, * ist logisches UND und / ist logisches XOR. Die Umlaute in den Kommentaren waren MS-DOS-Umlaute von Codepage 437 damals, die hab ich nicht extra gewandelt.

Hey - damals war das ft-Interface noch Open Source Software! :-)

Gruß,
Stefan

Re: Parallelinterface

Verfasst: 09 Jul 2014, 07:31
von thkais
Moin,

PCs mit Parallelanschluss sind inzwischen selten - und dann erlauben moderne Betriebssysteme den Direktzugriff auf den Port (der notwendig ist) nicht mehr ohne Weiteres (Treiber).
Eine Alternative besteht in der ROBO Connect Box (http://www.knobloch-gmbh.de/wbcdirect.p ... uktid=2751), damit ist der Anschluss eines parallel-Interface an einen USB-Port möglich. Ein USB-Parallel-Umsetzer für Drucker funktioniert übrigens nicht, weil diese Adapter das Protokoll des parallel-Interface nicht erzeugen können. Die ROBO Connect Box verhält sich wie ein ROBO Interface, kann also sowohl mit ROBO Pro als auch mit C über die fischertechnik Library (oder die Libraries von Ulrich Müller, http://www.ftcommunity.de/ftComputingFinis/index.htm) angesteuert werden.

Re: Parallelinterface

Verfasst: 11 Jul 2014, 10:40
von Dirk Haizmann ft
.. also ich würd einfach den neuen TXT-Controller empfehlen!

Soviel von mir

ft