Read NMEA from Server

schimanski

Well-Known Member
Licensed User
Longtime User
Hello!!!

Ich have a Problem with reading a kompletly NMEA-protocol like "§GPGGA,..." (see Help 'StrSplit') from a server.
The Server sends every two seconds a NMEA-protokoll. Ich can see this in a Control-Monitor and the server allows every client to take this data. But in the 'filestream.ReadString' there are only some parts of the protocol. Sometimes parts out of the middle or something from the end. Only the first read is correct and begins with "GPGGA,...." With the folowing code i always checked the length of the string. This is every time different between 5 or 10 and perhaps 60 to 80.
I have tested the timer with 500,1000 and 2000 ms, but no different.
If i don't know, where the string begins, I can not take the parameters with 'StrSplit' to use them.

Here the nessesary parts of my code:

I use the components Network.dll and BinaryFile.dll

Sub App_Start
..
Timer1.Enabled=true
Client.New1
Client.Connect("87.139.78.???",11112)
..
end sub

Sub Timer1_Tick
..
if Client.DataAvailable=true then
filestream.New1(Client.Getstream,false)
Protokoll=filestream.ReadString
Label1.Text=Protokoll
Label2.Text=StrLength(Protokoll)
end if
..
end sub

:sign0085:

I trie to find an answer for two weeks, but nothing.....

Thanks for help!!!
 

schimanski

Well-Known Member
Licensed User
Longtime User
GPSStream

Hello Erel, thanks for your fast answer.

But I have two problems with GPS.GPSStream: First i have give a kompletly NMEA-String to the GPSStream like


Sub Globals
NMEA="$GPGGA,161229.487,3723.2475,N,12158.3416,W,1,07,1.0,9.0,M,,,,0000*18"

end Sub

Sub Timer1_Tick
if NMEA<>"" then
gps.GPSStream(NMEA)
end if
End Sub

Sub GPS_GPSDecoded
Label1.text=gps.latitude
...
end Sub


but the GPS_GPSDecoded -Sub was not call. So I have call this Sub manuell, but there is no data from the NMEA-Protocol. I have tested it with GPGGA an GPRMC. What else i need to call the GPS_GPSDecoded, if the GPSBuffer have enough data?

The second Problem is, that my application takes the data from a GPS-mouse and the GPS-data from the server at the same time, because i calculate then distance and course of this two points. When I use the GPS.dll for both, the GPSBuffer takes the data from the GPS-mouse and from the server, so that I must have two different GPS-Objekts with two different GPS-Buffer.

To take the data from the server is my last problem of the application, then it run.

Frindly greetings

schimanski
 

schimanski

Well-Known Member
Licensed User
Longtime User
Problem with buffer from Server

Hello!

Thanks for the given answers. It was a great help for me. But now, i have again one problem:
When I read the NMEA-protocoll from the server by using the client-object and filestream.readstring over a GPRS-connection, i can take the data without problems. But if I dont' read the data form the server for perhaps one minute, the server will send me the NMEA-protocoll from one minute ago. If I wait three or four minutes and read then the filestream, i don't can take the actuell data, only the data from the time, i have stoped reading. The administrator from the server said, that the server doesn't buffer the data. Is it possible to make a reset, when i begin to read from the stream?


:sign0085:


thanks for help....
 

schimanski

Well-Known Member
Licensed User
Longtime User
How to discard?

Thanks for help, but i don't know, how I discard the old data? Which argument do I have to use?

m.f.G. schimanski
 

schimanski

Well-Known Member
Licensed User
Longtime User
The code, which I take the data from the server...

Hello Erel!

Here the code, which i take the data from the server:
If I don't take the data for perhaps two minutes, because i have selected another index in combobox2, i only can get the old data.


Sub Globals
Dim Type (Lat,Lon,HemLat,HemLon) Ziel
Dim Type (Lat,HemLat,Lon,HemLon,Geschwindigkeit,Kurs) Array_NMEA
..
end sub

Sub App_Start
GPS_Server.New1
..
end sub

'Create the server-connection, when button is clicked'
Sub Button4_Click
ErrorLabel(noconnection)
WaitCursor(true)
client.New1 'init Client-Objekt'
IP_Adresse=textbox18.Text
Port_Nummer=textbox19.Text
Client.Connect (IP_Adresse,Port_Nummer)

