Forum: PC-Programmierung Serialport in Visual Baisc 2005 Express


von Richard van Huizen (Gast)


Lesenswert?

Hi, ich möchte über die serielle Schnittstelle einen Roboter steuern und
muss dafür Zeichenketten über den COM-Port senden und empfangen können.
Als Programmiersprache will ich Visual Basic 2005 Express benutzen.
Da ich nun leider ein absoluter Neuling bin, was VB 2005 und den COM
Port angeht brauche ich eure Hilfe.

Ich habe bereits herausgefunden, dass Visual Basic die Klasse
System.IO.Ports.SerialPort zur Verfügung stellt mit der das alles sehr
einfach gehn soll. Aus der MSDN Beschreibung werd ich allerdings nicht
wirklich schlau.

Es wäre fantastisch wenn hier jemand mal ein einfaches Beispielprogramm
posten würde indem die grundlegenden Schritte zur Kommunikation (Lesen
und Schreiben) über den COM-Port mit der Klasse "SerialPort"
aufgeführt werden.

Vielen Dank schon mal im Voraus.

von Daniel Steurer (Gast)


Lesenswert?

Hallo,

ja das tolle an Visual Basic, dass es sehr einfach ist, die serielle
Schnittstelle anzusprechen.

also:
1. Du musst die Schnittstelle öffnen
     ->  SerialPort1.Open()

2. Senden:
     ->  SerialPort1.Write("Hallo")

3. Lesen:
     ->  Wert = SerialPort1.ReadLine    (Dim Wert As String)

ich hoffe, ich konnte helfen

gruß daniel

von Richard Van Huizen (Gast)


Lesenswert?

Danke für die schnelle Antwort, nur brauch ichs noch etwas genauer.
Wie schon gesagt, ich bin ein absoluter Neuling in VB und hab da schon
so meine Probleme.

Zu allererst, wie binde ich die Klasse SerialPort ein?
Welche Schritte sind außerdem notwendig um die Kommunikation
herzustellen (Angabe von Port, Baudrate, etc. ).

Zum Ausprobieren hab ich jetzt erstmal ein Messgerät (Metex M-3640D)
angeschlossen und schon die ersten Probleme. Senden kann ich zwar (hier
also ein "D" zur Sendeaufforderung) aber beim empfangen der
angeforderten Daten hängt sich das Programm auf. Verwendet hab ich den
Befehl "ReadLine".

Es würde mir Helfen wenn ich ein typsiches Beispielprogramm für die
Verwendung der Klasse "SerialPort" vor Augen hätte.

von Daniel Steurer (Gast)


Lesenswert?

>Zu allererst, wie binde ich die Klasse SerialPort ein?

im Entwurfmodus kannst du auf der linken Seite unter Komponenten den
Serialport auswählen. Diesen dann auf deine Oberfläche ziehen. Dann
müsste dort dein Symbol für den Serialport aufscheinen. Wenn du drauf
klickst, kannst du unter Eigenschaften, unter anderem, deine Baudrate
festlegen.

>...aber beim empfangen der
>angeforderten Daten hängt sich das Programm auf.

ich hab vergessen zu sagen, dass der Befehl
"Wert = SerialPort1.ReadLine" so lange wartet, bis der Buffer voll
ist (die Buffer größe kannst du übrigens auch unter Eigenschaften
festlegen), also ein oder mehrere Zeichen empfangen wurden.

Dein Programm läuft solange in einer Schleife.

Ich weiß nicht, ob es hier noch andere Befehle gibt, da ich mich auch
erst seit kurzem damit beschäftige.

Wie du schon gesagt hast, aus der Hilfe im VB wird man auch nicht
richtig schlau :(

gruß daniel

von Marc M. (bytewood) Benutzerseite


Lesenswert?

Ich denke, das Abfragen des Seriellen Ports ist am besten mit einem
Timer lösbar:
Serielle öffnen
do
-> Timer starten
   Irgend was wichtiges machen
-> Timer Stoppen
   Serielle abfragen
loop
Serielle schliessen

Eine andere Möglichkeit ergibt sich, wenn man die Serielle (ohne
Timer)in einer Schleife abfragt und den letzten Wert mit dem neuen Wert
vergleicht, sprich den Puffer mit einer Variablen in dem der letzte Wert
drin steht.
Den Befeht "DoEvents" in der Schleife nicht vergessen, damit die
Kiste nicht hängt.
Diese ReadLine -Geschichte ich nicht ganz optimal.
Versuche  etwas in dieser Art(die Initialisierung der Seriellen habe
ich mir mal gespart):
 Do
    DoEvents
    Empfang= MSComm2.Input
 Loop Until Right(Empfangscode, 1) = vbLf

von Richard Van Huizen (Gast)


Lesenswert?

Vielen Dank für die Antworten. Ich werd heut abend die Sachen alle mal
ausprobieren und euch das Ergebnis mitteilen.

Schönen Sonntag noch :-).

