PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : GPS an Mega32 -> will nicht



Ronny81
23.03.2010, 22:26
Hallo zusammen,

ich bin jetzt seid zwei tagen dran, mein GPS-Modul mit einem Mega32 auszulesen.
Ich dachte mir "kann nicht so schwer sein" es will aber nicht richtig laufen.

-Ist ein NL-552 von Navilock
-TTL mit 4800 baud
-Gibt NEMA aus

Zum testen will ich die "Daten" über die RS232 an meinen Pc ausgeben.
Ich hab jetzt nur mal "Print #1 , "hallo" in Do Loop geschrieben, aber nicht mal das kommt richtig an, 10-15 mal ist alles okay, dann folgen wieder ein paar Fehler.
Wenn ich "Disable Interrupts" einstelle läuft es. Ich habe also den Eindruck, wie als wenn mir der Hardware UART die ""Print #1 , "hallo" Ausgabe zerhacken würde.
Ich hoffe es hat einer von euch eine Idee. Danke schon mal.

Gruß Ronny



$regfile = M32def.dat
$crystal = 12000000
$baud = 4800

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

Dim C As Byte
Dim I As Byte
Dim Sspeed As String * 11
Dim Stime As String * 11
Dim Sdate As String * 11
Dim Soutput As String * 11

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

Declare Sub Wait_for_char(byval C As String)
Declare Sub Wait_for_string(byval S As String)
Declare Function Read_string() As String

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

Open "COMB.0:115200,8,N,1" For Output As #1
Wait 1
Print #1 , "lese ein"
Wait 1

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

Config Serialin = Buffered , Size = 200
Enable Interrupts

'$GPRMC,235945.180,V,0000.0000,N,00000.0000,E,0.00 ,0.00,120136,,,N*74
'$GPVTG,0.00,T,,M,0.00,N,0.0,K,N*02
'$GPGGA,235945.180,0000.0000,N,00000.0000,E,0,00,9 9.9,-17.0,M,17.0,M,,0000*7C
'$GPGSA,A,1,,,,,,,,,,,,,99.9,99.9,99.9*09
'$GPGSV,1,1,00*79
'$GPGLL,0000.0000,N,00000.0000,E,235945.180,V,N*44

Do

Print #1 , "hallo"
Waitms 100

Loop

Close #1
End

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

Sub Wait_for_char(byval C As String)
Local Cc As Byte
Do
Cc = Waitkey()
Loop Until Cc = Chr(c)
End Sub

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

Sub Wait_for_string(byval S As String) As String
Local Ii As Byte
Local Cc As Byte
Ii = 1
M1:
Cc = Waitkey()
If Cc <> Mid(s , Ii , 1) Then
Goto M1
Else
Incr Ii
If Ii > Len(s) Then Goto M2
Goto M1
End If
M2:
End Sub

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

Function Read_string() As String
Local Cc As Byte
Local Ss As String * 10
Ss = ""
Do
Cc = Waitkey()
Ss = Ss + Chr(cc)
Loop Until Cc = ","
Read_string = Left(ss , 5)
End Function
End

for_ro
23.03.2010, 23:35
Hallo Ronny,
mit dem Config Serialin=Buffered verwendet BASCOM automatisch den URXC Interrupt. Obwohl du keine der Subs anspringst, könnte dies trotzdem dein Print unterbrechen.
Warum machst du überhaupt das Einlesen mit Buffered? Bei 4800 baud könntest du die Zeichen in Ruhe empfangen und in den Pausen weiterverarbeiten und senden.
Probier doch mal sowas:


Dim Got_some As Byte
Dim Byte_received As Byte
On URXC urxc_isr 'kommentiere die Config Serialin Zeile aus
Enable URXC
Open "COMB.0:115200,8,N,1" For Output As #1

Do
If Got_some = 1 Then
Got_some = 0
Print #1, Chr(Byte_received)
End If
Loop

End

URXC_isr:
Byte_received = UDR
Got_some = 1
Return

Damit sollte jedes empfangene Zeichen direkt an den PC weitergeleitet werden.

Alternativ könntest du auch ganz auf den Interrupt verzichten, z.B. so:


Do
If IsCharWaiting() = 1 Then
Byte_received = UDR
Print #1, Chr(Byte_received)
End If
Loop

Ronny81
24.03.2010, 08:47
Guten Morgen,

Hi for_ro,
danke für deinen Tip mit dem "Serialin=Buffered". Ich habe es raus genommen und jetzt läuft es soweit ohne die Ausgabe zu zerhacken.

