Hallo, ich empfange Daten von einem GPS Modul, das Programm in Bascom sieht gekürzt so aus: ... Config Serialin1 = Buffered , Size = 20 , Bytematch = 13 ... do print incoming_data waut 2 loop ... sub Serial1charmatch: input incoming_data noecho Return end sub Sprich wenn ein \r erkannt wird, werden die ankommenden Daten in eine Variable geschrieben und im Hauptprogramm ausgegeben. Die gesendeten Strings vom Sensor sehen ja pro Durchlauf in etwa so aus: $GPRMC,191410,A,4735.5634,N,00739.3538,E,0.0,0.0,181102,0.4,E,A*19 $GPRMB,A,9.99,L,,Exit,4726.8323,N,00820.4822,E,29.212,107.2,,V,A*69 $GPGGA,191410,4735.5634,N,00739.3538,E,1,04,4.4,351.5,M,48.0,M,,*45 $GPGSA,A,3,,,,15,17,18,23,,,,,,4.7,4.4,1.5*3F $GPGSV,2,1,08,02,59,282,00,03,42,287,00,06,16,094,00,15,80,090,48*79 $GPGLL,4735.5634,N,00739.3538,E,191410,A,A*4A $GPBOD,221.9,T,221.5,M,Exit,*6B Mein Problem ist nun, dass ich immer nur die erste Zeile, also den $GPRMC Teil bekomme, da jede Zeile per \r abgeschlossen wird. Ich benötige aber den $GPGGA Teil. Könnte mir jemand einen Tipp geben, wie ich den Code abändern muss? Danke!
Config Serialin1 = Buffered , Size = 20 , Bytematch = 13 und du denkst wirklich, dass deine kompletten Zeilen in 20 Zeichen Platz haben?
Das ist nur ein Beispiel, ich habe es aus dem Kopf getippt. Tatsächlich steht da meintwegen 200. Trotzdem ist nur die komplette erste Zeile verfügbar - die würde in die 20 Zeichen auch nicht passen. Das sind nämlich ca 69 Zeichen.
Alex schrieb: > Das ist nur ein Beispiel, ich habe es aus dem Kopf getippt. Dann bin ich raus Ich habe es nämlich satt, Fehler in Code zu suchen, der nicht dem entspricht, der tatsächlich auf dem AVR läuft und der dann auch nur aus ein paar nichtssagend hingerotzten Zeilen besteht. Du sitzt vor dem Programm, hast es laufen und findest den Fehler nicht. Und wir sollen hier aus ein paar Bruchstücken erraten, was da wieder mal schief läuft.
Der Vorlage angemessen auch mal so nichtssagend hingerotzt: Alle Zeilen wegschmeissen, bis die richtige da ist. Das ist aber nun wirklich Programmieren erstes Kapitel und zeigt anschaulich was passiert, wenn ein Anfaenger einfach drauflosprogrammiert, ohne sich vorher Gedanken zu machen. Gast
Hallo, Du detektierts halt "$GPGGA" und verarbeitest dann erst weiter... Die überlegng hat mit "programmieren" erst einmal noch nichts zu tun, sondern nur mit etwas Nachdenken. Entweder Du postest hier den gesamten Code und alle Unmstände oder Du läßt es besser sein. Man will Dir ggf. helfen, aber nicht verarscht werden, alles klar ?! DS
Hier das Programm $regfile = "m644pdef.dat" $crystal = 16000000 $baud = 9600 $baud1 = 9600 Declare Sub Serial0charmatch() Config Serialin = Buffered , Size = 200 , Bytematch = 13 Dim Incoming_data As String * 200 Dim Filtered As String * 200 Dim Writestring As String * 20 Dim Length As Integer Dim Var As Integer 'Hauptschleife Waitms 500 Dim A As Word , B As Word Dim Einzelzeichen As String * 1 Enable Interrupts Do If Var = 1 Then Disable Interrupts Length = Len(incoming_data) - 1 Filtered = Mid(incoming_data , 2 , Length) print Filtered Enable Interrupts Var = 0 End If Wait 2 Loop End 'Daten vom Buffer auslesen Sub Serial0charmatch() Incoming_data = "" Input Incoming_data Noecho Var = 1 Return End Sub
schau Dir mal hier das 2. Beispiel mit den Overlays an und lies Dir mal durch was der sachkundige Autor schreibt. Das ist sehr strukturiert und wäre eine gute und bessere Ausgangsbasis für einen funktionierenden Code.. http://www.rowalt.de/mc/index.htm ...... Wer das Vorgehen String=String+Zeichen nicht mag, kann mit einem kleinen Trick optimal vorgehen: In Bascom ist es möglich, ein und denselben SRAM-Platz mit mehreren Variablen zu belegen. Wir können z.B. anweisen, daß unsere String-Variable auf Adresse &H60 gesetzt werden soll. Gleichzeitig können wir ein Feld mit 11 Bytes dimensionieren, das auf der gleichen Adresse liegen soll (ein 10 Byte langer String benötigt 11 Bytes Platz). Damit können wir ganz einfach und effizient über völlig verschiedene Methoden auf denselben Speicher zugreifen. Schauen Sie sich bitte das folgende Listing an. '0011.BAS: Optimierter String-Empfang $Regfile = "2313def.dat" $Crystal = 3686400 $Baud = 9600 Dim s As String*10 At &H60 Dim b(11) As Byte At &H60 Overlay Dim n As Byte On URXC OnRxD Enable URXC Enable Interrupts Main: If n > 9 Then Print s n = 0 End If Goto Main OnRxD: Incr n b(n) = UDR Return Der String wird auf Adresse &H60 im AVR abgelegt. Dies ist die Adresse des ersten Bytes im SRAM (da der AT90S2313 über 128 Bytes SRAM vefügt, ist die höchste SRAM-Adresse &HDF). Quasi "darüber", also auf die selbe Adresse, legen wir ein Feld, das genauso lang wie der String ist. Das ist alles. Der Trick ist nur, daß wir beim Füllen des Strings in unserem Anwendungsfall am effizientesten mit einem Feld arbeiten können, während in anderen Fällen die Arbeit mit einem String günstiger sein kann. Welche Wege man in der Praxis gehen will, hängt natürlich immer von der Anwendung ab. Die Anwendung des Overlay-Tricks kostet weder zusätzlichen Code, noch SRAM. Es ist vielleicht eher wie die Auswahl zwischen Buddelschippe, Schaufel und Bagger bei ein und dem selben Haufen Sand. Und noch ein drittes UART-Mißverständnis trat wiederholt auf: Der UART-Empfangs-Interrupt meldet, daß ein Zeichen empfangen wurde. In der Interrupt-Routine kann man deshalb auch immer nur ein Zeichen auslesen. Zum Beispiel macht es daher keinen Sinn, in der Interrupt-Routine den Bascom-Befehl Input einzusetzen, um doch mehrere Zeichen empfangen zu können.
Was ich aber nicht verstehe ist folgendes: Declare sub serial0charmatch() config serialin = buffered, size = 100, bytymatch = 13 dim incoming_data as string *100 do print incoming_data wait 2 loop end sub serial0charmatch() input incoming_data noecho 'print incoming_data end sub das print in der hauptschleife gibt immer nur eine empfangene zeile aus. Kommentiere ich das print in der serial0charmatch ein, dann gibt es alle empfangenen zeilen aus - eben das, was ich benötige. Warum ist es so?
Alex schrieb: > das print in der hauptschleife gibt immer nur eine empfangene zeile aus. > Kommentiere ich das print in der serial0charmatch ein, dann gibt es alle > empfangenen zeilen aus - eben das, was ich benötige. > > Warum ist es so? Wahrscheinlich deshalb, weil dieses print in der ISR mit dem Empfang synchronisiert ist. Es gibt nur dann aus, wenn auch tatsächlich ein String epfangen wurde. Wohingegen deine Hauptschleife auf biegen und brechen ausgibt. Auch interessant: Die Ausgabe dauert ja auch seine Zeit. Was passiert eigentlich, wenn während der Ausgabe die serial0charmatch aufgerufen wird, und dem PRINT die Daten unter dem Allerwertesten umdreht.
Nein daran scheint es nicht zu liegen: Declare sub serial0charmatch() config serialin = buffered, size = 100, bytymatch = 13 dim incoming_data as string *100 dim flag as byte flag = 0 do if flag = 1 then print incoming_data flag = 0 endif wait 2 loop end sub serial0charmatch() flag = 1 input incoming_data noecho 'print incoming_data end sub liefert das gleiche ergebnis - immer nur eine empfangene zeile
Wartest du auch lange genug? 2 Sekunden können sich ziehen, wenn man darauf wartet. (wozu warten, wenn du jetzt sowieso eine Flagsteuerung hast?)
Bist du sicher, dass dein GPS Empfänger mit 9600 Baud sendet? Meistens haben die nämlich nur 4800 Baud. Die Schlussfolgerung wäre dann $crystal = 16000000 Dein µC läuft in Wirklichkeit mit 8Mhz, so dass sich wieder korrekte 4800 ergben. Aber: wait 2 das werden dann 4 Sekunden Wartezeit
Bzgl der 9600 bin ich mir sicher - sonst wären ja die empfangenen Daten nur noch Müll. Der Sensor ist mit 9600 im Datenblatt angegeben. Mfg Alex
Oder dein Mikrocontroller läuft in Wirklichkeit mit 8MHz. Du musst auch mal lesen, was man schreibt.
Ja, nee is klar ! Und denen welche geholfen haben ist das jetzt das Feedback ???
90% dumme Sprüche im Thread, da hat man wenig Bock auf Feedback. Hau rein
Karl Heinz: Ich weiß es nicht genau ehrlich gesagt. Ich habe es so gelöst, dass ich in der Interrupt-Routine den Empfangsstring zerlegt habe und in zwei weiteren globalen Variablen die MMC und GGA Strings gespeichert habe. 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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.