PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RS232-Schnittstelle ansteuern über VBA mittels DLL - Hilfe!



elwood151
10.11.2005, 10:05
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

Skilltronic
10.11.2005, 12:14
Hallo

Mit VBA kenne ich mich nicht aus, ich kenne das nur von QuickBasic her, aber 760 bzw. 1016 sind nur die jeweils ersten Adressen das Registerbereichs, über den die COM-Ports gesteuert werden. Darüber werden normalerweise nur einzelne Pins angesprochen und ausgelesen. Für die serielle Kommunikation mus der COM erst mit OPEN "COMn...AS #m" geöffnet und konfiguriert werden (Parity Bit, Zahl der Datenbits, Stopbit usw.). Dabei ist n die Nummer das zu öffnenden COMs (1 oder 2) und m ist die Dateinummer - das kennst du vielleicht vom Arbeiten mit Dateien. Genauso wie du mir OPEN ...AS #1, OPEN...AS#2 usw. auf mehrere Dateien gleichzeitig zugreifen kannst, sollte es so auch möglich sein, beide COM-Ports gleichzeitig zu nutzen.

Gruss
Skilltronic

elwood151
10.11.2005, 14:47
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

Skilltronic
11.11.2005, 13:02
Hallo

Mit dem PortIn liest du nur die Steuerregister des Ports aus. Das kann man benutzen, um den Zustand einzelner Pins am COM abzufragen, aber nicht für die serielle Kommunikation über RS232. Mit OPEN wird der Port wie eine sequentielle Datei geöffnet und du solltest auch genauso lesen und schreiben können. Wie gesagt kenne ich das aber nur von QuickBasic.

Gruss
Skilltronic

elwood151
11.11.2005, 15:43
Hm,

danke für den Hinweis. Dann bin ich allerdings ratlos, denn es wird in der dll offenbar keine "Open"-Funktion oder was ähnliches zur Verfügung gestellt.
Wie kann das denn dann gedacht sein?

Gruß

Martin

frank-findus
14.11.2005, 16:57
Hallo,

darf es auch ein anderes Basic sein? Ich arbeite seit Jahren mit RealBasic (objektorientiert, echter Compiler), da ist (u.a.) die Benutzung der seriellen Ports überhaupt kein Problem - du gibst ihnen Namen und kannst dann darauf zugreifen, wie z.B. "MessPort.write m" ... bzw. "s=SteuerPort.readall" ...

Beispiel:

dim Messport as serialport
messport=new serialport
messport.port=0 '(COM1=0, COM2=1, COM3=2 usw.)
messport.baud=9600
messport.parity=0
messport.stopbits=1
if messport.open then
...
else
msgbox "shit!"
end if


Zusätzlich hätte das den Vorteil, dass du ausführbare Programme für Windows, Linux und MacOS erhältst - aus dem gleichen Quelltext.

Frank

elwood151
15.11.2005, 07:51
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

frank-findus
16.11.2005, 00:08
Hallo,

du hast recht, RB gibts nur mit Lizenz. Und es ist auch keine Software, die man "mal eben so" im Vorbeigehen vernünftig nutzen kann, man braucht schon ein wenig Erfahrung. Aber Excel gibts ja eigentlich auch nicht umsonst :-)

Die gleichzeitige Darstellung der hereinkommenden Meßwerte in beliebiger Form (Liste, Diagramm, 3D-Profil etc.) wäre aber überhaupt kein Problem. Auch Drucken oder die Ansteuerung von Plottern ist möglich ... Nun will ich das hier nicht zum Werbe-Thread ausarten lassen ... aber es gibt in RB Nichts, was nicht geht - und vor Allem im Gegensatz zu z.B. Java, Delphi oder VB - plattformübergreifend und als "echte" compilierte Applikation.

Frank

recycle
16.11.2005, 01:45
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?


Im April gab es RealBasic eine zeitlang kostenlos. Jedenfalls für Umsteiger von VB6.
http://www.golem.de/0504/37319.html
Wie tief intensiv man sich vorher mit VB6 beschäftigt haben musste um als Umsteiger durchzugehen weiss ich nicht, wurde aber auch für den Download nicht abgefragt.

Eine 15 Tage Demoversion, Handbücher usw. kannst du dir auf www.realbasic.com immer noch herunterladen.
Wenn es dir gefällt, reicht ja vielleicht auch erst mal eine Studentenversion.
Wenn du dich auf der Webseite bis zu deren deutschen Reseller durchhangelst, kannst du die da für 60 Euro bestellen.

elwood151
16.11.2005, 07:43
@ Frank:


du hast recht, RB gibts nur mit Lizenz. Und es ist auch keine Software, die man "mal eben so" im Vorbeigehen vernünftig nutzen kann, man braucht schon ein wenig Erfahrung. Aber Excel gibts ja eigentlich auch nicht umsonst

Die Idee ist auf jeden Fall gut, allerdings sehe ich da nach wie vor die genannten "Hürden". Klar ist Excel auch nicht umsonst, aber wir haben hier im Institut eben Office-Lizenzen für alle Rechner, und wenn die Daten aus dem Messgerät direkt in eine Excel-Tabelle geschrieben werden, dann können auch andere Kollegen direkt was damit anfangen.
In VBA kann ich durchaus noch einiges lernen, was mir dann auch an anderer Stelle nützen wird, daher möchte ich vermeiden, noch eine weitere Baustelle RealBasic aufzumachen (es gibt davon schon genug, im Moment :-().

Es gibt mittlerweile noch eine Hoffnung, das Problem in den Griff zu kriegen:
Bei der Schrittmotorsteuerung für die Luftlagerachsen ist eine DLL dabei, die eine entsprechende Programmschnittstelle zur Verfügung stellt. Mit dieser kann man u. a. auch Ports öffnen und schließen, und wenn ich das Messgerät wie eine zweite Schrittmotorsteurung verwende, müsste es gehen.
Ich bin gerade dabei, das zu testen. Melde mich, falls das Problem damit gelöst ist.

@ recycle

Danke Dir für den Hinweis! Falls es keinen anderen Weg gibt, werde ich es mit RealBasic versuchen.
Gruß

Martin

teslapower
16.11.2005, 09:05
Geh mal hier hin http://www.activevb.de/cgi-bin/upload/search.pl und such nach "seriell".
Da findest du genug Module um aus VBA ohne extra DLL übern Com Port Daten zu senden.

MFG teslapower