Forum: PC-Programmierung Problem mit der UART (RS232) Schnittstelle


von JBourges (Gast)


Lesenswert?

Hallo,
habe ein kleines Programm in Visual Basic "erschafffen" welches Daten zu 
einem ATMega32 über die UART sendet und auch welche empfängt! Kann es 
sein, dass beim Empfang über die RS232 mein Programm intern eine 
Empfangsbestätigung von sich aus sendet und wie kann ich dies 
verhindern? Ich sehe nämlich beim Empfang Impulse auf der Sendeleitung!

Hier die Empfangs - SUB:
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As 
System.IO.Ports.SerialDataReceivedEventArgs) Handles 
SerialPort1.DataReceived
.......
End SUB

Danke und schönen Abend noch
Jochen

von Bartosz B. (bartosz)


Lesenswert?

> Kann es
> sein, dass beim Empfang über die RS232 mein Programm intern eine
> Empfangsbestätigung von sich aus sendet

Normalerweise nicht. Wie erstellst du die Port-Eigenschaften im Visual 
Studio?
Ich habe Folgendes im Button_verbinden_Click

1
If Not SerialPort1.IsOpen Then
2
            Button_verbinden.Enabled = False
3
            SerialPort1.PortName = ComboBox1.SelectedItem.ToString
4
            SerialPort1.BaudRate = 19200
5
            SerialPort1.DataBits = 8
6
            SerialPort1.Parity = IO.Ports.Parity.None
7
            SerialPort1.StopBits = IO.Ports.StopBits.One
8
            SerialPort1.DtrEnable = True
9
            SerialPort1.RtsEnable = True
10
            SerialPort1.Handshake = IO.Ports.Handshake.None
11
            SerialPort1.NewLine = Environment.NewLine 'oder Convert.ToChar(13)
12
            SerialPort1.Open()
13
        End If

und im Data_Received_Event
1
Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
2
        If SerialPort1.IsOpen Then
3
            Dim Anzahl_Bytes As Integer = SerialPort1.BytesToRead 'Ermitteln, wie viele Bytes kommen.
4
            If Anzahl_Bytes > 0 Then
5
                Dim COMBuffer() As Byte = New Byte(Anzahl_Bytes - 1) {} 'Ein Byte-Array mit genau dieser Anzahl erstellen.
6
                SerialPort1.Read(COMBuffer, 0, Anzahl_Bytes) 'einlesen
7
                Me.Invoke(Sub() Evaluate_Message(COMBuffer)) 'den Text ausgeben lassen (funktioniert nur mit Invoke, weil die SerialPort-Klasse einen eigenen Thread hat).
8
            End If
9
        End If
10
    End Sub

Das Einzige, was mir spontan einfallen würde, wäre der Handshake, der 
den Empfang von Daten quittiert. Der ist bei mir immer aus.

von JBourges (Gast)


Lesenswert?

Danke! Ich schicke dir mal den Inhalt der gesamten SUB und der 
Initialisierung der COM. Ist hier leider nicht so übersichtlich. Aber du 
kannst recht haben mit dem Handshake. Habe ein älteres Null-Modem-Kabel 
als Verbindung genutzt, bei dem noch eine Brücke drin ist. Mein jetziges 
(nur RD und Td) hat nur 3 Leitungen und ich habe das Problem nicht mehr!

Private Sub Button1_Click(sender As System.Object, e As 
System.EventArgs) Handles Button1.Click     'Connect-Button
        Try
            SerialPort1.PortName = TextBox1.Text   'Com1
            SerialPort1.BaudRate = TextBox2.Text   '2400
            SerialPort1.Open()
            TextBox3.Focus()          'Fokus wird auf TextBox3 gesetzt
            Button1.Enabled = False
            Button2.Enabled = True
            Button3.Enabled = True
            Button4.Enabled = True
            Button5.Enabled = True
            Button6.Enabled = True
        Catch ex As Exception
            MsgBox("Verbindung konnte nicht hergestellt werden!")
            SerialPort1.PortName = "COM1"
            SerialPort1.BaudRate = "9600"
        End Try
    End Sub

Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As 
System.IO.Ports.SerialDataReceivedEventArgs) Handles 
SerialPort1.DataReceived

        Dim ZBytes As Integer = SerialPort1.BytesToRead          'Anzahl 
der Bytes im Empfangspuffer
        U555Dat = CByte(SerialPort1.ReadByte())

        Invoke(Sub()
                   Label4.Text = U555Dat.ToString() 
'SerialPort1.Read(MyArray, 0, 2) oder BitConverter.ToUInt16(ZEmpf, 0)

        If Merker1 = True Then
           TextBox7.Text = TextBox7.Text & U555Add & " ; " & U555Dat & 
vbCrLf
           U555Add = U555Add + 1

           If U555Add > BisAdd Then
              U555Add = BisAdd
              Button2.Enabled = True
              Button5.Enabled = True
              Merker1 = False
          End If

          TextBox3.Text = U555Add

          MyArray = BitConverter.GetBytes(U555Add)
          SerialPort1.Write(MyArray, 0, 2)

       End If
       End Sub)
    End Sub

Danke nochmalvom Jörg

von Bartosz B. (bartosz)


Angehängte Dateien:

Lesenswert?

Ok, gut.
Du solltest 2 Sachen einstellen:
Option Strict On einschalten und Option Infer auf Off stellen.
Option Strict On sorgt für, dass du die Datentypen richtig umwandelst. 
So konnte ich 2 Fehler entdecken: Der Text aus TextBox2 muss zu einem 
Integer umgewandelt werden (und du solltest vorher abprüfen, ob der 
Benutzer keinen Quatsch eingibt) und zum anderen ist die BaudRate = 
9600, statt dem String "9600". 🙂

Option Infer Off sorgt dafür, dass du dir angewöhnst, ...
1
As Integer
 oder
1
As String
 zu schreiben
1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
2
        Try
3
            SerialPort1.PortName = TextBox1.Text   'Com1
4
            SerialPort1.BaudRate = CInt(TextBox2.Text)   '2400
5
            SerialPort1.Open()
6
            TextBox3.Focus()          'Fokus wird auf TextBox3 gesetzt
7
            Button1.Enabled = False
8
            Button2.Enabled = True
9
            Button3.Enabled = True
10
            Button4.Enabled = True
11
            Button5.Enabled = True
12
            Button6.Enabled = True
13
        Catch ex As Exception
14
            MsgBox("Verbindung konnte nicht hergestellt werden!")
15
            SerialPort1.PortName = "COM1"
16
            SerialPort1.BaudRate = 9600
17
        End Try
18
    End Sub

Und noch eine dritte Sache, wenn es dir möglich ist*: Nimm den 
VB6-Namespace raus. Dann ist kein alter VB6-Code im Programm. Es gibt 
nämlich heute Funktionen, die effizienter sind. Es heißt
1
MessageBox.Show("Dein Text", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)

* Es kann je nach Hardware sein, dass du doch VB6 brauchst. Zum Beispiel 
für vbCrLf. Ich weiß nicht, ob dir das Environment.NewLine reicht...

Was dein Data-Received-Sub angeht, da weiß ich nicht, was U555Dat sein 
soll.

: Bearbeitet durch User
von Bartosz B. (bartosz)


Angehängte Dateien:

Lesenswert?

Du kannst auch noch Folgendes machen: In einer ComboBox den Benutzer 
auswählen lassen, welcher COM-Port genommen werden soll. Du musst nur 
invoken, da der SerialPort-Thread nicht gleich dem GUI-Thread ist.
1
 Private Sub Form_Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
2
        Me.Invoke(Sub() ComboBox1.Items.AddRange(IO.Ports.SerialPort.GetPortNames()))

von JBourges (Gast)


Angehängte Dateien:

Lesenswert?

Danke  Bartosz B. für Deine Hilfe!
"Option Strict On" habe ich immer schon in den Settings eingeschaltet. 
Die COM1 soll die einzige COM sein, da diese auch tatsächlich vorhanden 
ist und nicht über einen USB-Wandler! Man kann diese aber auch ändern im 
Programm! U555Dat sind die Eingangsdaten des sehr sehr alten EPROMs in 
Word, die nach dem String in eine Textdatei (später csv) geschrieben 
werden. Die Daten sind durch " ; " getrennt. vbCrLf funktioniert sogar 
noch unter Visual Studio 2015 unter Windows 10. Nehme auch gern noch die 
MsgBox. Ist aber bei den Profis wohl verpönt, warum auch immer.
Das Programm funktioniert jetzt sehr gut. Es soll ja nur die EPROMs 
auslesen. Das Brennprogramm wird nächstes Jahr realisiert.
Danke nochmal und ein gesundes neue Jahr wünscht
Jörg

Hänge mal das komplette Programm als zip an!

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.