www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART - Datenverlust


Autor: Filth __ (filth)
Datum:

Bewertung
0 lesenswert
nicht 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):
$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#^
$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#^
$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#^
$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#^
$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#^
$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#^
$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#^
$GPRMC,154825.000,V,5123.8024,N,00727.0921,E,0.00,0.00,27

OPW myFile.txt
WRF 140
$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#^
$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#^
$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#^
$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#^
$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#^
$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:
$regfile = "m644pdef.dat"
$crystal = 16000000
$baud = 9600
$baud1 = 9600


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

Declare Sub Serial0charmatch()
Declare Sub Clearvars()
Declare Sub Initsti()
Declare Function Striptags(mydata As String) As String
Declare Function Buildgpsstring(mc As String , Ga As String) As String
Declare Sub Writeusb(mydata As String)


Dim Incoming_data As String * 100
Dim Gps_string As String * 300
Dim Mc As String * 100
Dim Ga As String * 100
Dim Filter As String * 400
Dim Writestring As String * 300
Dim Subfilter As String * 40
Dim Length As Integer


Call Initsti()

Enable Interrupts


Do
   If Mc <> "" And Ga <> "" Then
      Disable Interrupts

      ' escape chars
      Mc = Striptags(mc)
      Ga = Striptags(ga)

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

      ' write data to usb
      If Len(gps_string) > 20 Then
         Call Writeusb(gps_string)
      End If

      ' tidy up
      Call Clearvars()
      Enable Interrupts
   End If

   !nop

Loop

End

' ---------------------------------------------------





'Daten vom Buffer auslesen
Sub Serial0charmatch()

   Input Incoming_data Noecho

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

      If Subfilter = "$GPRMC" And Mc = "" Then
         Mc = Filter
      End If

      If Subfilter = "$GPGGA" And Ga = "" Then
         Ga = Filter
      End If

   End If

   Return
End Sub


'STI Initialization
Sub Initsti()
   Wait 10
   Print #2 , Chr(&H0d);
   Print #2 , Chr(&H0d);

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

   Wait 10
End Sub


' variablen leeren
Sub Clearvars()
   Mc = ""
   Ga = ""
   Incoming_data = ""
   Filter = ""
   Subfilter = ""
End Sub

' entfernt \n und \r
Sub Striptags(mydata As String) As String
    Length = Len(mydata) - 1
    Striptags = Mid(mydata , 2 , Length)
End Sub


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


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

   Length = Len(mydata)

   Writestring = "WRF " + Str(length)

   Print #2 , Chr(&H0d);

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

   Print #2 , Writestring;
   Print #2 , Chr(&H0d);

   Print #2 , Mydata;

   Print #2 , "CLF myFile.txt";
   Print #2 , Chr(&H0d);
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!

Autor: holger (Gast)
Datum:

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

Autor: Stefan B. (Gast)
Datum:

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

Autor: Stefan B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Filth __ (filth)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Stefan B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Filth __ (filth)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Stefan B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Filth __ (filth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Behoben ist es, Testlauf ist gerade dran :)

Autor: Filth __ (filth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm,

es war auf jeden Fall ein Fehler, aber daran scheint es nicht gelegen zu 
haben:
$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#^
$GPRMC,180303.000,V,5147.5472,N,00723.9163,E,0.00,0.00,27

OPW myFile.txt
WRF 140
$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#^
$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#^
$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.

Autor: Stefan B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Filth __ (filth)
Datum:

Bewertung
0 lesenswert
nicht 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:
$regfile = "m644pdef.dat"
$crystal = 16000000
$baud = 9600
$baud1 = 9600


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

Declare Sub Serial0charmatch()
Declare Sub Clearvars()
Declare Sub Initsti()
Declare Function Striptags(mydata As String) As String
Declare Function Buildgpsstring(mc As String , Ga As String) As String
Declare Sub Writeusb(mydata As String)


Dim Incoming_data As String * 100
Dim Gps_string As String * 254
Dim Mc As String * 100
Dim Ga As String * 100
Dim Filter As String * 254
Dim Subfilter As String * 40


Call Initsti()

Enable Interrupts


Do
   If Mc <> "" And Ga <> "" Then
      Disable Interrupts

      ' escape chars
      Mc = Striptags(mc)
      Ga = Striptags(ga)

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

      ' write data to usb
      If Len(gps_string) > 20 Then
         Call Writeusb(gps_string)
      End If

      ' tidy up
      Call Clearvars()
      Enable Interrupts
   End If

   !nop

Loop

End

' ---------------------------------------------------





'Daten vom Buffer auslesen
Sub Serial0charmatch()

   Input Incoming_data Noecho

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

      If Subfilter = "$GPRMC" And Mc = "" Then
         Mc = Filter
      End If

      If Subfilter = "$GPGGA" And Ga = "" Then
         Ga = Filter
      End If

   End If

   Return
End Sub


'STI Initialization
Sub Initsti()
   Wait 10
   Print #2 , Chr(&H0d);
   Print #2 , Chr(&H0d);

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

   Wait 10
End Sub


' variablen leeren
Sub Clearvars()
   Mc = ""
   Ga = ""
   Incoming_data = ""
   Filter = ""
   Subfilter = ""
   Gps_string = ""
End Sub

' entfernt \n und \r
Sub Striptags(mydata As String) As String
    Local Length As Integer
    Length = Len(mydata) - 1
    Striptags = Mid(mydata , 2 , Length)
End Sub


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


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

   Length = Len(mydata)

   Writestring = "WRF " + Str(length)

   Print #2 , Chr(&H0d);

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

   Print #2 , Writestring;
   Print #2 , Chr(&H0d);

   Print #2 , Mydata;

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


Autor: Filth __ (filth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs jetzt mit baud = 115200 getestet. Das gleiche Ergebnis.
Es ist immer die gleiche Stelle, an der der String abgeschnitten wird:
$GPRMC,193603.000,V,5121.3525,N,00650.3698,E,0.00,0.00,27

OPW myFile.txt
WRF 140

immer nach der "27".

Autor: Filth __ (filth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

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

Danke an MagicWhiteSmoke!

Alex

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.