Aber ich komme nicht so richtig weiter.
Ich zerlege den ankommenden String mit:



Sub Wait_for_string(byval S As String)
Local Ii As Byte
Local Cc As Byte
Ii = 1
M1:
Cc = Waitkey()
If Cc <> Mid(s , Ii , 1) Then
Goto M1
Else
Incr Ii
If Ii > Len(s) Then Goto M2
Goto M1
End If
M2:
End Sue

und


Function Read_string() As String
Local Cc As Byte
Local Ss As String * 10
Ss = ""
Do
Cc = Waitkey()
Ss = Ss + Chr(cc)
Loop Until Cc = ","
Read_string = Left(ss , 6)
End Function
End



Sub Wait_for_char(byval C As String)
Local Cc As Byte
Do
Cc = Waitkey()
Loop Until Cc = Chr(c)
End Sub


Wait_for_string hat bei den Tests immer 1a funktioniert, jetzt will es die Zeichen aus meinem Sting aber nicht mehr erkennen.

Bei Call Wait_for_string( "$GPRMC,") sollte es erst weiter gehen, wenn $GPRMC,") im Sting gelesen wird. Die ist aber nicht so. Es läuft immer weiter, sobald irgent ein Sting am Port ankommt.

Was kann denn das noch sein?

Anbei noch mal mein ganzer Code -> "Print #1 , "1" ist zur Fehlersuche von mir.



$regfile = M32def.dat
$crystal = 12000000
$baud = 9600

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

Dim C As Byte
Dim I As Byte
Dim Sspeed As String * 2
Dim Stime As String * 2
Dim Sdate As String * 2
Dim Soutput As String * 2

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

Declare Sub Wait_for_char(byval C As String)
Declare Sub Wait_for_string(byval S As String)
Declare Function Read_string() As String

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

Open "COMB.0:115200,8,N,1" For Output As #1
Wait 1
Print #1 , "lese ein"
Wait 1

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

'Config Serialin = Buffered , Size = 200
'Enable Interrupts

'$GPRMC,235945.180,V,0000.0000,N,00000.0000,E,0.00 ,0.00,120136,,,N*74
'$GPVTG,0.00,T,,M,0.00,N,0.0,K,N*02
'$GPGGA,235945.180,0000.0000,N,00000.0000,E,0,00,9 9.9,-17.0,M,17.0,M,,0000*7C
'$GPGSA,A,1,,,,,,,,,,,,,99.9,99.9,99.9*09
'$GPGSV,1,1,00*79
'$GPGLL,0000.0000,N,00000.0000,E,235945.180,V,N*44

'$GPRMC,232058.00,A,4740.48501,N,01229.28266,E,1.6 35,,230310,,,A*73
'$GPVTG,,T,,M,1.635,N,3.029,K,A*2A
'$GPGGA,232058.00,4740.48501,N,01229.28266,E,1,05, 1.23,709.9,M,45.3,M,,*5D
'$GPGSA,A,3,29,14,31,02,26,,,,,,,,2.52,1.23,2.21*0 C
'$GPGSV,3,1,11,01,42,285,,02,38,086,17,04,16,041,, 09,15,148,*74
'$GPGSV,3,2,11,12,61,076,09,14,31,254,30,26,07,199 ,12,27,14,150,09*7F
'$GPGSV,3,3,11,29,50,217,11,30,78,322,08,31,26,311 ,29*4A
'$GPGLL,4740.48501,N,01229.28266,E,232058.00,A,A*6 8



Do


Call Wait_for_string( "$GPRMC,") 'wartet auf $GPRMC
Print #1 , "1"
Sspeed = Read_string()
Print #1 , "2"
For I = 1 To 3
Print #1 , "3"
Call Wait_for_char( ",")
Print #1 , "4"
Next
Print #1 , "5"
Sspeed = Read_string()
Print #1 , "6"
Waitms 100
Print #1 , "7"
Print #1 , Sspeed;
Print #1 , "8"



Loop

Close #1
End

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

Sub Wait_for_char(byval C As String)
Local Cc As Byte
Do
Cc = Waitkey()
Loop Until Cc = Chr(c)
End Sub

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

Sub Wait_for_string(byval S As String)
Local Ii As Byte
Local Cc As Byte
Ii = 1
M1:
Cc = Waitkey()
If Cc <> Mid(s , Ii , 1) Then
Goto M1
Else
Incr Ii
If Ii > Len(s) Then Goto M2
Goto M1
End If
M2:
End Sub

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