If timer2.Enabled=false Then timer2.Enabled = true
'I have tested the Timer with 2000, 1000 and 500 ms'
WaitCursor(false)
Return
noconnection:
..
End Sub

'Takes the data from the server'
Sub Timer2_Tick
ErrorLabel(connectionbreak)
if ComboBox2.SelectedIndex = 1 then
If client.DataAvailable=true Then
Image4.LoadPicture("IconDaten1.bmp")
filestream.New1(client.GetStream,false)
GPS_Server.GPSStream(filestream.ReadString)
Else
Image4.LoadPicture("IconDaten2.bmp")
End If
End If
Return

connectionbreak:
..
client.close
End Sub

'Read the GPS_Server-bufferstring'
Sub GPS_Server_GPSDecoded
ErrorLabel(GPS_Server_Fehler)
If GPS_Server.status="A" Then
Image3.LoadPicture("IconSat1.bmp")
Else
Image3.LoadPicture("IconSat2.bmp")
End If

Ziel.Lat=GPS_Server.DecimalLatitude
Ziel.HemLat=GPS_Server.LatitudeHemisphere
Ziel.Lon=GPS_Server.DecimalLongitude
Ziel.HemLon=GPS.LongitudeHemisphere

'Save the GPS-data from Server to create a NMEA-protocoll'
Array_NMEA.Lat=GPS_Server.Latitude
Array_NMEA.HemLat=GPS_Server.LatitudeHemisphere
Array_NMEA.Lon=GPS_Server.Longitude
Array_NMEA.HemLon=GPS_Server.LongitudeHemisphere
Array_NMEA.Geschwindigkeit=GPS_Server.SpeedOverGround
Array_NMEA.Kurs=GPS_Server.CourseOverGround

Label11.Text=Round(GPS_Server.SpeedOverGround * 1.852)

Label20.Text=Round(GPS_Server.Altitude) & "(" & (Round(GPS_Server.Altitude)-Round(GPS.Altitude)) & ")"
Return

GPS_Server_Fehler:
End Sub

'Close server-connection'
Sub Button3_Click
client.Close
If timer2.Enabled=true Then timer2.Enabled=false
Image3.LoadPicture("IconSat2.bmp")
Image4.LoadPicture("IconDaten2.bmp")
End Sub


'Generate a NMEA-protokoll (GPRMC) an send it to a serial COM.port'
Sub Timer3_Tick

NMEA="$GPRMC," & Time(Now) & ",A," & Array_NMEA.Lat & "," & Array_NMEA.HemLat & "," & Array_NMEA.Lon & "," & Array_NMEA.HemLon & "," & Array_NMEA.Geschwindigkeit & "," & Array_NMEA.Kurs & "," & Date(Now) & ",0.4,E,A*"

'Berechnung der Prüfsumme'
buffer() = bit.StringToBytes(NMEA,1,StrLength(NMEA)-2)
laenge=ArrayLen(buffer())
Summe=buffer(0)
For i=1 To laenge-1
Summe=bit.XOR(summe,buffer(i))
Next
Pruefsumme=bit.DecToHex(Summe)

'Pruefsumme am NMEA-Protokoll anhängen'
NMEA=NMEA & Pruefsumme & crlf

serial_output.Output(NMEA)
End Sub



:):):)
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You don't need to initialize filestream object each time you read the data.
Instead you should initialize once after creating the connection.

Maybe something like this will solve your problem:
Instead of:
B4X:
Sub Timer2_Tick
    ErrorLabel(connectionbreak)
    If ComboBox2.SelectedIndex = 1 Then
        If client.DataAvailable=true Then
            Image4.LoadPicture("IconDaten1.bmp")
            'REMOVE THIS LINE:filestream.New1(client.GetStream,false)
            GPS_Server.GPSStream(filestream.ReadString)
        Else
            Image4.LoadPicture("IconDaten2.bmp")
        End If
    End If
    Return
    
    connectionbreak:
    ..
    client.close
End Sub
Discard the data if ComboBox2.SelectedIndex doesn't equal 1:
B4X:
Sub Timer2_Tick
    ErrorLabel(connectionbreak)
    If ComboBox2.SelectedIndex = 1 Then
        If client.DataAvailable=true Then
            Image4.LoadPicture("IconDaten1.bmp")
            GPS_Server.GPSStream(filestream.ReadString)
        Else
            Image4.LoadPicture("IconDaten2.bmp")
        End If
    Else If client.DataAvailable Then
       fileStream.ReadString
    End If
    Return
    
    connectionbreak:
    ..
    client.close
End Sub
 

schimanski

Well-Known Member
Licensed User
Longtime User
Many thanks

Very best thanks, Erel. That what i'am looking for....
 

schimanski

Well-Known Member
Licensed User
Longtime User
Only one small problem..

Hello Erel,

thanks for your code. It works very best. But now i have one problem with this code: When the server breaks the connection, my application will stop and I can't do anything. The only thing is to end the application with the task-manager. When there is no data, i can handle the problem, but when the connection breaks, i don't no, how to handle this error.


:confused::confused:

...schimanski
 

derez

Expert
Licensed User
Longtime User
I had a similar problem, as mentioned in your first post,that the string does not always start with "$GP..." so I am checking it using strindexof():

instring = Serial.InputString
...
sats() = StrSplit(instring,",")
..
If StrIndexOf (sats(0) , "SA",0) > -1 Then gsa 'for string $GPGSA

the complete application code is here
http://www.b4x.com/forum/showthread.php?p=9108#post9108
 

schimanski

Well-Known Member
Licensed User
Longtime User
Lock up when server-connection is interuppted

Hello Erel, hello Derez!

I can't say, in which line the application locks up. The only thing is to end the app with the task-manager. I think, that the problem is in the sub timer2_tick, because the image4 (it's a little icon 15x15) doesn't change after breaking the server connection.
My english is not so good, so I don't know the function of client.value=server.accept. Is it nessesary to use this line?

:sign0013:
 

schimanski

Well-Known Member
Licensed User
Longtime User
Lock up when the server send no data

Hello!

I have written a smal testapp to see, where the problem is. When the server sends no data, the application will stop as long, as the server sends data again. When there is data again, the Application runs without any problems. Is there no data, i only can stop the app with the task-manager. Here the code:

Sub App_Start
Form1.Show
timer3.Enabled=true 'timer3=1000 ms'
client.New1
Client.Connect ("87.139.??.???",11112)
filestream.New1(client.GetStream,false)
End Sub

Sub Timer3_Tick
If client.DataAvailable=true Then
filestream.ReadString
label5.Text="data!"
Else
label5.Text="no data!"
End If
End Sub

The server-connection is always available!

:sign0085:

Now i have tested more:

The server sends every two seconds a NMEA-protocol. When the timer3 is 2000, the app will run without problems. Is the timer3 500ms, the app will stop, when there is no data. Is the timer3 1000ms, sometimes the app will lockup and another time, the app run without problems, when there is no data. But I need a timerintervall from 500, because when the timer is bigger than 500, i only get old data, not the actually.
 
Last edited:

schimanski

Well-Known Member
Licensed User
Longtime User
no server code

Hello Erel!

I can't post the server code, because it's not my application. It is a police-server with an GPS-application, that only provides GPS-data for every officer, who is in duty. Today we have only Notebooks with the same software to get this data. Now, i want' to write a client-application for PDA. I only can say, that the server provides every two seconds a NMEA-String (RMC & GGA) on one port and when there is no data, the server stops providing, but the connection is always available. I don't know the developer of this application, so I can't ask him.
I can' t understand the effects of the different timerintervalls.
:sign0013:
 

agraham

Expert
Licensed User
Longtime User
I can' t understand the effects of the different timerintervalls.:sign0013:
This is is a wild guess but is it anything to do with the fact that if you wait two seconds then a full message is probably available but polling more often than that it is likely that only part of a message is available. Does your app make the assumption that a full message always arrives as a single read? My experience of the network library is that even small messages can arrive as separate packets so you have to be prepared to reassemble multiple reads into a single message - which is what I believe the GPS library GPSStream method does.
 
Top