Gruß

Rich

von Richard Van Huizen (Gast)


Lesenswert?

Also ich hab jetzt mal alles ausprobiert und konnte zumindest die
Kommunikation mit dem Messgerät herstellen, den Befehl zum Datensenden
"D" senden und teilweise auch die Daten auslesen.
Allerding nur mit dem Befehl ReadTo(x). ReadLine funktioniert, trotz
Anpassung des Lesepuffers nicht.

Wie funktioniert eigentlich der Befehl Read(buffer,offset,count)?
Wie kann ich nun die gesamten Daten richtig auslesen, und was passiert
überhaupt beim Auslesen?

Im Anhang habe ich mal mein Beispielprogramm angefügt, die in
Kommentarklammern gesetzten Zeilen funktionieren nicht.

Ich hoffe Ihr könnt mir helfen ...

Anhang:

        SerialPort1.Open()
        SerialPort1.Write("D")
        TextBox1.Text = SerialPort1.ReadTo(8)

        'TextBox2.Text = SerialPort1.ReadLine
        'TextBox3.Text = SerialPort1.ReadExisting

        SerialPort1.Close()

von Richard Van Huizen (Gast)


Lesenswert?

> Do
>    DoEvents
>    Empfang= MSComm2.Input
> Loop Until Right(Empfangscode, 1) = vbLf

Es tut mir leid, aber ich bin ein absoluter Neuling in VB und kann beim
besten Willen mit dem Code-Ausschnitt nichts anfangen.
Bitte erklär mir was du in der Schleife abfragst und wozu.
Auch das mit dem Timer hab ich nicht ganz durchschaut.

Bitte nicht die Geduld mit mir verlieren :-)

Danke und Gruß

Rich

von Toni (Gast)


Lesenswert?

Sorry, aber ein klein wenig solltest Du Dich schon mal in die
Programmiersprache einarbeiten. VB ist nun wirklich nicht sehr schwer
zu erlernen.

Den Input über Timer oder Schleifen abzufragen, ist so ziemlich die, na
sagen wir mal, uneleganteste Methode die es gibt. Das Zauberwort hier
heißt 'Event'. Schau Dir doch einfach mal die Hilfe zu seriellen
Kommunikation in VB an. Es ist alles sehr schön erklärt und es gibt
auch Beispiele.

Toni

von arc (Gast)


Lesenswert?

Warum Schleifen oder Timer?
Der Serialport hat ein Event das beim Eintreffen von Daten ausgelöst
wird (DataReceived). Mit ReadExisting() können dann die angefallenen
Daten eingelesen werden.

von Rahul (Gast)


Lesenswert?

es gibt auch das onComm-Event... Dafür braucht man keinen Timer.
Und Hilfe findet man (wenn auch nur in Englisch) im MSDN.

von Richard Van Huizen (Gast)


Lesenswert?

Also haltet mich bitte nicht für total bescheuert aber ich kann beim
besten Willen keine vernünftige Doku zum Thema "Serielle Komunikation
mit Visual Basic 2005" finden.
Um Missverständnisse zu vermeiden werd ich mein Problem nochmal
schildern.
Ich möchte in VB 2005 Express mit der Klasse "SerialPort" (NEU, erst
seit VB 2005) zunächst mit einem Messgerät kommunizieren. Bisher habe
ich es geschafft den Port zu öffnen (Baudrate, etc. sind korrekt
eingestellt) und ein Zeichen, nämliche "D" (den Befehl zum Daten
senden) an das Messgerät zu schicken.
Was ich bisher nicht bewerkstelligen konnte war das korrekte und
vollständige Auslesen des Messwertes. Bisher funktionierte nur
".ReadTo(x)". Alle anderen Read-Methoden [ReadExisting(),
Read(puffer,offset,length), ...] klappen nicht und das Programm bricht
nach erreichen der ReadTimeOut ab.

