VB Serial Port Datenempfang nicht komplett

OP #3092860
Lesenswert?

Hi,

ich habe mir eine Form in VB gebastelt in der ich die Serielle 
Schnittstelle auswerte.
Dort kommen Daten von einem Mikrocontroller rein.
Das komische ist, dass der Mikrocontroller circa 250 mal eine Zeile 
sendet die in ca. so aussieht "11|22|33|44\r\n", mein VB Projekt aber 
bei 158 empfangenen Zeilen immer Schluss macht!
Mit einem Terminal Programm welches wie Bild 1 eingestellt ist, klappt 
die komplette Übertragung!

Ich hatte den Fehler erst woanders gesucht, diesen Vorgang und andere 
Einstellwerte sieht man noch in diesem 
Thread:Beitrag "Ethernet - Serielle Verbindung"
Aber offensichtlich, da es ja im Terminal klappt, liegt der Fehler 
womöglich in VB Projekt...

Kann mir einer sagen was ich da Falsch machen?!?

Hier der Code des VB-Projekts:
1
Public Class Form1
2
    Dim SerialInput As String = ""
3

4

5

6

7

8

9
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
10

11
        '   SerialPort1.PortName = "COM4"
12
        '   SerialPort1.BaudRate = 9600
13
        '   SerialPort1.Parity = IO.Ports.Parity.None
14
        '   SerialPort1.DataBits = 8
15
        '   SerialPort1.StopBits = IO.Ports.StopBits.One
16
        '    SerialPort1.Handshake = IO.Ports.Handshake.None
17
        ' SerialPort1.RtsEnable = True
18
        SerialPort1.Open()
19

20
        If SerialPort1.IsOpen Then
21
            Label1.Text = "...verbunden"
22
            SerialPort1.Write("11|22|33|44" + Chr(13))
23
        Else
24
            Label1.Text = "...getrennt"
25
        End If
26
    End Sub
27

28
   
29

30

31

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

34

35
        SerialInput = SerialPort1.ReadLine()
36
        Me.Invoke(New EventHandler(AddressOf DoUpdate))
37

38

39
    End Sub
40

41
    Public Sub DoUpdate()
42

43
        ListBox1.Items.Insert(0, "Recv: " & SerialInput)
44
        TextBox1.Text = TextBox1.Text + 1
45

46
    End Sub
47

48

49

50
    Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
51
        SerialPort1.Write(TextBox5.Text & Convert.ToChar(13) & Chr(13))
52
    End Sub
53

54
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
55
        ListBox1.Items.Clear()
56
        TextBox1.Text = 0
57
    End Sub
58

59
    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
60
        If SerialPort1.IsOpen = True Then
61
            SerialPort1.Close()
62
        End If
63

64
        Me.Close()
65

66
    End Sub
67

68
End Class
Angehängte Dateien:
Gast #3092880
Lesenswert?

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

das ist schon mal unsinn. Du kannst du nicht im demn Event mehr daten 
empfangen als vorhanden sind.
OP #3093428
Lesenswert?

Peter II schrieb:
> das ist schon mal unsinn. Du kannst du nicht im demn Event mehr daten
> empfangen als vorhanden sind.

Warum genau ist das Unsinn?
Wie kann ich es besser machen?

Ich kann es auch direkt ohne Zwischenvariable schreiben, jedoch macht 
das keine Unterschied!
1
    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
2
        Me.Invoke(New EventHandler(AddressOf DoUpdate))
3
    End Sub
4

5
    Public Sub DoUpdate()
6

7
        ListBox1.Items.Insert(0, "Recv: " & SerialPort1.ReadLine())
8
        TextBox1.Text = TextBox1.Text + 1
9

10
    End Sub
OP #3093462
Lesenswert?

Aber gehen wir mal davon aus, dass ich immer ein Zeilenende habe. Merke 
ich alleine schon daran, dass wenn ich die ersten Sendestrings auf 
Mikrocontroller Seite entferne, macht er trotzdem 158. Also geht dann 
ein bischen weiter in der Liste...
Wie kriege ih denn ein Zeilenende mit ReadExisting mit?!?

