GPS application - Part I

Erel

B4X founder
Staff member
Licensed User
Longtime User
This tutorial is made of two parts.
The first part explains how to use the Serial library to create a connection with a GPS device and how to use the GPS library to retrieve the data.
The second part will explain how to convert coordinates from one datum to another and how to convert between Lat/Lon format and UTM format.

First we need to add a reference to the Serial and GPS libraries.
We will use the Serial2 library which requires .Net 2.0.
You can use SerialDesktop and SerialDevice instead but they are no longer supported by new devices and therefore are less recommended.

Create a new file and save it.
Without saving our file we won't be able to add any library as their is still no project folder.

Choose Tools - Components...
Choose Add Both (as we want to add the same libraries to both the desktop and the device) and add GPS.dll.
Add Serial2 in the same way.

Picture1.jpg


Each library added, exposes one or more objects types that can be added to our program.
There are two ways to add objects; at runtime with AddObject and at design time using Tools - Add Object.
Normally we will use the second option.
Add a GPS object and name it GPS1 and a Serial object and name it Serial1.

Picture2.jpg


Create a new form and add a Timer, a ListBox and one MenuItem named mnuConnect.

Picture3.jpg


Now for the real part...
GPS devices whether external or internal send the data via a serial port.
The port could be COM1 to COM9.
See this thread if you want to find the available ports from the registry:
http://www.b4x.com/forum/showthread.php?t=314
The GPS continuously sends NMEA strings.
Using a Serial object and a Timer we check each second if data is waiting in the input buffer.
If there is data we read the data and pass it to a GPS object.
B4X:
Sub Timer1_Tick
    If Serial1.InBufferCount > 0 Then
        GPS1.GPSStream(Serial1.InputString)
    End If
End Sub
GPS1 collects the partial strings and when there is enough data it parses the data and raises a GPSDecoded event.
Inside the GPSDecoded event we can read the GPS data (lstData is a ListBox):
B4X:
Sub GPS1_GPSDecoded
    lstData.Clear
    lstData.Add("Status: " & GPS1.Status)
    lstData.Add("Number of satellites: " & GPS1.NumberOfSatellites)
    lstData.Add("Time: " & GPS1.UTCTime)
    lstdata.Add("Lat: " & GPS1.Latitude)
    lstdata.Add("Lon: " & GPS1.Longitude)
    If gps1.SpeedOverGround <> "" Then lstdata.Add("Speed: " & (GPS1.SpeedOverGround * 1.852))
    lstdata.Add("Course: " & GPS1.CourseOverGround)
End Sub
Picture4.jpg


To make our application less error prone we've added a global variable named counter.
The GPS continuously sends data even when there is no satellites reception.
On each tick event (each second), if there is no data we increase counter by one.
If counter equals 5 (which means that no data was sent in the last five seconds), we assume that the connection is broken, we close the serial port and ask the user if he wants to reconnect.
B4X:
Sub Timer1_Tick
    If Serial1.InBufferCount > 0 Then
        Label1.Text = "GPS is connected."
        GPS1.GPSStream(Serial1.InputString)
        counter = 0
    Else
        counter = counter + 1
        If counter >= 5 Then 'After 5 seconds without any data we will try to make a new connection.
            counter = 0
            Timer1.Enabled = false
            Serial1.PortOpen = false
            Label1.Text = "No connection."
            GPS1.GPSBuffer = "" 'Clear the yet unparsed data.
            If Msgbox("GPS was disconnected." & crlf & "Do you want to reconnect?","",cMsgboxYesNo) = cYes Then
                mnuConnect_Click 'Try to reconnect.
            End If            
        End If
    End If
End Sub
Picture5.jpg


Some notes:
* Most of the GPS object properties are directly parsed from the NMEA strings.
If there is no reception properties like SpeedOverGround, Latitude / Longitude and CourseOverGround will not be zero but rather be an empty string.
Which means that you need to check that the data is not empty before using it in a calculation:
B4X:
If gps1.SpeedOverGround <> "" Then lstdata.Add("Speed: " & (GPS1.SpeedOverGround * 1.852)) 'Convert to KMH.
* The attached code uses port 8. You should change the global variable 'port' to match the right port.
* When the user closes Form1 we check if the serial port is still open and close it if necessary.
* You will need to install .Net 2.0 to run the attached code (or remove Serial2 library and add SerialDesktop and SerialDevice).
 

Attachments

  • GPS.zip
    9.8 KB · Views: 1,362

sruthika

New Member
Hi,

This is a great tutorial.
Just a small question: Is it possible to locate another gps object and then using that object as the end point, is it possible to travel towards it?
 

peacemaker

Expert
Licensed User
Longtime User
What PDAs can work well with GPS.dll ?

For ex., this sample works OK on Eten Glofiish device, but does not work on HTC device: the COM-port that's working OK with a navigation software over NMEA protocol, but if try GPS-Demo with the same port - the port can be opened, but next there is the "OutOfMemoryException" error in "sub_timer1_tick".

Seems the buffer is full of data, but cannot be decoded as NMEA.

But all these devices have the same modernest GPS chipset SirfStar III.
 

RoniR