Function Read_string() As String
Local Cc As Byte
Local Ss As String * 10
Ss = ""
Do
Cc = Waitkey()
Ss = Ss + Chr(cc)
Loop Until Cc = ","
Read_string = Left(ss , 6)
End Function
End


Danke.

Gruß Ronny

for_ro
24.03.2010, 20:35
Hallo Ronny,
ehrlich gesagt kann ich mir nicht so recht vorstellen, dass deine Subs funktionieren. Mal abgesehen davon, dass dein Programm absolut nichts anderes machen kann, weil immer wieder die Waitkey() kommen.
Angenommen, ein Zeichen wird nicht richtig eingelesen, dann kommt das Programm hier nicht mehr raus:
M1:
Cc = Waitkey()
If Cc <> Mid(s , Ii , 1) Then
Goto M1
Bis dann irgendwann später doch mal zufällig das eingelesene Zeichen eines späteren GPS Satzes mit der aktuellen Position in S übereinstimmt.

Wie oben schon geschrieben, geht das mit dem URXC Interrupt viel sicherer und der µC ist nicht blockiert.
Dazu würde ich alle Zeichen einlesen bis ein CR auftauscht. Dann ist ein Satz komplett eingelesen.
Nun kannst du diesen in der Main Loop analysieren. Also etwa so:


Dim Gps_string As String * 100
Dim Gps_string_ovly(100) As Byte At Gps_string Overlay
Dim Gps_words(15) as String * 12
Dim Gps_pos As Byte
Dim GPS_complete As Byte
On URXC Urxc_isr 'kommentiere die Config Serialin Zeile aus
Enable URXC
Open "COMB.0:115200,8,N,1" For Output As #1
Enable Interrupts

Do
If Gps_complete = 1 Then
Gps_complete = 0
Word_count=Split(Gps_string, Gps_words(1), ",") 'Jetzt hast du alle Wörter in einem Array
'hier kommt die Auswertung hin
End If
Loop

End

Urxc_isr:
Gps_string_ovly(Gps_pos)=UDR
If Gps_string_ovly(Gps_pos) = 13 Then 'ASCII Wert von Carriage Return
Gps_string_ovly(Gps_pos) = 0 'String Ende setzen
GPS_complete = 1
End If
Return

Da sind jetzt vielleicht einige Sachen drin, die du nicht verstehst, aber das kommt schon noch.

Blue72
30.03.2010, 18:24
Hallo,

bislang habe ich auch die "Waitkey" Variante benutzt.
Genervt hat es eigentlich nur wenn man außer dem GPS noch andere Sachen machen will (so wie ich jetzt). Bei meinem jetzigen Projekt sollte das GPS zwar ein Bestandteil sein, aber nicht im Vordergrund stehen.

Mit Deinem obigen Code wäre das denk ich mal realisierbar.

Ich muss nur mal herausfinden wie ich jetzt die einzelnen GPS_strings zuordnen kann.

Für TIPs bin ich wie immer dankbar ;)

LG
Blue72

Blue72
30.05.2010, 17:49
Hallo for_ro,

ich habe Deinen Code so übernommen und wie folgt ergänzt:



Do
If Gps_complete = 1 Then
Gps_complete = 0
Word_count=Split(Gps_string, Gps_words(1), ",") 'Jetzt hast du alle Wörter in einem Array
'hier kommt die Auswertung hin

If Gps_words(1) = "$GPRMC" Then

Lcdat 1 , 1 , "Zeit: " ; Val(gps_words(3))
Lcdat 2 , 1 , "Lat: " ; Val(gps_words(4))
Lcdat 3 , 1 , "N/S: " ; Asc(gps_words(5))
Lcdat 4 , 1 , "Lon: " ; Val(gps_words(6))
Lcdat 5 , 1 , "E/W: " ; Asc(gps_words(7))
Lcdat 6 , 1 , "Speed: " ; Val(gps_words(8))
Lcdat 7 , 1 , "Course: " ; Val(gps_words(9))
Lcdat 8 , 1 , "Datum: " ; Val(gps_words(10))

End If

End If

Loop


Es bleibt hier leider nur "Go" stehen, sonst passiert nichts.
Die "Waitkey" Variante funktioniert bei mir zwar, ist für mein Projekt aber unbrauchbar.

Kannst Du mir noch einen Tip geben WIE ich diesen Code ans laufen bekomme ? Es wäre genau das was ich suche.

Danke Dir !

Gruß
Jens