Das ist doch mal wieder ein kack Fehler...
#3093468
Lesenswert?

Alexander Alexander schrieb:
> Aber gehen wir mal davon aus, dass ich immer ein Zeilenende habe. Merke
> ich alleine schon daran, dass wenn ich die ersten Sendestrings auf
> Mikrocontroller Seite entferne, macht er trotzdem 158. Also geht dann
> ein bischen weiter in der Liste...
> Wie kriege ih denn ein Zeilenende mit ReadExisting mit?!?

Indem du dir ansiehst, was von der Seriellen auf PC Seite alles 
herauspurzelt. Wenn da ein Carriage Return dabei ist, dann war alles 
davor eine Zeile. Wenn da nur ein einsames '1' herauspurzelt, dann wurde 
eben bis zu dem Zeitpunkt an dem du die Serielle befragst nur dieses 
eine Zeichen übertragen und der Rest kommt später.
OP #3093486
Lesenswert?

Mit ReadExisting liest er alles ein, genau wie das Terminal Programm das 
ordentlich der Zeile nach einliest!

Ich verstehe nur nicht warum das ReadLine nicht richtig macht? Hinter 
jedem Sendebefehl im Mikrocontroller ist ein Return:

Ich habe gerade diese Zeile 400mal kopiert:

usart_writePC ("89|25|01|01\r\n");
usart_writePC ("89|25|01|01\r\n");
usart_writePC ("89|25|01|01\r\n");
usart_writePC ("89|25|01|01\r\n");
...
...

Trotzdem hört er jetzt nach 195-200 Zeilen auf
#3093497
Lesenswert?

Alexander Alexander schrieb:
> Mit ReadExisting liest er alles ein, genau wie das Terminal Programm das
> ordentlich der Zeile nach einliest!
>
> Ich verstehe nur nicht warum das ReadLine nicht richtig macht?

Ich schätze mal, dass das ReadLine ins Timeout laufen wird.

> Hinter
> jedem Sendebefehl im Mikrocontroller ist ein Return:

Alles schön und gut.
Aber der Event wird ausgelöst, sobald das erste Zeichen im PC 
eintrudelt. Da hat dein µC den Return noch gar nicht weggeschickt.

Du scheinst in der Annahme zu leben, dass irgendwie instantan im PC der 
komplette String "89|25|01|01\r\n" auftaucht, sobald du auf µC Seite 
einen

> usart_writePC ("89|25|01|01\r\n");

aufrufst.
Dem ist nicht so. Die Übertragung braucht ja auch Zeit und geht Zeichen 
für Zeichen.
#3093502
Lesenswert?

> usart_writePC ("89|25|01|01\r\n");
> ...
> ...
>
> Trotzdem hört er jetzt nach 195-200 Zeilen auf

Tipp: schick nicht immer dieselbe Zeile. Sorge dafür, dass sich da etwas 
systematisch verändert und wenn es nur ein Zähler ist der hochzählt.
Dann kannst du am PC nämlich auch feststellen, ob dir nicht 
zwischendurch ein paar Zeilen flöten gegangen sind und dieses 'aufhören' 
völlig zu recht erfolgt ist, weil tatsächlich nichts mehr kommt.
OP #3093507
Lesenswert?

Normalerweise sind das auch alles andere Werte, aber alle Querbet, nicht 
fortlaufend oder so.... Wie soll ich das denn auswerten?!

