UART - Datenverlust

OP #1533268
Lesenswert?

Hallo,

ich habe ein etwas seltsames Problem, dem ich nicht auf die Sprünge 
komme.
Am µC ist ein GPS Modul angeschlossen (UART1). An UART2 ist das USB 
Modul STI100 angeschlossen. Dort sollen die empfangenen Daten 
gespeichert werden.

Es klappt auch weitgehend, jedoch tritt zwischendurch ein Fehler auf. 
Und zwar wird der String, anscheinend nicht komplett zum STI100 
übertragen.

Hier sieht man das Problem (Auszug der log-Datei auf dem Stick):
1
$GPRMC,154818.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*7B^^$GPGGA,154818.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*41#^
2
$GPRMC,154819.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*7A^^$GPGGA,154819.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*40#^
3
$GPRMC,154820.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*70^^$GPGGA,154820.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*4A#^
4
$GPRMC,154821.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*71^^$GPGGA,154821.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*4B#^
5
$GPRMC,154822.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*72^^$GPGGA,154822.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*48#^
6
$GPRMC,154823.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*73^^$GPGGA,154823.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*49#^
7
$GPRMC,154824.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*74^^$GPGGA,154824.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*4E#^
8
$GPRMC,154825.000,V,5123.8024,N,00727.0921,E,0.00,0.00,27
9

10
OPW myFile.txt
11
WRF 140
12
$GPRMC,154826.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209$GPRMC,154827.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*77^^$GPGGA,154827.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*4D#^
13
$GPRMC,154828.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*78^^$GPGGA,154828.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*42#^
14
$GPRMC,154829.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*79^^$GPGGA,154829.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*43#^
15
$GPRMC,154830.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*71^^$GPGGA,154830.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*4B#^
16
$GPRMC,154831.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*70^^$GPGGA,154831.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*4A#^
17
$GPRMC,154832.000,V,5123.8024,N,00727.0921,E,0.00,0.00,271209,,,N*73^^$GPGGA,154832.000,5123.8024,N,00727.0921,E,0,0,,102.5,M,47.5,M,,*49#^

Der entscheidende Teil ist in der mitte. Das sind eigentlich die 
Steuerbefehle für den STI100, die auf dem USB Stick landen. Dies hängt 
damit zusammen, dass der String vorher plötzlich aufhört (es fehlen 
einige Zeichen im $GPRMC Teil und der gesamte $GPGGA Teil). Da aber vor 
dem Speichern des Strings die Länge angegeben wird, erwartet das STI 
noch weitere Daten, die geispeichert werden sollen.

Das Fehlerbild deutet eigentlich drauf hin, dass der String nach dem 
Berechnen der Länge irgendwie gekürzt wird.

Hier ist das Quellprogramm:
1
$regfile = "m644pdef.dat"
2
$crystal = 16000000
3
$baud = 9600
4
$baud1 = 9600
5

6

7
Open "COM2:" For Binary As #2
8
Config Serialin = Buffered , Size = 100 , Bytematch = 13
9

10
Declare Sub Serial0charmatch()
11
Declare Sub Clearvars()
12
Declare Sub Initsti()
13
Declare Function Striptags(mydata As String) As String
14
Declare Function Buildgpsstring(mc As String , Ga As String) As String
15
Declare Sub Writeusb(mydata As String)
16

17

18
Dim Incoming_data As String * 100
19
Dim Gps_string As String * 300
20
Dim Mc As String * 100
21
Dim Ga As String * 100
22
Dim Filter As String * 400
23
Dim Writestring As String * 300
24
Dim Subfilter As String * 40
25
Dim Length As Integer
26

27

28
Call Initsti()
29

30
Enable Interrupts
31

32

33
Do
34
   If Mc <> "" And Ga <> "" Then
35
      Disable Interrupts
36

37
      ' escape chars
38
      Mc = Striptags(mc)
39
      Ga = Striptags(ga)
40

41
      ' build gps string
42
      Gps_string = Buildgpsstring(mc , Ga) + Chr(&H0a)
43

44
      ' write data to usb
45
      If Len(gps_string) > 20 Then
46
         Call Writeusb(gps_string)
