Jump to content

How to read Data from my GPS module?


 Share

Recommended Posts

Hi,

I have a GPS bluetooth module that is sending data to my computer through a USB Bluetooth dongle adapter. When I use a small utility called TurboGPS with the setting on Com4 port the GPS is working fine and TurboGPS is receiving updated datas every second.

I would like to use Autoit to retreive those datas from the Bluetooth dongle and make my own little utility. So far, after numerous readings and searchings, I have not been able to progress a bit on that matter.

The dongle is using ports COM3, COM4 and COM5, as I can see in the "connexion pannel". If I remove it, I only have COM1.

Using CommMG.au3 I tried to open these ports but except for port COM1 I always have the message that the port does not exist.

I would be really happy if someone could tell me how to retreive the raw data that the GPS module is sending to the dongle using Autoit.

I am using Windows XP sp3 but I will also use Win 7.

Many thanks!

Alain

Edited by AlainB
Link to comment
Share on other sites

I tried everything that I could think about with CommMG.au3. I also used CommmgExamples.au3 that I found on this forum. The message is always the same: The port does not exist.

Edited by AlainB
Link to comment
Share on other sites

I tried everything that I could think about with CommMG.au3. I also used CommmgExamples.au3 that I found on this forum. The message is always the same: The port does not exist.

Have you got the COM port showed in the device manager when you plug in the GPS ?

Br, FireFox.

Link to comment
Share on other sites

Yes, I see COM3, COM4 and COM5 when I plug the dongle. If I remove it I only see COM1, the port that is installed on my computer. I have no problem opening it (COM1) with CommMG.au3.

Edited by AlainB
Link to comment
Share on other sites

Yes, I see COM3, COM4 and COM5 when I plug the dongle. If I remove it I only see COM1, the port that is installed on my computer.

If the COM1 port is always present, it means that the dongle is probably not using it because when you plug it in, the other COM ports appear.

You have not mentioned that you tried the other ports, did you do it?

Ops mistake. Well unless I have the GPS in my hands I can't solve the problem.

Br, FireFox.

Edited by FireFox
Link to comment
Share on other sites

Thanks for your reply FireFox.

To me, the problem is not the GPS. I may be wrong but I would be incline to think that the problem is that the COM ports used by the dongle are virtual ports and that CommMG.au3 is not suitable for that usage.

Have you ever succeded in opening a virtual COM port with Autoit? If so, please tell me how you did it.

Alain

Link to comment
Share on other sites

Thanks for your reply FireFox.

To me, the problem is not the GPS. I may be wrong but I would be incline to think that the problem is that the COM ports used by the dongle are virtual ports and that CommMG.au3 is not suitable for that usage.

Have you ever succeded in opening a virtual COM port with Autoit? If so, please tell me how you did it.

Alain

Unfortunately no, the only COM port I have used is for my Arduino; and it's quite simple.

Br, FireFox.

Link to comment
Share on other sites

Maybe this could help:

#include <WinAPI.au3>
$RESULT = _WinAPI_CreateFile(".COM3", 2, 2)
If $RESULT = 0 then
msgbox(16, "", "Port not available, please plug in your device")
else
$tBuffer = DllStructCreate("byte[6]")
_WinAPI_ReadFile($RESULT, DllStructGetPtr($tBuffer), 6, $nBytes)
_WinAPI_CloseHandle($RESULT)
$sText = BinaryToString(DllStructGetData($tBuffer, 1))
msgbox(64, "Reading", "This is the output of 6 bytes from COM3: " & $sText)
EndIf

----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Link to comment
Share on other sites

Hi,

Thanks MKISH!

It is helping a lot indeed.

I changed the code to read byte by byte. The output of the raw datas from the GPS is then very nice. But I don't know if this is the optimal way for retreiving those datas.

Thanks again.

Alain

(NB for the picture, the GPS module is connected but on my desk. It is nor receiving any data from the satellites. If I put it outside, I will receive all the updated datas including the coordinales.)

post-63893-0-71367800-1346586216_thumb.p

Edited by AlainB
Link to comment
Share on other sites

:guitar: If you consider making your own program, here is some guidance: http://www.codeproject.com/Articles/8128/Writing-Your-Own-GPS-Applications-Part-I.