...
if (StatusByteSteck5&0b00000100)usart_writePC ("83|13|03|01\r"); else 
usart_writePC ("83|13|03|00\r");
if (StatusByteSteck5&0b00001000)usart_writePC ("83|13|04|01\r"); else 
usart_writePC ("83|13|04|00\r");
if (StatusByteSteck6&0b00000001)usart_writePC ("83|14|01|01\r"); else 
usart_writePC ("83|18|01|00\r");
if (StatusByteSteck6&0b00000010)usart_writePC ("83|14|02|01\r"); else 
usart_writePC ("83|18|02|00\r");
if (StatusByteSteck6&0b00001000)usart_writePC ("83|15|01|01\r"); else 
usart_writePC ("83|15|01|00\r");
if (StatusByteSteck6&0b00010000)usart_writePC ("83|15|02|01\r"); else 
usart_writePC ("83|15|02|00\r");
if (StatusByteSteck6&0b00100000)usart_writePC ("83|15|03|01\r"); else 
usart_writePC ("83|16|03|00\r");
if (StatusByteSteck6&0b01000000)usart_writePC ("83|15|04|01\r"); else 
usart_writePC ("83|16|04|00\r");
if (StatusByteSteck6&0b10000000)usart_writePC ("83|15|05|01\r"); else 
usart_writePC ("83|15|05|00\r");
....
#3093514
Lesenswert?

Alexander Alexander schrieb:
> Normalerweise sind das auch alles andere Werte, aber alle Querbet, nicht
> fortlaufend oder so.... Wie soll ich das denn auswerten?!

Ich denke im Moment geht es darum die PC Seite korrekt hinzukriegen, 
oder nicht?

Wer oder was hindert dich daran, in deinen µC ein Programm zu brennen

  for( i = 0; i < 99; i++ )
    for( j = 0; j < 99; j++ )
      for( k = 0; k < 99; k++ )
        for( l = 0; l < 99; l++ )
        {
          sprintf( str, "%02d|%02d|%02d|%02d\r", i, j, k, l );
          usart_writePC( str );
        }

damit debuggst du erst mal die PC-Seite Empfangsroutine und wenn da dann 
alles korrekt ist, dann kannst du deinen richtigen Code wieder auf den 
PC hetzen.
OP #3093561
Lesenswert?

Also mein Terminal empfängt die Schleife richtig...dauert ewig;-)

Mein VB Projekt empfängt garnichts, wenn ich meine Form schliesse, kommt 
die Fehlermeldung (s. Bild 1)

Was macht das Terminal besser als ich?!?!? ;-)

VB Code:
1
Imports System.IO.Ports
2

3

4

5
Public Class Form1
6
    Dim SerialInput As String = ""
7

8

9

10

11

12

13
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
14

15
        SerialPort1.PortName = "COM4"
16
        SerialPort1.BaudRate = 9600
17
        SerialPort1.Parity = IO.Ports.Parity.None
18
        SerialPort1.DataBits = 8
19
        SerialPort1.StopBits = IO.Ports.StopBits.One
20
        SerialPort1.Handshake = IO.Ports.Handshake.None
21
        SerialPort1.RtsEnable = False
22
        SerialPort1.DtrEnable = False
23
        SerialPort1.Open()
24

25
        If SerialPort1.IsOpen Then
26
            Label1.Text = "...verbunden"
27
            SerialPort1.Write("11|22|33|44" + Chr(13))
28
        Else
29
            Label1.Text = "...getrennt"
30
        End If
31
    End Sub
32

33

34

35

36

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

39

40

41
            SerialInput = SerialPort1.ReadLine()
42

43

44

45

46
            Me.Invoke(New EventHandler(AddressOf DoUpdate))
47

48
    End Sub
49

50

51

52

53

54
    Public Sub DoUpdate()
55

56

57

58
        ListBox1.Items.Insert(0, "Recv: " & SerialInput)
59
        TextBox1.Text = TextBox1.Text + 1
60

61
    End Sub
62

63

64

65
    Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
66
        SerialPort1.Write(TextBox5.Text & Convert.ToChar(13) & Chr(13))
67
    End Sub
68

69
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
70
        ListBox1.Items.Clear()
71
        TextBox1.Text = 0
72
    End Sub
73

74
    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
75
        If SerialPort1.IsOpen = True Then
76
            SerialPort1.Close()
77
        End If
78

79
        Me.Close()
80

81
    End Sub
82

83
End Class
Angehängte Dateien:
Gast #3093566
Lesenswert?