47
      End If
48

49
      ' tidy up
50
      Call Clearvars()
51
      Enable Interrupts
52
   End If
53

54
   !nop
55

56
Loop
57

58
End
59

60
' ---------------------------------------------------
61

62

63

64

65

66
'Daten vom Buffer auslesen
67
Sub Serial0charmatch()
68

69
   Input Incoming_data Noecho
70

71
   If Len(incoming_data) > 50 Then
72
      Filter = Incoming_data
73
      Subfilter = Mid(incoming_data , 2 , 6)
74

75
      If Subfilter = "$GPRMC" And Mc = "" Then
76
         Mc = Filter
77
      End If
78

79
      If Subfilter = "$GPGGA" And Ga = "" Then
80
         Ga = Filter
81
      End If
82

83
   End If
84

85
   Return
86
End Sub
87

88

89
'STI Initialization
90
Sub Initsti()
91
   Wait 10
92
   Print #2 , Chr(&H0d);
93
   Print #2 , Chr(&H0d);
94

95
   Print #2 , "IPA";
96
   Print #2 , Chr(&H0d);
97

98
   Wait 10
99
End Sub
100

101

102
' variablen leeren
103
Sub Clearvars()
104
   Mc = ""
105
   Ga = ""
106
   Incoming_data = ""
107
   Filter = ""
108
   Subfilter = ""
109
End Sub
110

111
' entfernt \n und \r
112
Sub Striptags(mydata As String) As String
113
    Length = Len(mydata) - 1
114
    Striptags = Mid(mydata , 2 , Length)
115
End Sub
116

117

118
' create the cps writestring
119
Sub Buildgpsstring(mc As String , Ga As String) As String
120
    Buildgpsstring = Mc + "^^"
121
    Buildgpsstring = Buildgpsstring + Ga
122
    Buildgpsstring = Gps_string + "#^"
123
End Sub
124

125

126
' write given data to the usb device
127
Sub Writeusb(mydata As String)
128

129
   Length = Len(mydata)
130

131
   Writestring = "WRF " + Str(length)
132

133
   Print #2 , Chr(&H0d);
134

135
   Print #2 , "OPW myFile.txt";
136
   Print #2 , Chr(&H0d);
137

138
   Print #2 , Writestring;
139
   Print #2 , Chr(&H0d);
140

141
   Print #2 , Mydata;
142

143
   Print #2 , "CLF myFile.txt";
144
   Print #2 , Chr(&H0d);
145
End Sub

Hat vielleicht jemand eine Idee? Wird da durch einen Interrupt was 
überschrieben? Oder liegt es an dem 16Mhz Quarz, bei dem es keine 100% 
Fehlerfreiheit bei der UART Übertragung gibt? Allerdings wird bei 9600 
baud die Fehlerrate mit ca 0.2 % angegeben - und dafür tritt dieser 
Fehler einfach zu oft auf.

Hilfe!
Gast #1533299
Lesenswert?

Checke also diese Stelle:

' create the cps writestring
Sub Buildgpsstring(mc As String , Ga As String) As String
    Buildgpsstring = Mc + "^^"
    Buildgpsstring = Buildgpsstring + Ga
    Buildgpsstring = Gps_string + "#^" ' <===============
End Sub
OP #1533302
Lesenswert?

Stefan:
Aaargh stimmt! Danke!

Holger:
Es wird mit max 5 Hz geschrieben. Jeweils etwa 150 Zeichen. Reicht die 
Baudrate nicht aus?

Ich leere erstmal den gps_string und teste es nochmal!

Edit:
Jap die Stelle ist mir gerade aufgefallen, das ist nicht richtig. Statt 
gps_string sollte da buildstring stehen.

Ich teste nochmal!
Gast #1533310
Lesenswert?

In Verbindung mit dem:

      ' build gps string
      Gps_string = Buildgpsstring(mc , Ga) + Chr(&H0a)

baust du nämlich ein Datenmonster auf.

Bsp.

