RS232-Schnittstelle ansteuern über VBA mittels DLL - Hilfe!
Hallo,
ich habe folgendes Problem (und bin mit den Nerven ziemlich am Ende):
Ein Messgerät soll über die RS232-Schnittstelle am PC (Windows XP) betrieben werden:
An COM1 hängt das Messgerät selbst, hier soll vom PC ein Messwert angefordert und ausgelesen werden können.
An COM2 hängt die Steuerung für die 2 Schrittmotoren, mit denen das zu messende Bauteil gedreht und verschoben werden kann, um es an verschiedenen Stellen zu vermessen.
Die Ansteuerung soll aus Excel über VBA erfolgen, wobei meine Fragen etwas allgemeinerer Natur sind (ich blick's noch nicht so ganz) - also auch nicht-VBA-Programmierer dürfen gerne weiterlesen!
Was bisher geschah:
Mit VBA kenne ich mich einigermaßen aus und hatte mir für den Zugriff auf die Schnittstellen zunächst ein Buch besorgt (siehe http://www.b-kainka.de/msrwin.htm.)
Mithilfe der RSAPI.DLL bzw. der neueren Version PORT.DLL ist es mir dann auch gelungen, über COM1 das Messgerät über VBA anzusteuern und Messwerte auszulesen. Diese DLLs haben aber den Nachteil, dass die Befehle zum Senden und Lesen von Bytes keinen Parameter haben, in dem festgelegt ist, welcher Port gemeint ist.
Um also immer abwechselnd über COM1 (Messgerät) einen Messwert auszulesen und dann anschließend über COM2 (Schrittmotoren) das Bauteil auf die nächste Position zu drehen, müsste ich also immer wieder
Port COM1 öffnen, COM1 schließen, COM2 öffnen, COM2 schließen, COM1 öffnen... und da sehr sehr viele Werte gemessen werden sollen, sind die Verzögerungen beim unablässigen Öffnen und Schließen der Ports nicht akzeptabel (außerdem könnte das ganze dann auch sehr instabil werden..).
Daher habe ich mich auf die Suche nach einer Alternative zur PORT.DLL gemacht, wo mehrere Ports gleichzeitig geöffnet bleiben und angesprochen werden können. Schließlich fand ich die IO.DLL (http://www.geekhideout.com/iodll.shtml), mit der das möglich sein sollte. Ich kapiere allerdings noch nicht so ganz, wie man ihre Funktionen nutzen kann, daher bitte ich um Hilfe:
Die IO.DLL stellt folgende Funktionen zur Verfügung:
Private Declare Sub PortOut Lib "IO.DLL" (ByVal Port As Integer, ByVal Data As Byte)
Private Declare Sub PortWordOut Lib "IO.DLL" (ByVal Port As Integer, ByVal Data As Integer)
Private Declare Sub PortDWordOut Lib "IO.DLL" (ByVal Port As Integer, ByVal Data As Long)
Private Declare Function PortIn Lib "IO.DLL" (ByVal Port As Integer) As Byte
Private Declare Function PortWordIn Lib "IO.DLL" (ByVal Port As Integer) As Integer
Private Declare Function PortDWordIn Lib "IO.DLL" (ByVal Port As Integer) As Long
Private Declare Sub SetPortBit Lib "IO.DLL" (ByVal Port As Integer, ByVal Bit As Byte)
Private Declare Sub ClrPortBit Lib "IO.DLL" (ByVal Port As Integer, ByVal Bit As Byte)
Private Declare Sub NotPortBit Lib "IO.DLL" (ByVal Port As Integer, ByVal Bit As Byte)
Private Declare Function GetPortBit Lib "IO.DLL" (ByVal Port As Integer, ByVal Bit As Byte) As Boolean
Private Declare Function RightPortShift Lib "IO.DLL" (ByVal Port As Integer, ByVal Val As Boolean) As Boolean
Private Declare Function LeftPortShift Lib "IO.DLL" (ByVal Port As Integer, ByVal Val As Boolean) As Boolean
Private Declare Function IsDriverInstalled Lib "IO.DLL" As Boolean
Wenn ich das richtig verstanden habe, kann ich die COM-Ports über den Parameter "Port" unter folgenden Adressen ansprechen:
COM1 - 3F8 (hex) -> 1016
COM2 - 2F8 (hex) -> 760
Im Terminal oder mit der Port.DLL kann ich durch das Senden eines Fragezeichens (ASCII 63) und eines Returns (ASCII 13) das Messgerät dazu bringen, eine Messung zu starten.
Mit der io.dll kriege ich das nicht hin. Mit der folgenden Prozedur sollte es doch eigentlich gehen (Fragezeichen und Return werden über COM1 gesendet):
Sub test()
Call PortOut(1016, 63)
Call PortOut(1016, 13)
For i = 1 To 100
Debug.Print PortIn(1016)
Next
End Sub
.. aber es tut sich nichts, das Messgerät misst nicht. :-(
Wenn ich versuche über PortIn, PortWordIn oder PortDWordIn 100 mal den Port COM1 auszulesen, kommt 100 mal die "255" für PortIn bzw. die "-1" für Port(D)WordIn.
](*,)
Kann mir jemand sagen, was da schief läuft? Muss ich irgendwie auch die Befehle SetPortBit, ClrPortBit, ... verwenden?
Kennt jemand eine andere Möglichkeit, wie ich aus VBA mehrere COM-Ports abwechselnd ansprechen kann?
Vorab vielen Dank für Eure Hilfe,
Gruß
Martin
Ok,Port muss offen sein. Mit den Bytes komme ich nicht klar
Hallo Skilltronic,
danke für Deine Antwort - mittlerweile bin ich schon einen Schritt weiter (immerhin):
Wenn ich mit dem (bewährten) Befehl OPENCOM "COM1:19200,N,8,1" aus der PORT.DLL den COM-Port geöffnet habe, kann ich auch mit den Funktionen aus der IO.DLL Bytes senden und damit das Messgerät zum Messen bewegen.
So weit so gut.
Das Problem ist aber, dass ich mit dem, was zurück kommt, noch nichts anfangen kann:
Wenn ich mit
For i = 1 To 20
Debug.Print (PortDWordIn(1016) & " " & PortWordIn(1016) & " " & PortIn(1016))
Next i
20 Mal den Port auslese (zumindest die erste Speicheradresse), dann erhalte ich folgendes:
62983946 3850 10
62983946 3850 10
62918410 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
62983946 3850 10
Mit
Debug.Print PortDWordIn(1016) & " " & PortDWordIn(1017) & " " & PortDWordIn(1018) & " " & PortDWordIn(1019)
erhalte ich:
62983946 184795407 1611334593 274729731
Im Hyperterminal erhalte ich den Messwert in der folgenden Form:
!3,1667
bzw. die Bytes, die ankommen, sind:
33 51 44 49 54 54 56 13 10 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
=! 3 , 1 6 6 8 und 3 Sonderzeichen
Sorry, ich stehe total auf dem Schlauch. Kann mir jemand sagen, mit welcher der im ersten Posting genannten Funktionen ich lesen muss, was auf dem Port ankommt und wie ich das dann in "Klartext" umwandeln kann?
Gruß
Martin
Daten sollen eigentlich in Excel "online" ausgewer
Hallo Frank,
vielen Dank für den Hinweis (da ich immer noch im Dunkeln tappe, wie ich mein Problem lösen kann).
Bei der Verwendung von RealBasic sehe ich folgende Nachteile:
a) man braucht doch eine Lizenz für die RealBasic-Programmierumgebung, oder gibt es da eine kostenlos verfügbare?
b) ich hatte mir das eigentlich so vorgestellt, dass die gemessenen Daten schon während der laufenden Messung (die pro Bauteil ca. 15 Minuten dauern wird) ausgewertet und graphisch dargestellt werden.
Das ist für mich in Excel deutlich leichter zu realisieren, da ich mich dort auskenne und die notwendige "Infrastruktur" für Diagramme etc. vorhanden ist.
Gruß
Martin