Forum: Mikrocontroller und Digitale Elektronik UART - Datenverlust


von Filth _. (filth)


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!

von holger (Gast)


Lesenswert?

Mach doch mal die Baudrate zum STI100 erheblich größer.
Vermutlich kommen die Daten schneller rein als du sie speichern kannst.

von Stefan B. (Gast)


Lesenswert?

Gps_string wird nie "leergemacht". Irgendwann ist der größte Speicher 
auch mal voll.

von Stefan B. (Gast)


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

von Filth _. (filth)


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!

von Stefan B. (Gast)


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.

von Filth _. (filth)


Lesenswert?

Stimmt.
Aber ein String kann max 255 bytes lang sein. In dem Fall sollte es 
eigentlich schon nach 2 Durchläufen einen Überlauf geben, oder?

von Stefan B. (Gast)


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.

von Filth _. (filth)


Lesenswert?

Behoben ist es, Testlauf ist gerade dran :)

von Filth _. (filth)


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.

von Stefan B. (Gast)


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

von Filth _. (filth)


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

von Filth _. (filth)


Lesenswert?

Habs jetzt mit baud = 115200 getestet. Das gleiche Ergebnis.
Es ist immer die gleiche Stelle, an der der String abgeschnitten wird:
1
$GPRMC,193603.000,V,5121.3525,N,00650.3698,E,0.00,0.00,27
2
3
OPW myFile.txt
4
WRF 140

immer nach der "27".

von Filth _. (filth)


Lesenswert?

Hallo,

die Lösung wurde dort gefunden:
http://bascom-forum.de/index.php/topic,3100.0.html

Danke an MagicWhiteSmoke!

Alex

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.