New Member
i am trying to run the dlls in my Windows Mobile 5.0 Pocket PC application using .net framework 3.5
i've used them in my framework 1.0 application and they worked fine.They worked great actually
my application is running
when i tried them on the new framework i got an error
on Decoder.GPSStream(Buffer)
the application throws an expection.By viewing the details i get those
ExceptionCode: 0xc0000005
ExceptionAddress:0xxxe83d70
Reading:0x00000004
Faulting module: mscoree3_5.dll
offset: 0x00063d70

at SerialPort.ReadFile(int32 hFile,Byte[] Budder,Int32 mNumberOfBytesToRead..
at SerialPort.REadThreadProc()

i am using an Intermec CN3

any ideas?
 

hyyg

New Member
ABOUT THE gps PORT OPEN ERROR

WHEN I RUN THE GPS app(part I),can not open the gps port ,error messaege "open the gps error". i don't what's wrong.
 

epo

New Member
Licensed User
Using serial port not bluetooth

Pls disregard :)

:sign0085:

Hi!

I have a survey grade gps receiver with serial output. I want to use an ipaq h2415 to capture the streaming nmea sentences coming out of it. To do that, I have two options, use a socket compact flash serial adapter (SocketSerial(TM)) or the ipaq serial cable. As the GPS basic4ppc program you describe in this tutorial access the virtual serial port provided by bluetooth, is there a way to modify the program so it will use the hardware serial rather than the virtual one?

Programming ability is very limited and would appreciate all the help.

Thanks.
 
Last edited:
Hello. I'm a complete noob in the serial and GPS stuff can you please help me getting started?
I run the ComPorts.sbp on my device and this is what I get:
COM3::
COM5:: Serial Cable on COM5:
COM7::
COM8::
COM9::

So in the GPS example I set
Port = 5
in Sub Globals

When I run the app and click mnuConnect:Label1.Text = "Error opening port 5"

What's wrong?? Please help me.
Getting knowlege on these issues is very important to me.
:sign0085:
:sign0104:
 
Ooops I tried Port = 3
On clicking mnuConnect : Label1.Text = "Serial port is open"
and in 5 seconds - "No connection" and a msgbox :
"GPS was disconnected.Do you want to reconnect?"

Any help will be much appreciated
Thank you.
 
I just copied the source code.
How am I to connect a GPS to the port?
I have never even used a GPS so please pardon me asking silly questions :(
 
My device has external GPS . I have to choose a programm port COM0 to
COM9, GPD1 to GPD9; and a hardware port COM0 to COM9

Running the ComPorts.sbp gives the following result:
COM3::
COM5:: Serial Cable on COM5:
COM7::
COM8::
COM9::

:sign0085:

Running GPS4PPC (older version) I get msgbox "Error opening port:5"
If select COM3 I get msgbox "GPS is connected" and in 3 seconds "GPS disconnected"


Edit:

I have querried my device's support service and was told that my RoverPC c6 has no GPS module.

That is wierd as I have on the menu Settings => System => External GPS
 
Last edited:

dking

New Member
Error compiling program

hey guys,

when i try to compile the file to a Smartphone.exe the Basic4ppc-Desktop-compiler give me the error:"Smartphones do not support listbox control".

what's the issue? must i replace the listbox for something else?


dK
 

Zenerdiode

Active Member
Licensed User
You appear as an un-registered user. How are you compiling?

Also, because Smartphones do not have touch-screens, some controls that require stylus input can not be used and you get the error above.
 
Last edited:

diego

Member
Licensed User
Longtime User
GPS Speed without moving

I'm trying GPSDriver and GPS dll's and I notice that both lat/lon and speed are "moving" without moving, e.g. the speed fluctuates (2km/h, 4km/h...), so it's impossible to make a reliable distance calculation using this sample code:

B4X:
Sub getDistanceKM(lat1, long1, lat2, long2)

   DEGREES_TO_RADIANS = (cPI / 180.0)
   EARTH_RADIUS = 6371.0
   
   rlat1 = DEGREES_TO_RADIANS * lat1
   rlong1 = DEGREES_TO_RADIANS * long1
   rlat2 = DEGREES_TO_RADIANS * lat2
   rlong2 = DEGREES_TO_RADIANS * long2
   
   '   There is no real reason To break this lot into 
   '   4 statements but I just feel it's a little more 
   '   readable.
   p1 = Cos(rlat1) * Cos(rlong1) * Cos(rlat2) * Cos(rlong2)
   p2 = Cos(rlat1) * Sin(rlong1) * Cos(rlat2) * Sin(rlong2)
   p3 = Sin(rlat1) * Sin(rlat2)

   ret = p1 + p2 + p3
   If ret = 1 Then Return 0
   
   ret = ACos(ret)
   ret = ret * EARTH_RADIUS
   
   Return ret
   
End Sub

:sign0085:
 

mjcoon

Well-Known Member
Licensed User
I notice that both lat/lon and speed are "moving" without moving, e.g. the speed fluctuates (2km/h, 4km/h...), so it's impossible to make a reliable distance calculation ...

That's probably the inherent inaccuracy of a simple GPS receiver. Which is why, in http://www.b4x.com/forum/open-source-projects/5208-gps4ppc-v2-0-a-3.html#post36567 I included an averaging function.

Unfortunately I made the mistake of averaging the direction of travel too. When that alternates between 359 and 001 degrees the average comes out at 180, which is south rather than north! I haven't got a solution for that yet... (Klaus?)

Mike.
 
Top