Relais-Karte... Ports auslesen

  • Guten Tag,

    Ich hoffe ich bin hier richtig.
    Als AutoIT-Neuling eine Frage an die Fachleute.

    Ich möchte den Status einer Relaiskarte RTX-O2D mit 8255 Proz. mit AutoIT auslesen.
    Das Setzen der Ports habe ich mit "DLLCall io.dll" ja hinbekommen.

    **** das funktioniert ! ****

    Func Ausgabe()
    ; Ausgabe auf Relaiskarte
    DllCall("io.dll", "int", "PortOut", "int", 768, "int", $DEZIMAL1)
    DllCall("io.dll", "int", "PortOut", "int", 769, "int", $DEZIMAL2)
    DllCall("io.dll", "int", "PortOut", "int", 770, "int", $DEZIMAL3)
    EndFunc

    Nur mit dem Lesen haperts.!!
    Ich habe bereits einiges mit "PortIN" rumprobiert, leider ohne Erfolg.

    Ehrlich gesagt bin ich mir noch nicht einmal sicher ob sich der Status überhaupt- und wenn ja -
    WIE - auslesen lässt.
    Gibts hier vielleicht jemanden der sich mit so etwas schon einmal beschäftigt hat ??

    Vielen Dank im voraus.

    Joshi

  • Hi,
    ein bisschen Code und ein Paar Infos zur Relaiskarte wären ganz gut und natürlich zu den Ports

  • .. ups!
    Sorry, blöd von mir!
    Ich habe mal die Anleitung zu der Karte angefügt.
    Leider kann ich persönlich mit den Daten nicht viel anfangen.
    Wie gesagt, das Setzen der Ausgänge (schalten der Relais) habe ich hinbekommen.
    Nur würde ich gern auch den Status wieder einlesen und weiterverarbeiten.

    Zum Hintergrund:
    Die Karte läuft bei mir seit 10 Jahren zur Heizungssteuerung im Haus auf einem W2K-Server.
    Mit den Relais werden die Heizkörper, der Brenner und Warmwasser angesteuert. (AN/AUS)
    Damals habe ich ein recht komplexes Ansteuerprogramm in TurboBasic geschrieben.
    Das AUSLESEN hatte ich damit aber auch nicht hinbekommen und somit vernachlässigt.

    Als mir vor ein paar Wochen AutoIT in die Hände gefallen ist dachte ich, es wäre an der Zeit
    um das Ganze damit zum Laufen zu bringen.
    Vielleicht klappts ja diesmal auch mit dem Auslesen ! Wäre toll.

    Falls es nicht zu unverschämt ist und jemand einen Lösungsansatz sieht
    dann würde ich mich über eine Zeile Quellcode freuen!
    Als Anfänger in AutoIT ist einem die genaue Syntax doch noch nicht sooo geläufig.

    Vielen Dank im voraus

    Joshi

  • Hi,
    du könntest mal die Adresse 0x303 (Control Register) auslesen und hier Posten.
    Zum Status einlesen, willst du Auslesen ob ein Ausgang gesetzt ist oder sind weitere Statusleitungen angeschlossen?

  • Hi RAPTOR-ONE !

    Erst einmal Danke für Deine Hilfe.
    Richtig, ich möchte einlesen ob ein Ausgang (sprich Relais) gesetzt ist oder nicht!

    Nur .... "Adresse 0x303" AUSLESEN ...!
    Da sind sie wieder, meine 3 Probleme ! ha
    Auslesen..gern, nur wie?

    Vermutlich gehe ich die Sache aus Unwissenheit völlig falsch an !
    Hardware-nahes programmieren ist nicht ganz so mein Ding.
    Und die Syntax bei AutoIT gibt mir dafür echt Rätsel auf.

    Die "io.dll" habe ich hier gefunden: http://geekhideout.com/iodll.shtml
    Wie gesagt, beim "Schreiben" funzt es ja damit!

  • Hi,
    ich hab mal das Beispielprogramm aus der Anleitung übersetzt und ein Stück Code zum Auslesen der Config.
    Wie ist eigentlich das Board mit dem PC verbunden?
    Schreib dann erstmal ob sich was regt vielleicht auch wenn du die anderen Ports ausließt sonst könnte man noch ein paar andere Sachen testen.

    Spoiler anzeigen
    [autoit]


    Dim $dll
    Dim $config

    [/autoit] [autoit][/autoit] [autoit]

    $dll = DllOpen("io.dll")

    [/autoit] [autoit][/autoit] [autoit]

    $config = DllCall("io.dll", "byte", "PortIn", "short", 0x303)

    [/autoit] [autoit][/autoit] [autoit]

    DllClose($dll)

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, "Config", Hex($config))

    [/autoit] [autoit][/autoit] [autoit]

    ;Beispielprogramm aus der Anleitung
    Dim $Port = 0x300

    [/autoit] [autoit][/autoit] [autoit]

    DllCall("io.dll", "none", "PortOut", "short", $Port+3, "byte", 0x80)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 to 20
    ;while 1
    DllCall("io.dll", "none", "PortOut", "short", $Port, "byte", 0x00)
    DllCall("io.dll", "none", "PortOut", "short", $Port+1, "byte", 0x00)
    DllCall("io.dll", "none", "PortOut", "short", $Port+2, "byte", 0x00)

    [/autoit] [autoit][/autoit] [autoit]

    Sleep(1000)

    [/autoit] [autoit][/autoit] [autoit]

    DllCall("io.dll", "none", "PortOut", "short", $Port, "byte", 0xFF)
    DllCall("io.dll", "none", "PortOut", "short", $Port+1, "byte", 0xFF)
    DllCall("io.dll", "none", "PortOut", "short", $Port+2, "byte", 0xFF)
    ;WEnd
    Next

    [/autoit]
    • Offizieller Beitrag

    Hallo,

    probier mal das Programm!

    Spoiler anzeigen
    [autoit]

    Const $cwBaseAddr = 0x300
    Global $wPortA = $BaseAddr
    Global $wPortB = $BaseAddr + 1
    Global $wPortC = $BaseAddr + 2
    Global $wCtrlReg = $BaseAddr + 3

    [/autoit] [autoit][/autoit] [autoit]

    Global $bValA, $bValB, $bValC;

    [/autoit] [autoit][/autoit] [autoit]

    ; Folgende Werte im Control-Register schalten die
    ; Ports in entsprechenden Modus um

    [/autoit] [autoit][/autoit] [autoit]

    ; Control Reg | Port A Port B Port C
    ; 0x80 (128) OUT OUT OUT
    ; 0x82 (130) OUT IN OUT
    ; 0x85 (133) OUT OUT IN
    ; 0x87 (135) OUT IN IN
    ; 0x88 (136) IN OUT OUT
    ; 0x8A (138) IN IN OUT
    ; 0x8C (140) IN OUT IN
    ; 0x8F (143) IN IN IN

    [/autoit] [autoit][/autoit] [autoit]

    Global $hDll = DllOpen("io.dll")

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To 255
    ; Alle Ports auf OUT schalten
    DllCall("io.dll", "none", "PortOut", "short", $wCtrlReg, "byte", 0x80)

    [/autoit] [autoit][/autoit] [autoit]

    DllCall("io.dll", "none", "PortOut", "short", $wPortA, "byte", $i)
    DllCall("io.dll", "none", "PortOut", "short", $wPortB, "byte", $i)
    DllCall("io.dll", "none", "PortOut", "short", $wPortC, "byte", $i)

    [/autoit] [autoit][/autoit] [autoit]

    Sleep(1000)

    [/autoit] [autoit][/autoit] [autoit]

    ; Alle Ports auf IN schalten
    DllCall("io.dll", "none", "PortOut", "short", $wCtrlReg, "byte", 0x8F)

    [/autoit] [autoit][/autoit] [autoit]

    $bValA = DllCall("io.dll", "byte", "PortIn", "short", $wPortA)
    if IsArray($bValA) Then $bValA = $bValA[0];
    $bValB = DllCall("io.dll", "byte", "PortIn", "short", $wPortB)
    if IsArray($bValB) Then $bValB = $bValB[0];
    $bValC = DllCall("io.dll", "byte", "PortIn", "short", $wPortC)
    if IsArray($bValC) Then $bValC = $bValC[0];

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("PortA = " & $bValA & @CRLF)
    ConsoleWrite("PortB = " & $bValB & @CRLF)
    ConsoleWrite("PortC = " & $bValC & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    Sleep(1000)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    DllClose($dll)

    [/autoit] [autoit][/autoit] [autoit][/autoit]
  • Hallo Raptor, hallo Bernd !

    erstmal danke für die Scripte.

    Für Raptor:
    Also die Karte (übrigens noch ISA) ist über ein 36pol. Flachbandkabel an eine Eigenbau-24erRelaisplatine mit Treiberstufe und Schutzschaltung angeschlossen. Klappt seit jahren wunderbar!
    Zu Deinem Code:
    Es tut sich was .. nur nicht das richtige´.
    Wärend der 1. ForNext-Schl. wird das "Config"-Byte immer nur mit 0000 0000 angezeigt.
    Also ... kein Auslesen!
    Bei der 2.FN-Schleife werden im Sekundentakt (sleep1000) alle 24 Relais gesetzt und wieder gelöscht!
    Nach Ablauf der ForNext bleiben alle Relais gesetzt.

    Für Bernd:
    Nach Start werden gemäß ForNext die Variablen (A,B & C)
    ConsoleWrite("PortA = " & $bValA & @CRLF)
    ConsoleWrite("PortB = " & $bValB & @CRLF)
    ConsoleWrite("PortC = " & $bValC & @CRLF
    mit der dem Schleifenzähler $i gefüllt und werden auf der Console fortlaufed angezeigt.
    Also 0 - 255
    Am Status der Relais ändert sich gar nichts.
    Keinerlei Zugriff auf die Ausgabe.
    Lasse ich das Script auf einem Rechner OHNE die IO-Karte laufen ... werden bis Schleifenende nur fortlaufend Nullen (0) angezeigt.

    So, und jetzt vielleicht was peinliches!
    Ich habe zu dem Thema -wie schon so oft- auch nochmal ausgiebig gegoogelt.
    Ich habe eine dt. Anleitung zu einer ähnlichen Karte gefunden (ist im Anhang)
    Diese Karte hat allerdings 2x den 8255 Proz., aber ich glaube das kann man vernachlässigen!
    Wenn ich den Text richtig verstehe dann kann man
    a.) nur jeweils 1 Byte-Ausgang (8Relais) auf EINGANG schalten
    und ...
    b.) wenn der Ausgang (write) auf Eingang (Read) umgeschaltet wird er dabei RESETTET !
    also ist er auf 0. Also wird man auch immer nur "0000 0000" auslesen!
    Gedacht ist das ganze wohl um Messspannungen bzw. externe TTL-Signale die am jeweiligen Eingang aktiv anliegen auszuwerten.

    Falls das so ist ...und davon gehe ich aus ..... habe ich Euch ganz umsonst bemüht!
    Tut mir wirklich Leid.

    Oder seht ihr noch ne Chance ???

    Gruß

    Joshi

    • Offizieller Beitrag

    Das heißt, Dir geht es gar nicht darum digitale Daten einzulesen, sondern Dich interessiert nur der Relais-Status?
    Also keine echte Regelschleife, sondern lediglich die Steuerdaten. Die werden doch aber von Deinem Programm gesetzt, oder?
    Somit bräuchtest Du diese doch nur in einer Variablen ablegen und auswerten?! Oder habe ich das falsch verstanden?

  • Hi,
    mit dem Resettet ist eigentlich immer so. Die andere Karte unterstützt ja das auslesen von Ausgängen (Statur von gesetzten Ports).
    Deine Karte unterstützt das anscheinend nicht, du könntest entweder die Lösung von Oscar nehmen und die Werte speichern oder die Ports Rückkoppeln. Da du ja sehr wahrscheinlich nicht alle 24 IO-Ports deiner Karte nutzt müsstest du deinen Ausgangsport bsp. Port A auf Port B Rückkoppeln und dann kannst du den Status über Port B wieder einlesen.
    Die 1. Lösung ist zwar einfacher aber die zweite wäre auch möglich.

  • Was ist den mit der Funktion GetPortBit ? Damit kannst du zwar nur 1 bit kontrollieren, aber das sollte doch genug sein ;)

    Zitat

    short int WINAPI GetPortBit(short int Port, char Bit);
    ...
    GetPortBit
    Returns the state of the specified bit.

  • Im Grunde schon, nur ist die dll nicht das Problem sondern die Relaiskarte die das auslesen der als Ausgang definierten Ports nicht unterstützt.

  • Vielen Dank für Eure Hilfe.
    Tja, ich denke das wird wohl nix .... mit dem Auslesen.

    Für Oskar und zum allgemeinen Verständnis:
    Variablen ablegen? ... ja und nein!
    Mit meinem damaligen Programm unter Turbobasic .. kein Problem. Wärend der Laufzeit hatte ich immer den aktuellen Status der Ausgänge.
    Nur stellte sich über die Jahre und mit zunehmender Auslastung meines Servers (Heiz.Regelung, Telekommunikation, Proxy, FM-MP3-Hausverteilung, Fileserver,Funk-Schaltrelais-Empfänger,Klimaregelung, FTP / HTTP Server und noch so einiges ...) heraus, das das noch DOS-basierende TurboBasicprogramm u.a. durch die DOS-Architektur und ständig laufender Zeitschleifen eine recht hohe Prozessorlast poduziert.
    Also .. abschalten und zunächst auf Batchdatei-Relaisschaltung per Windows-Taskplaner umschwenken.
    Daher habe ich keinen aktuellen Status meiner 24 Relais zum Zeitpunkt X des Tages.
    Nicht das es so mega-wichtig ist .. aber wäre schon angenehm!

    Klar, man könnte natürlich auch einen schnelleren Server oder sogar einen weiteren Rechner installieren um das alles zu bewerkstelligen. Nur der Energieverbrauch der Steuerkomponente (PC) würde die der Einsparung beim Heizen etc. auffressen.

    Da kam AutoIT ins Spiel .. sehr flexibel ... mit Compiler... hat ein GUI... ist kostenlos... und verbraucht in meinem Fall erstaunlich wenig Recourcen.

    Ich denke, ich kann den Thread hier wohl schließen.
    Falls jemandem zu meinem Problem noch etwas einfällt ... immer gern.

    Ansonsten ... guten Rutsch

    Joshi

  • Im Grunde schon, nur ist die dll nicht das Problem sondern die Relaiskarte die das auslesen der als Ausgang definierten Ports nicht unterstützt.


    Bisher hab ich das hier im Thread nur so gelesen, dass das Auslesen mit PortIn nicht funktioniert, das den Port resettet.
    @Joshi: hast du es eigentlich schon mal mit GetPortBit versucht ohne vorher PortIn aufzurufen?

  • Hi Raptor,

    ja ... hatte bereits damit herumexperimentiert!
    Allerdings ohne genau zu wissen was ich da mache !

    Mit verschiedenen Ports usw.

    zB. auch so
    $Bit1 = DllCall("io.dll","byte","GEtPortBit","short",0x300)

    Ergebnis ist "00000000"

    Vielleicht muss der Befehl anders lauten ??

  • Der Befehl müsste so sein:

    [autoit]

    $aResult = DLLCall($id_dll, "ushort", "GetPortBit", "ushort", $iPort, "byte", $iBitNr) ; $iBitNr: Das auszulesende Bit
    $iBitAktiv = $aREsult[0]

    [/autoit][autoit][/autoit][autoit]

    $aResult = DLLCall($id_dll, "ushort", "GetPortBit", "ushort", 0x300, "byte", 1) ;
    $iBitAktiv = $aREsult[0]
    MsgBox(0,"", $iBitAktiv) ; müsste 1 sein, wenn Bit 1 aktiv

    [/autoit]
  • Hi,
    du könntest auch mal das Probieren

    Spoiler anzeigen
    [autoit]

    Dim $dll
    Dim $config

    [/autoit] [autoit][/autoit] [autoit]

    $dll = DllOpen("io.dll")

    [/autoit] [autoit][/autoit] [autoit]

    DllCall("io.dll", "none", "PortOut", "short", 0x303, "byte", 0x80)
    $config = DllCall("io.dll", "byte", "PortIn", "short", 0x303)

    [/autoit] [autoit][/autoit] [autoit]

    DllClose($dll)

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, "Config", Hex($config[0], 2))

    [/autoit] [autoit][/autoit] [autoit]

    ;Beispielprogramm aus der Anleitung
    Dim $port = 0x300
    Dim $portA, $portB, $portC

    [/autoit] [autoit][/autoit] [autoit]

    DllCall("io.dll", "none", "PortOut", "short", $Port+3, "byte", 0x80)

    [/autoit] [autoit][/autoit] [autoit]

    ;For $i = 0 to 20
    ;while 1
    DllCall("io.dll", "none", "PortOut", "short", $port, "byte", 0x00)
    DllCall("io.dll", "none", "PortOut", "short", $port+1, "byte", 0x00)
    DllCall("io.dll", "none", "PortOut", "short", $port+2, "byte", 0x00)

    $portA = DllCall("io.dll", "byte", "PortIn", "short", $port)
    $portB = DllCall("io.dll", "byte", "PortIn", "short", $port+1)
    $portC = DllCall("io.dll", "byte", "PortIn", "short", $port+2)
    MsgBox(0, "Alle Ports 0x00", "PortA: " & Hex($portA[0], 2) & "\nPortB: " & Hex($portB[0], 2) & "\nPortC: " & Hex($portC[0], 2))

    [/autoit] [autoit][/autoit] [autoit]

    Sleep(1000)

    [/autoit] [autoit][/autoit] [autoit]

    DllCall("io.dll", "none", "PortOut", "short", $port, "byte", 0xFF)
    DllCall("io.dll", "none", "PortOut", "short", $port+1, "byte", 0xFF)
    DllCall("io.dll", "none", "PortOut", "short", $port+2, "byte", 0xFF)

    $portA = DllCall("io.dll", "byte", "PortIn", "short", $port)
    $portB = DllCall("io.dll", "byte", "PortIn", "short", $port+1)
    $portC = DllCall("io.dll", "byte", "PortIn", "short", $port+2)
    MsgBox(0, "Alle Ports 0xFF", "PortA: " & Hex($portA[0], 2) & "\nPortB: " & Hex($portB[0], 2) & "\nPortC: " & Hex($portC[0], 2))
    ;WEnd
    ;Next

    [/autoit] [autoit][/autoit] [autoit]

    DllCall("io.dll", "none", "PortOut", "short", $port, "byte", 0x00)
    DllCall("io.dll", "none", "PortOut", "short", $port+1, "byte", 0x00)
    DllCall("io.dll", "none", "PortOut", "short", $port+2, "byte", 0x00)

    [/autoit]

    Einmal editiert, zuletzt von RAPTOR-ONE (28. Dezember 2009 um 17:33)

    • Offizieller Beitrag

    @RAPTOR-ONE, nur zur Info, DllCall gibt ein Array zurück! ;)