Alexander Alexander schrieb:
> Mein VB Projekt empfängt garnichts, wenn ich meine Form schliesse, kommt
> die Fehlermeldung (s. Bild 1)

steht doch alles da - es hängt in ReadLine während du versucht das 
Programm zu beenden.

entweder du verwendest einen Thread mit ReadLine oder du verwendest 
ReadExisting. Aber wie du es machst geht es nun mal nicht.
Gast #3093658
Lesenswert?

Alex schrieb:
> Wie geht das mit den Thread? Kenn ich noch nicht...

dann macht es auch nicht damit, ein thread ereugt erstmal noch mehr 
probleme als Lösungen.

mach einfach

String Data;

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

Data += SerialPort1.ReadExisting()

int pos = Data.IndexOf('\n');
if ( pos >= 0 ) {
   String meineDaten = Data.Substring(0, pos );
   //verarbeite meineDaten
   Data = Data.Substring( pos, Data.length-pos );
}
#3093792
Lesenswert?

Hallo

Ich würde auch gerne mal wieder ein wenig in Delphi programmieren. Vor 
allem Kommunikation via Serial-Ports!

Ich habe noch eine Delphi6 CD + Buch da Heim. Die ist von 2004 oder so. 
Bei welcher Version ist man denn jetzt? Und ist Delphi Software frei 
verfügbar im Internet erhältlich?


Gruß Steffen
OP #3095324
Lesenswert?