Start Gps_string = "foo"
Gps_string = Buildgpsstring(mc , Ga) + Chr(&H0a)
=> 1. Runde
Gps_string = "mc"+"^^"+ "ga" + "foo" + "#^"
=> 2. Runde
Gps_string = "mc"+"^^"+ "ga" + "mc^^gafoo#^" + "#^"
=> 3. Runde
Gps_string = "mc"+"^^"+ "ga" + "mc^^gamc^^gafoo#^#^" + "#^"
usw.
Gast #1533320
Lesenswert?

Also du willst der Frage nachzugehen, warum der Fehler keinen weiteren 
Fehler (wobei zu definieren wäre, wie der zur Laufzeit aussieht) auslöst 
;-) Ich würde den ersten Fehler beheben und gut ist's.
OP #1533329
Lesenswert?

Hmm,

es war auf jeden Fall ein Fehler, aber daran scheint es nicht gelegen zu 
haben:
1
$GPRMC,180302.000,V,5147.5472,N,00723.9163,E,0.00,0.00,271209,,,N*79^^$GPGGA,180303.000,5147.5472,N,00723.9163,E,0,0,,102.7,M,47.3,M,,*46#^
2
$GPRMC,180303.000,V,5147.5472,N,00723.9163,E,0.00,0.00,27
3

4
OPW myFile.txt
5
WRF 140
6
$GPRMC,180304.000,V,5147.5472,N,00723.9163,E,0.00,0.00,271209$GPRMC,180305.000,V,5147.5472,N,00723.9163,E,0.00,0.00,271209,,,N*7E^^$GPGGA,180306.000,5147.5472,N,00723.9163,E,0,0,,102.7,M,47.3,M,,*43#^
7
$GPRMC,180306.000,V,5147.5472,N,00723.9163,E,0.00,0.00,271209,,,N*7D^^$GPGGA,180307.000,5147.5472,N,00723.9163,E,0,0,,102.7,M,47.3,M,,*42#^
8
$GPRMC,180307.000,V,5147.5472,N,00723.9163,E,0.00,0.00,271209,,,N*7C^^$GPGGA,180308.000,5147.5472,N,00723.9163,E,0,0,,102.7,M,47.3,M,,*4D#^

Wenn es einmal auftritt, dann kommt es regelmäßig nach etwa 33 
Einträgen. Also schaut eigentlich nach einer Art Überlauf o.ä. aus ?!

Noch eine Idee:

' create the cps writestring
Sub Buildgpsstring(mc As String , Ga As String) As String
    Buildstring = "" ' <===============
    Buildgpsstring = Mc + "^^"
    Buildgpsstring = Buildgpsstring + Ga
    Buildgpsstring = Gps_string + "#^"
End Sub

Wobei eigentlich wird buildstring ja zurückgesetzt.
Gast #1533369
Lesenswert?

Buildstring ist eine andere Variable als Buildgpsstring ist eine 
andere Variable als Gps_string

Überlauf kann hinkommen. Du hast gut 1,3 KB globale Variablen und 
übergibst fette Strings auf dem Stack.

Globale Variablennamen und lokale Variablen mit gleichem Namen sind auch 
unschön. Soweit ich sehe könntest du auf etliche lokale Variablen 
verzichten.

BTW. Wenn du schreibst "Aber ein String kann max 255 bytes lang sein.", 
wie vereinbart sich das mit diesen Zeilen:

Dim Gps_string As String * 300
Dim Filter As String * 400
Dim Writestring As String * 300
OP #1533383
Lesenswert?

Auch wieder richtig, habe die mal alle auf 254 gekürzt.
Ich habe jetzt diverse Vars lokal deklariert.
Um auszuschließen, dass es tatsächlich an der 
Übertragungsgeschwindigkeit liegt, müsste ich zur Laufzeit die 
Geschwindigkeit von UART1 ändern. Ist das in Bascom möglich? Das STI ist 
nach einem Reset wieder bei 9600 baud.

Gibt es noch ggf weitere Fehlerquellen?
Ich habe mir übrigens die TX Leitung vom µC angeguckt - dort werden die 
Daten anscheinend komplett gesendet, das würde auch dafür sprechen, dass 
das STI mit dem Schreiben nicht nachkommt. Evtl habe ich aber auch was 
übersehen, da wird ja ziemlich viel geschrieben.