----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Link to comment
Share on other sites

Hi,

Here is how I ended up retrieving the datas from my GPS module thanks to the help that I received here on this thread and elswhere on the web. This is my way of doing it and I would not be surprise at all that would exist a better way.

As I understand it, the GPS module is sending a block of datas every second . In this block are the NMEA sentences (GPGGA, GPRMC and others) and each sentence is delemited by a CRLF, chr(13) and chr(10).

The code below is retrieving the block of datas from the port byte by byte. It isolate the sentence needed and then extract from that sentence what is needed to be used. This code is a modified extract from my utility. It does not verify the checksum of the sentence as it is done in my utility.

#include <WinAPI.au3>
Global $Port1, $Port, $Buffer, $String, $Data
$Port1 ="COM4"
_OpenPort()
for $I = 1 to 5 ; Let's do the cycle 5 times
_GetData()
   Global $TimeStamp = $DATA[2] ; UTC time
 
   Global $Lat1= Round((StringRight($DATA[4],7)/60) + StringLeft($DATA[4],2),6) ; Latitude converted to decimal degrees
   if $DATA[5] = "S" Then
   $Lat1=$Lat1 * -1
   EndIf
   Global $Lon1= Round((StringRight($DATA[6],7)/60) + StringLeft($DATA[6],3),6) ; Longitude converted to decimal degrees
   if $DATA[7] = "W" Then
   $Lon1=$Lon1 * -1
   EndIf
  
   Global $Speed = $DATA[8] ; Speed is in Knots. Multiply by 1.852 for Km or 1.150779 for miles
 
   Global $Bearing = $DATA[9] ; In degrees
 
consolewrite("Time: " & $TimeStamp  & "   Latitude: " & $Lat1  & "   Longitude:  " & $Lon1  & "   Speed: " & $Speed & "   Bearing:  " & $Bearing & @CR )
next
Func _OpenPort()
   $Port = _WinAPI_CreateFile($Port1, 2, 2)
   If $Port = 0 then
   msgbox(16, "", "No response from port " & $Port1)
   exit
   else
   $Buffer = DllStructCreate("byte[1]")
   EndIf
EndFunc
Func _GetData()
   While 1
   _GetString()
   if StringLeft($String,6) = "$GPRMC" then
   $Data = stringsplit($String, ",")
   Return
   EndIf
   WEnd
EndFunc
Func _GetString()
   Local  $C = 0, $TempString = "", $sText
   While 1
   _WinAPI_ReadFile($Port, DllStructGetPtr($Buffer), 1, 1)
   $sText = BinaryToString(DllStructGetData($Buffer, 1))
   if $stext=chr(13) or $sText=chr(10) then
   $C=$C+1
   if $C=2 then
      $String = $TempString
      $TempString = ""
      $C=0
      Return
   endif
   else
   $TempString= $TempString & $sText
   EndIf
   WEnd
EndFunc

This is the picture of my utility in action. It mimic the GOTO function of my hand held GPS. It is very helpfull to get the direction to a point of interest, an hotel or something else,

The arrow gives the Bearing and the black square gives the position of the geographical North.

The GPS calculations are working well and the precisions (bearing, distance and speed) are good.

The utility is not finished and I still have some minor problems about the GUI itself. Mainly, when I want to quit the application, there is often a delay betwen the order to quit and the action. I suppose that retrieving and processing the datas from the GPS module take just a few miliseconds and the order to quit is process only during that time. The rest of the time wich is the biggest portion of the second, the computer is waiting for the COM port to send something. During that period, the order cannot be processed. AM I making any sense?

Alain

post-63893-0-90474600-1347446980_thumb.p

Edited by AlainB
Link to comment
Share on other sites

For your delayed exit issue, read the docs here - GUI Reference. In particular, scroll down to this section - GUI Event Modes, that may help.

Post all of your code, you will probably get better help than my shots in the dark.

- Bruce /*somdcomputerguy */  If you change the way you look at things, the things you look at change.

Link to comment
Share on other sites

I changed my script to OnEvenMode. I think that it is helping a bit. But not much.