Peter II schrieb:
> String Data;
>
> Private Sub SerialPort1_DataReceived(ByVal sender As System.Object,
> ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles
> SerialPort1.DataReceived
>
> Data += SerialPort1.ReadExisting()
>
> int pos = Data.IndexOf('\n');
> if ( pos >= 0 ) {
>    String meineDaten = Data.Substring(0, pos );
>    //verarbeite meineDaten
>    Data = Data.Substring( pos, Data.length-pos );
> }

Hi,

ich programmiere mit Visual Basic 2010 mit "String Data" kann ich leider 
nichts anfangen. Wie sieht das in VB aus?!?!?
#3095329
Lesenswert?

Alexander Alexander schrieb:
> Peter II schrieb:
>> String Data;
>>
>> Private Sub SerialPort1_DataReceived(ByVal sender As System.Object,
>> ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles
>> SerialPort1.DataReceived
>>
>> Data += SerialPort1.ReadExisting()
>>
>> int pos = Data.IndexOf('\n');
>> if ( pos >= 0 ) {
>>    String meineDaten = Data.Substring(0, pos );
>>    //verarbeite meineDaten
>>    Data = Data.Substring( pos, Data.length-pos );
>> }
>
> Hi,
>
> ich programmiere mit Visual Basic 2010 mit "String Data" kann ich leider
> nichts anfangen. Wie sieht das in VB aus?!?!?

String    ist der Datentyp
Data      ist der Name der Variablen

Bei dir dann wohl

   Dim Data As String = ""


Bitte in bischen mitdenken, wie wohl
1
  Data += SerialPort1.ReadExisting()
2

3
  int pos = Data.IndexOf('\n');
4
  if ( pos >= 0 ) {
5
     String meineDaten = Data.Substring(0, pos );
6
     //verarbeite meineDaten
7
     Data = Data.Substring( pos, Data.length-pos );
8
  }
arbeitet. Das ist nach all dem Vorgeplänkel wirklich nicht schwer zu 
verstehen.
OP #3096797
Lesenswert?

Hallo,

ich habe des jetzt mal ausprovbiert und komme nicht darauf wofür das
 meineDaten = s.Substring(0, pos)

ist?!?!

Was soll das bringen?


Leider kommt so garnichts auf die Anzeige
1
    Dim SerialInput As String = ""
2

3

4
    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
5
        Dim pos As Integer
6
        Dim meineDaten As String
7

8
        SerialInput += SerialPort1.ReadExisting()
9

10
        pos = SerialInput.IndexOf(vbCr)
11

12
        If (pos >= 0) Then
13
            meineDaten = s.Substring(0, pos)
14
            'verarbeite meineDaten
15
            SerialInput = SerialInput.Substring(pos, SerialInput.Length - pos)
16
        End If
17

18
    End Sub
#3096944
Lesenswert?

Alexander Alexander schrieb:
> Hallo,
>
> ich habe des jetzt mal ausprovbiert und komme nicht darauf wofür das
>  meineDaten = s.Substring(0, pos)
>
> ist?!?!
>
> Was soll das bringen?


OK. Du bist der Computer und ich die Gegenstelle. Ich schicke dir

 "86|2"

bzw. das ist das, was im UART Empfangsbuffer vorliegt, wenn dein Message 
Handler mittels ReadExisting die Finger an die empfangenen Daten kriegt.

Was machst du damit?
Noch gar nichts. Da ist noch kein \n enthalten, daher kannst du noch 
nichts damit anfangen. Die Daten werden einfach mal in der Variablen 
zwischengespeichert, wo sie vor sich rumlungern, bis das nächste mal 
Windows meldet: Ich hab was an der Seriellen für dich.

Gut. Die Zeit vergeht und als nächstes trudelt ein

  "5|01|"

das hängst du an das bisher empfangene hinten drann. D.h. bisher hast du 
empfangen

  "86|25|01|"

kannst du damit was anfangen?
Nein. Immer noch kein \n weit und breit. D.h. der zusammengestückelte 
String lungert weiter vor sich hin in der Variablen 'Data' und wartet 
drauf, dass von der Seriellen noch was kommt.

Dauert auch nicht lange und Windows meldet wieder, dass es Daten an der 
UART zur gefälligen Entgegennahme für dich hätte.
Aus ReadExisting kriegst du raus

   "01\r\n89|"

Das wird wieder an das bisher empfangene hinten drann gehängt, sodass in 
Data jetzt steht

  "86|25|01|01\r\n89|"

Kannst du damit was anfangen?
Ja! Jetzt kannst du damit was anfangen. Hier

  "86|25|01|01\r\n89|"
                 ^
                 |
                 |

ist der \n, der das Ende der Zeile markiert. Um also an die Zeile zu 
kommen, brauchst du diesen

  "86|25|01|01\r\n89|"
   |             |
   |             |
   +-------------+

Teil des Strings. Das ist deine Zeile.
Und das was dann noch in Data übrig bleibt, das ist schon wieder der 
Anfang der nächsten Zeile. D.h. du schneidest dir genau diesen Teil aus 
Data raus

  "86|25|01|01\r\n"

und anschliessend stutzt du Data so zurecht, dass der rausgeschnittene 
Teil da drinnen nicht mehr vorkommt

  "89|"

und wenn dann die nächsten Daten eintrudeln

     "25|01|05"

dann werden die, alles wie gehabt, wieder hinten an Data drann gehängt

  "89|25|01|05"

und alles geht weiter seinen gewohnten Gang.


So. Und jetzt geh nochmal den Code durch, den du gekriegt hast und 
studier den nochmal, ob du diese Operationen da drinnen wiederfindest.
Gast #3097434
Lesenswert?

Dim SerialInput As String = ""


    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, 
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles 
SerialPort1.DataReceived
        Dim pos As Integer
        Dim meineDaten As String


        SerialInput += SerialPort1.ReadExisting()
> Hier wird das SerialInput jedesmal mit ReadExisting Erweitert und nicht 
>überschrieben.
        pos = SerialInput.IndexOf(vbCr)
> Hier wird geguckt auf welcher Postiion sich ein CarriageReturn ("\r" >oder doch 
beides? "\r\n") befindet
        If (pos >= 0) Then
> Wenn ein CR gefunden
            meineDaten = SerialInput .Substring(0, pos)
> Zeigt den Ersten String bis zum CR an, aber nur den ersten...86|25|01|01
>            'verarbeite meineDaten
            SerialInput = SerialInput.Substring(pos, SerialInput.Length 
- pos)
> hier würde jetzt auch immer der String stehen der vom letzten bis zum aktuellen 
gefundenen CR steht.
        End If

Ist doch so richtig, oder? Wofür ist dann meineDaten = SerialInput 
.Substring(0, pos) ???

    End Sub
Gast #3097437
Lesenswert?

Alex schrieb:
> Ist doch so richtig, oder? Wofür ist dann meineDaten = SerialInput
> .Substring(0, pos) ???

das kann doch nicht so schwer sein, versteht du überhaupt was du machst? 
Das ist Deine Daten auf die du gewartest hast und die jetzt verarbeitet 
werden können.
#3097639
Lesenswert?

Alex schrieb:

> Ist doch so richtig, oder? Wofür ist dann meineDaten = SerialInput
> .Substring(0, pos) ???


Weil du nach dem finden des CR in SerialInput DIESEN Fall vorliegen 
haben kannst

  "86|25|01|01\r\n89|"

Da ist deine Zeile drinnen, schon richtig. Aber da ist auch mehr als 
diese eine Zeile drinnen! (wenn du mal genau schauen würdest)

Du musst dich endlich von der Vorstellung lösen, dass du von der 
Seriellen wieder deine Zeilenstruktur kriegst, so wie du das gewohnt 
warst bzw. so wie du das am µC wegschickst.

DEM IST NICHT SO!

Von der Seriellen kommen Bytes rein. Und zwar aus Sicht des Handlers 
eines oder MEHRERE auf einmal. Je nachdem wie Windows gerade Zeit hatte 
den UART Puffer auszuleeren, bzw. je nachdem ob dein Programm Zeit hatte 
sofort auf die Benachrichtigung von Windows zu reagieren.
Und es ist deine Aufgabe dir aus dem Bytestrom wieder die Zeilen, die du 
brauchst, rauszuholen. Nur dann musst du aber auch wirklich irgendwann 
mal aus dem empfangenen Bytestrom die dich interessierende Zeile 
rausholen! Und zwar ohne dass du irgendwelche Annahmen triffst, was 
alles in der Zwischenzeit sich in deinem Buffer angesammelt hat. Du 
kannst nicht davon ausgehen, dass nur und ausschliesslich die Bytes 
einer einzigen Zeile in deinem Buffer stehen, wenn du dir mit 
ReadExisting die nächsten Daten holst. Das mag manchmal so sein, aber du 
hast keine Garantie dafür. Also triff auch nicht diese Annahme.
#3097647
Lesenswert?

>             meineDaten = SerialInput .Substring(0, pos)
>    Zeigt den Ersten String bis zum CR an,

Was heißt hier 'zeigt an'. Da wird überhaupt nichts angezeigt. Aus dem 
empfangenen Bytestrom wird der Teil rauskopiert, der einer Zeile 
entspricht (weil pos ja anzeigt, wo der \n ist).

was dann damit weiter passiert, ob das auf eine Anzeige geht oder ob das 
in einem File gespeichert wird oder ... das interessiert hier nicht. 
meineDaten ist eine Variable und was immer mit deren Inhalt weiter 
passiert, das passiert. Aber das interessiert ja den Empfangscode nicht.
Gast #3097801
Lesenswert?

Danke für deine Antworten und Entschuldigung wenn  ich nicht so schlau 
bin wie Du auf dem Gebiete der Programmierung!

Wofür brauche ich genau:

meineDaten = SerialInput .Substring(0, pos)

Wenn ich vom Mikrocontroller ein solchen String senden:

11|22|33|44\r\n55|66|77|88\r\n99|00|12|23\r\n34|45|56|78\r\n


steht in  meineDaten dann:

11|22|33|44
wenn die nächste pos gefunden:
11|22|33|4455|66|77|88
wenn die nächste pos gefunden
11|22|33|4455|66|77|8899|00|12|23
wenn die nächste pos gefunden
11|22|33|4455|66|77|8899|00|12|2334|45|56|78

Das brauche ich doch nicht...?

Ich verstehe das nicht?!
#3097834
Lesenswert?

Alex schrieb:
> Danke für deine Antworten und Entschuldigung wenn  ich nicht so schlau

> Wenn ich vom Mikrocontroller ein solchen String senden:
>
> 11|22|33|44\r\n55|66|77|88\r\n99|00|12|23\r\n34|45|56|78\r\n
>
>
> steht in  meineDaten dann:
>
> 11|22|33|44
> wenn die nächste pos gefunden:
> 11|22|33|4455|66|77|88

nö.

meine Daten wird ja überschrieben
Beim nächsten mal steht
55|66|77|88

drinnen.

> wenn die nächste pos gefunden
> 11|22|33|4455|66|77|8899|00|12|23

nö
99|00|12|23

> wenn die nächste pos gefunden
> 11|22|33|4455|66|77|8899|00|12|2334|45|56|78

nö
34|45|56|78

> Das brauche ich doch nicht...?

Du wolltest doch die Zeilen einzeln haben!

Hier
  SerialInput = SerialInput.Substring(pos,
                                      SerialInput.Length - pos)

wird aus dem empfangenen der Teil, der mittels meineDaten 
zurückgeliefert wurde, vorne rausgeschnitten.
Nachdem
  11|22|33|44
nach meineDaten kopiert wurde, wird aus 11|22|33|4455|66|77|88 der 
Anfang entfernt, so dass danach nur noch 55|66|77|88 für den nächsten 
Aufruf übrig bleibt. Beim nächsten mal kann daher gar nicht mehr
11|22|33|4455|66|77|88
in meineDaten geliefert werden, weil der Teil 11|22|33|44 in SerialInput 
schon längst nicht mehr drinnen steht!
#3097839
Lesenswert?

Alex schrieb:
> Danke für deine Antworten und Entschuldigung wenn  ich nicht so schlau
> bin wie Du auf dem Gebiete der Programmierung!


Das hat mit schlau nichts zu tun.

Schnapp dir Papier und Bleistift und spiele Computer.
Denk dir eine Abfolge von Zeichen aus, wie sie bei mehreren Aufrufen der 
Funktion aus ReadExisting herauskommen können und arbeite jedesmal den 
Code durch.

Dein Computer macht letzten Endes auch nichts anderes.

Das

  11|22|33|44\r\n55|66|77|88\r\n99|00|12|23\r\n34|45|56|78\r\n

ist das, was dein µC sendet.
Jetzt nimm an, dass aus dem PC folgendes passiert

die SerialPort1_DataReceived wird aufgerufen
   ReadExisting liefert     11|22|3

die SerialPort1_DataReceived wird aufgerufen
   ReadExisting liefert     3|44\r\n55

die SerialPort1_DataReceived wird aufgerufen
   ReadExisting liefert     |66|77|88\r\n

die SerialPort1_DataReceived wird aufgerufen
   ReadExisting liefert     99|00|1

die SerialPort1_DataReceived wird aufgerufen
   ReadExisting liefert     2|23\r

die SerialPort1_DataReceived wird aufgerufen
   ReadExisting liefert     \n34|45|45|78\r\n


gehs nicht im Kopf durch sondern schnapp dir Papier und Bleistift und 
schreib dir auf welche Variablen welche Werte haben. Und ansonsten 
machst du genau das (und nur das), was im Programmtext steht.

Wenn dus dann immer noch nicht hast, dann kann ich dir nur noch raten, 
dir ein anderes Hobby zu suchen.
OP #3100302
Lesenswert?

Ich habe es nocheinmal mit diesem Code ausprobiert und da kommt, so wie 
ich schon vermutete habe, nicht das richtig raus:
1
Public Class Form1
2

3
    Dim meineDaten As String
4

5
    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
6
        Dim pos As Integer
7
        Dim SerialInput As String
8

9
        SerialInput = SerialPort1.ReadExisting()
10

11
        pos = SerialInput.IndexOf(vbCr)
12

13
        If (pos >= 0) Then
14
            meineDaten = SerialInput.Substring(0, pos)
15
            'verarbeite meineDaten
16
            SerialInput = SerialInput.Substring(pos, SerialInput.Length - pos)
17
            Me.Invoke(New EventHandler(AddressOf DoUpdate))
18
        End If
19

20
    End Sub
21

22
    Public Sub DoUpdate()
23
        ListBox1.Items.Insert(0, "Recv: " & meineDaten)
24
        TextBox1.Text = TextBox1.Text + 1
25

26
    End Sub
27
End Class

auf dem Mikro:
1
 for( uint16_t i = 0; i < 4; i++ )
2

3
    for( uint16_t j = 0; j < 4; j++ )
4

5
    for( uint16_t k = 0; k < 4; k++ )
6
    
7
      for( uint16_t l = 0; l < 4; l++ )
8
      {
9
      sprintf( str, "%02d|%02d|%02d|%02d\r", i, j, k, l );
10
      usart_write_str0(str);
11
      }
12
      
13
  usart_write_str0(test);

Ausgabe in der Listbox siehe Anhang.
Angehängte Dateien:
Gast #3100328
Lesenswert?

Du wirfst Daten weg, wenn kein CR im DataReceived-Aufruf dabei ist ;D

Ungetesteter (keine VB.net-Kenntnisse) Änderungsvorschlag:
1
Dim SerialInput As String
2
Dim eineZeile As String
3

4
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
5
  Dim pos As Integer
6

7
  // Daten an SerialInput dranhängen, statt SerialInput zu überschreiben
8
  SerialInput = SerialInput + SerialPort1.ReadExisting()
9

10
  pos = SerialInput.IndexOf(vbCr)
11
  If (pos >= 0) Then
12
    eineZeile = SerialInput.Substring(0, pos)
13
    'verarbeite meineDaten
14
    SerialInput = SerialInput.Substring(pos, SerialInput.Length - pos)
15
    Me.Invoke(New EventHandler(AddressOf DoUpdate))
16
  End If
17

18
End Sub
19

20
Public Sub DoUpdate()
21
  ListBox1.Items.Insert(0, "Recv: " & eineZeile)
22
  TextBox1.Text = TextBox1.Text + 1
23

24
End Sub
OP #3100337
Lesenswert?

Da hatten wir ne Doppelpost...sorry. Damit bekomme ich dann 
komischerweise folgende Anzeige!
1
    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
2
        Dim pos As Integer
3

4

5

6
        '' Daten an SerialInput dranhängen, statt SerialInput zu überschreiben
7
        SerialInput = SerialInput + SerialPort1.ReadExisting()
8

9
        pos = SerialInput.IndexOf(vbCr)
10
        If (pos >= 0) Then
11
            eineZeile = SerialInput.Substring(0, pos)
12
            'verarbeite meineDaten
13
            SerialInput = SerialInput.Substring(pos, SerialInput.Length - pos)
14
            Me.Invoke(New EventHandler(AddressOf DoUpdate))
15
        End If
16

17

18
    End Sub
19

20
    Public Sub DoUpdate()
21
        ListBox1.Items.Insert(0, "Recv: " & eineZeile)
22
        TextBox1.Text = TextBox1.Text + 1
23

24
    End Sub
Angehängte Dateien:
Gast #3100463
Lesenswert?

vllt. muss bei:
SerialInput = SerialInput + SerialPort1.ReadExisting()
...wie unten auch ein "&" statt "+" hin?
Kann es sein, dass "+" in vb.net womöglich irgendwelche Besonderheiten 
macht und "&" da für normale Konkatenation gedacht ist?
Gast #3110794
Lesenswert?

ich kenn die probs zu genüge...

ich kann nur sagen verwende nicht die ocx... hatte damit nur ärger
und du musst immer schön warten zwischen abfrage absenden und antwort 
abholen
(waitms-function)

hier ein modul im anhang damit konnte ich arbeiten atmega32...
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren