Read NMEA from Server

Discussion in 'Questions (Windows Mobile)' started by schimanski, Dec 13, 2007.

  1. schimanski

    schimanski Well-Known Member Licensed 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!!!
     
  2. Erel

    Erel Administrator Staff Member Licensed User

    You could try to use the GPS library.
    The GPS.GPSStream collects pieces of NMEA strings and parses it when there is enough data.
     
  3. schimanski

    schimanski Well-Known Member Licensed 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
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    The GPS decoder waits for a full GPGGA and a full GPRMC sentences.
    There is no problem with creating several GPS objects.
     
  5. schimanski

    schimanski Well-Known Member Licensed 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....
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    You can read the waiting data and discard it. Wait one second and read the new data.
     
  7. schimanski

    schimanski Well-Known Member Licensed 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
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    Can you post the code that you use to read the data from the server and pass it to the GPS object?
     
  9. schimanski

    schimanski Well-Known Member Licensed 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



    :):):)
     
  10. Erel

    Erel Administrator Staff Member Licensed 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:
    Code:
    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:
    Code:
    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
     
  11. schimanski

    schimanski Well-Known Member Licensed User

    Many thanks

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

    schimanski Well-Known Member Licensed 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
     
  13. Erel

    Erel Administrator Staff Member Licensed User

    Can you find the line that gets blocked?
     
  14. derez

    derez Expert Licensed 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.basic4ppc.com/forum/showthread.php?p=9108#post9108
     
  15. schimanski

    schimanski Well-Known Member Licensed 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:
     
  16. Erel

    Erel Administrator Staff Member Licensed User

    server.accept should be called in the server code.
    It creates the connection with the client.
    The client object that is returned should be used to communicate with the real client.
    Can you upload your code file?
     
  17. schimanski

    schimanski Well-Known Member Licensed 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: Feb 8, 2008
  18. Erel

    Erel Administrator Staff Member Licensed User

    Your client code is fine and it should not be blocked.
    Can you post your server code?
     
  19. schimanski

    schimanski Well-Known Member Licensed 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:
     
  20. agraham

    agraham Expert Licensed User

    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.
     
Loading...