However, it make the code much cleaner. No need to have a ChkMsg function and no need for the numerous calls that I was making to that function here and there in my script.

Thanks!

Edited by AlainB
Link to comment
Share on other sites

Here is the code that I use to calculate the distance between 2 coordinates and also the bearing. It is quite accurate, within 50 meters on a 5000 or so Km distance, from Montreal to Anchorage. This when compared with Google distances calculations. For the same coordinates Google gives 5026.92 Km and the function gives an unformated distance of 5026.8853 or 5026.9 formated.

The bearing is also very accurate.

This is not my codes. I am not that bright. Just things that I picked up on the web and adapt to Autoit with my low level of competence.

The picture show the accuracy of the bearing compare to Goggle Map. Funny to see that on a map, the shortest distance between 2 point is not necessary a straight line. It show also that the bearing will change when travelling on a long distance. I go often in Asia and on one of the plane that I take, going from Chicago to Tokyo, we always fly near Anchorage. This is because going that way it is the shortest distance to go from these 2 points.

#include <Math.au3>

;Montreal
global $Lat1 = 45.547283
global $Lon1 = -73.645783

;Anchorage airport
global $Lat2 = 61.175758
global $Lon2 = -149.979631

_DistanceAndBearing()

consolewrite("Distance " & $Distance & @CR & "Bearing " & $Bearing & @CR)

Func _DistanceAndBearing()
;Calculating the distance
Local $R = 6378.1 ;Earth radius in Km (Possibly the value used by Google to calculate distances)
Local $dLat = _Radian($lat2-$lat1)
Local $dLon = _Radian($lon2-$lon1)
Local $lat11 = _Radian($lat1)
Local $lat22 = _Radian($lat2)
Local $a = sin($dLat/2) * sin($dLat/2) + sin($dLon/2) * sin($dLon/2) * cos($lat11) * cos($lat22)
Local $c = 2 * _atan2(sqrt($a), sqrt(1-$a));
Global $Distance = $R * $c

;Formatting it
if $Distance >= 10 Then
    $Distance = Round($Distance,1)
         if $Distance = Int($Distance) Then
          $Distance = $Distance & ".0"
         endif
    $Distance = $Distance & " Km"
Else
    if $Distance < 1 then
         $Distance = Floor($Distance * 1000) & " m"
    Else
         $Distance = Round($Distance,2)
             if $Distance = Int($Distance) Then
                 $Distance = $Distance & ".00"
               endif
             if StringLen($Distance) = 3 then
                $Distance = $Distance & "0"
             EndIf
             if $Distance = "10.00" Then
                 $Distance = "10.0"
             EndIf
         $Distance = $Distance & " Km"
    endif
EndIf

;Calculating and formatting the bearing
Local $y = sin($dLon) * cos($lat22)
Local $x = cos($lat11)*sin($lat22) -sin($lat11)*cos($lat22)*cos($dLon)
Global $Bearing = Round(_Degree(_atan2($y, $x))) & "°"

;For not formatted results remove the semicolons below
; $Distance = $R * $c
; $Bearing = _Degree(_atan2($y, $x))
EndFunc

post-63893-0-50134700-1347651839_thumb.p

Edited by AlainB
Link to comment
Share on other sites

Well, i have been watching this for quite sometime. A suggestion for u - why not use your app with google maps if u have net connectivity, so as to get the directions and all other stuff?

----------------------------------------

:bye: Hey there, was I helpful?

----------------------------------------

My Current OS: Win8 PRO (64-bit); Current AutoIt Version: v3.3.8.1

Link to comment
Share on other sites

Hi MKISH,

I don't think that I will go that way. I want to keep it as simple as possible (The KISS formula). Just what you see plus a database of my Points of interest.

I am just using 5 datas from the GPRMC sentence: Latitude, Longitude, Speed, Bearing and the last data of the sentence that is a letter that gives information about the validity of the fix: good, estimated or bad. I use it to change the color of the arrow.

Eventually, I would like to buy a 7 in. tablet, like a Nexus with a build in GPS chip and translate this app for Android. This, only for my own usage of course. :shifty:

Android!... For now, I only know the name!!

Edited by AlainB
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...