Bitte gebt mir einen Hinweis wo ich eine Lösung für dieses Problem
finden kann. Möglicherweise liegt es ja am Messgerät, in diesem Fall
muss es doch so etwas wie einen virtuellen COM-Port geben, mit dem ich
das Programm testen kann.
Und bitte gebt die Links zu eventuellen Dokumentationen (auch MSDN) an
weil ich entweder zu Blöd bin die MSDN zu benutzen oder die
entsprechenden Hilfestellungen nicht in meiner Version (EXPRESS)
vorhanden sind.

Gruß und vielen Dank

Rich

von Rahul (Gast)


Lesenswert?


von Richard Van Huizen (Gast)


Lesenswert?

Beide Dokumente sind mir bekannt.

Mein Hauptproblem liegt darin, dass ich mir den Ablauf der ganzen
Kommunikation nicht so richtig vorstellen kann.
Außerdem sind mir die Funktionsweise und Voraussetzungen der
Read-Methoden nicht ersichtlich.
Hat denn bisher keiner mit der neuen Klasse "SerialPort" gearbeitet
und Erfahrungen gesammelt?

von arc (Gast)


Lesenswert?

Wie schon oben gesagt.
Zieh die Komponente auf eine Form und verknüpfe den DataReceived-Event
mit einer eigenen Methode. Sieht dann ungefähr so aus wie unten


sub DataReceived(byval sender as object, byval e as
System.IO.Ports.SerialDataReceivedEventArgs)
   if e.EventType = System.IO.Ports.SerialData.Chars
      str = str + port.ReadExisting
   if e.EventType = System.IO.Ports.SerialData.Eof
      ...
end sub

von Ralph Harms (Gast)


Lesenswert?

Also unter VB6 Pro habe ich das wie folgt gelöst :

Daten von Schnittstelle einlesen :

Private Sub MSComm1_OnComm()
    SerIN = MSComm1.Input
    SerialData = SerialData + SerIN
End Sub


Puffer "SerialData" bei Änderung prüfen :

Private Sub SerialData_Change()
    ...
    ...
End Sub



Ich weiss nicht, ob es unter VB Express auch funktioniert.




P.S.: Die Klasse SerialPort gab es schon unter VB6, allerdings nur in
der Pro-Version!

von Matthias (Gast)


Lesenswert?

Hallo,
vielleicht kann ich Dir auch noch ein wenig auf die Sprünge die Helfen.
Also ich zieh den Port nicht auf die Oberfläche, sondern lege eine
Instanz davon mit Event an - ganz einfach:
Private WithEvents mySerialport As New System.IO.Ports.SerialPort 'das
machts du als "globale Variable" gleich nach dem Klassennamen.
Dann musst du vor dem öffnen noch die ganzen Eigenschaften festtlegen,
evtl. bei New(), Form load oder direkt vor dem öffnen:
mySerialport.PortName = "COM1"
mySerialport.BaudRate = 19200
mySerialport.DataBits = 8
mySerialport.StopBits = IO.Ports.StopBits.One
mySerialport.Parity = IO.Ports.Parity.None
mySerialport.ReceivedBytesThreshold = 20 'damit legst du fest nach
wievielen angekommen Zeichen der DataReceived-Event ausgelöst werden
soll.
Den Event legst du einfach an, indem du im Pull-Down-Menü deiner Klasse
mySerialport auswählst und im Pull-Down-Menü rechts daneben den
gewünschten Event auswählst - sieht dann so aus:
Private Sub mySerialport_DataReceived(ByVal sender As Object, ByVal e
As System.IO.Ports.SerialDataReceivedEventArgs) Handles
mySerialport.DataReceived
        Dim data As String ' musst du natürlich global anlegen, sonst
sind die Daten gleich wieder weg
        data = moRS232.ReadExisting
    End Sub
Eventuell musst du noch die InputBuffergröße festlegen, wenn dir der
Default-Wert nicht reicht.
Ich hoffe damit und mit der msdn-Hilfe kommst du jetzt weiter.
Wenn du mit VB.net noch schwierigkeiten hast, such doch einfach nach
irgendwelchen Tutorien.
Viel Erfolg....

von Rage (Gast)


Lesenswert?

Hallo,

da wir gerade beim Thema sind, ich hab ein Problem mit dem Senden.
Vieleicht kennt jemand diesen Effekt, der sich durch senden von
unerwünschten nullen äußert. Mein Sourceauschnitt:


 Dim rs232 As New System.IO.Ports.SerialPort
        Dim i As Integer, comS$(8)
        Const genadr = 1
        Dim RS232Port As String

        comS$(1) = "COM1" : comS$(2) = "COM2" : comS$(3) = "COM3"