Der Code sieht nun so aus:
1
$regfile = "m644pdef.dat"
2
$crystal = 16000000
3
$baud = 9600
4
$baud1 = 9600
5

6

7
Open "COM2:" For Binary As #2
8
Config Serialin = Buffered , Size = 254 , Bytematch = 13
9
Config Serialout = Buffered , Size = 254
10
Config Serialout1 = Buffered , Size = 254
11

12
Declare Sub Serial0charmatch()
13
Declare Sub Clearvars()
14
Declare Sub Initsti()
15
Declare Function Striptags(mydata As String) As String
16
Declare Function Buildgpsstring(mc As String , Ga As String) As String
17
Declare Sub Writeusb(mydata As String)
18

19

20
Dim Incoming_data As String * 100
21
Dim Gps_string As String * 254
22
Dim Mc As String * 100
23
Dim Ga As String * 100
24
Dim Filter As String * 254
25
Dim Subfilter As String * 40
26

27

28
Call Initsti()
29

30
Enable Interrupts
31

32

33
Do
34
   If Mc <> "" And Ga <> "" Then
35
      Disable Interrupts
36

37
      ' escape chars
38
      Mc = Striptags(mc)
39
      Ga = Striptags(ga)
40

41
      ' build gps string
42
      Gps_string = Buildgpsstring(mc , Ga) + Chr(&H0a)
43

44
      ' write data to usb
45
      If Len(gps_string) > 20 Then
46
         Call Writeusb(gps_string)
47
      End If
48

49
      ' tidy up
50
      Call Clearvars()
51
      Enable Interrupts
52
   End If
53

54
   !nop
55

56
Loop
57

58
End
59

60
' ---------------------------------------------------
61

62

63

64

65

66
'Daten vom Buffer auslesen
67
Sub Serial0charmatch()
68

69
   Input Incoming_data Noecho
70

71
   If Len(incoming_data) > 50 Then
72
      Filter = Incoming_data
73
      Subfilter = Mid(incoming_data , 2 , 6)
74

75
      If Subfilter = "$GPRMC" And Mc = "" Then
76
         Mc = Filter
77
      End If
78

79
      If Subfilter = "$GPGGA" And Ga = "" Then
80
         Ga = Filter
81
      End If
82

83
   End If
84

85
   Return
86
End Sub
87

88

89
'STI Initialization
90
Sub Initsti()
91
   Wait 10
92
   Print #2 , Chr(&H0d);
93
   Print #2 , Chr(&H0d);
94

95
   Print #2 , "IPA";
96
   Print #2 , Chr(&H0d);
97

98
   Wait 10
99
End Sub
100

101

102
' variablen leeren
103
Sub Clearvars()
104
   Mc = ""
105
   Ga = ""
106
   Incoming_data = ""
107
   Filter = ""
108
   Subfilter = ""
109
   Gps_string = ""
110
End Sub
111

112
' entfernt \n und \r
113
Sub Striptags(mydata As String) As String
114
    Local Length As Integer
115
    Length = Len(mydata) - 1
116
    Striptags = Mid(mydata , 2 , Length)
117
End Sub
118

119

120
' create the cps writestring
121
Sub Buildgpsstring(mc As String , Ga As String) As String
122
    Buildgpsstring = ""
123
    Buildgpsstring = Mc + "^^"
124
    Buildgpsstring = Buildgpsstring + Ga
125
    Buildgpsstring = Buildgpsstring + "#^"
126
End Sub
127

128

129
' write given data to the usb device
130
Sub Writeusb(mydata As String)
131
   Local Length As Integer
132
   Local Writestring As String * 15
133

134
   Length = Len(mydata)
135

136
   Writestring = "WRF " + Str(length)
137

138
   Print #2 , Chr(&H0d);
139

140
   Print #2 , "OPW 666.txt";
141
   Print #2 , Chr(&H0d);
142

143
   Print #2 , Writestring;
144
   Print #2 , Chr(&H0d);
145

146
   Print #2 , Mydata;
147

148
   Print #2 , "CLF 666.txt";
149
   Print #2 , Chr(&H0d);
150
End Sub

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