: comS$(4) = "COM4"
        comS$(5) = "COM5" : comS$(6) = "COM6" : comS$(7) = "COM7"
: comS$(8) = "COM8"

        RS232Port = "COM10"

        For i = 1 To 8

            Try
                With rs232

                    If .IsOpen = True Then .Close()
                    .BaudRate = 19200
                    .StopBits = IO.Ports.StopBits.One
                    .Parity = IO.Ports.Parity.None
                    .ParityReplace = 63
                    .ReadTimeout = 100
                    .ReadBufferSize = 4096
                    .WriteTimeout = 100
                    .WriteBufferSize = 2048
                    .DataBits = 8
                    .RtsEnable = False
                    .DtrEnable = False
                    .DiscardNull = False
                    .Handshake = IO.Ports.Handshake.None
                    .ReceivedBytesThreshold = 1
                    .PortName = comS$(i)
                    .Open()
                    .Write("+1a2" + Chr(13) + Chr(10))

                    If rs232.ReadLine = "-" & genadr & "OK" Then
RS232Port = comS$(i)

                End With

            Catch : End Try



        Next i



Ich wollte mit diese Routine ein Gerät am Com-Port suchen. Es würde
auch funktionieren, wenn VB nicht immer Nullen mitschicken würde. Was
mach ich nur falsch?

von Carsten Langerwisch (Gast)


Lesenswert?

Hallo! Habe mit Spannung und Interesse die oben stehene Diskussion
gelesen und viel gelernt. Meinen serial Pot kann ich nun mit VB 2005
Xpress ansteuern. Aber die von dem Gerät gesendeten daten kann ich
nicht auslesen, Programm hängt sich immer auf.
Woran kanns liegen?
Danke!

von Dirk (Gast)


Lesenswert?

Moin Leute,

also ich komme auch nicht wirklich klar. Ich möchte meinen AVR anbinden
und Daten empfangen. Ich kann erfolgreich Kommandos senden und der
Empfang klappt teilweise. Nach einem Startkommando sendet der AVR
zweimal pro Sekunde einen TAB getrennten Datensatz, ich bekomme aber
immer nur den ersten von neun Teilen zu sehen. irgendwie will VB den
Rest nicht haben?

Mit dem Hyperterminal klappt das alles hervoragend. Es sollte doch
möglich sein ohne ein VB-Genie zu sein ein kurzes Programm zu
schreiben, welches immer die ankommenden Daten anzeigt???

von Torben Schumacher (Gast)


Lesenswert?

Hallo Leute,
ich bin gerade dabei mit meinem MDA Vario die GPS-Position über den
virtuellen COM-Port (Bluetooth) einzulesen und ebenso die Daten einer
SAM4000-Schussauswertemaschine.

Die Datenflut habe ich schon langsam im Griff :-)

Allerdings möchte ich hier nicht ein 2000-Zeilen Programm abbilden.
Ich werde demnächst (morgen oder übermorgen) ein paar einfache
Prozeduren hier niederlegen (kleines Beispiel-Programm, damit die
Abhängigkeiten klar sind)

Eigentlich ist das nämlich auch ganz einfach.

1. Com-Port herausfinden
2. Com-Port öffnen
3. Event-Handler des Ports liest die Daten aus
4. Daten auswerten und verarbeiten.

Zu den Leuten, dessen Programme sich immer aufhängen -> VB legt per
Standard den Timout auf "endlos" und wartet bis zum Nimmerlein dass
Daten ankommen. Wer dieses in einer Timer-Funktion eingebaut hat bleibt
in der Prozedur hängen und bei Mobile-Geräten lässt sich nicht mal das
Programm per "Task-Manager" entfernen.
(Mein Reset-Knopf ist schon ganz abgenutzt g)

von AM (Gast)


Lesenswert?

Hallo,

finde den Thread sehr interessant. Habe gleiche Probleme, wie die 
anderen.
Ich kann keine Daten empfangen. Das DataReceived-Event springt nicht an. 
An was könnte das liegen? evlt. muss ich die Daten so abholen oder muss 
ich anfangs erst ein Steuerkommando an die Schnittstelle senden?

Wäre sehr dankbar für infos!!!

Gruß und Danke
am

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.