Wednesday, September 06, 2006

Property Bar location using GPS (and Visual FoxPro) Part II

Ok, so in the last post I threw out some generalities regarding the project. This time we'll try and get down to some specifics.

I tend to attack projects from a proof-of-concept point of view. First, I'll try and get a rudimentary version up and running of whatever idea I'm working on. That keeps me interested. Once that has been successfully accomplished, that will motivate me to round it off with user interface etc, all the boring stuff that I've done for too many years now. That's not considered good practice, but hey, I'm the boss around here so I offer no apologies.

And so it went in this case.

Cost is always primary in my mind: it is a sport to keep software costs down. I purchased a Holux USB GPS module on eBay last year, which included a purported legal version of Microsoft Streets and Trips 2005. (I should point out that, even though this is a USB device for a hardware point of view, it presents itself as a serial port device from a software point of view.) The GPS works fine with MS S & T, but I was hoping that it would also include an ActiveX control, which I could then use to program the GPS from my own applications. However, it didn't, so I hunted around for other GPS serial port ActiveX controls on the web. There's quite a number out there, but the price is somewhat steep. So I decided to see if I could use the serial port control included with most (or all) versions of Windows, MSComm. After the usual amount of trail-and-error and some research on the web, I got it to work with the GPS. The GPS reports its status every second when it rattles off a number of phrases all of which start with a $ sign. Of the 3 or 4 phrases the Holux offers, I only used the $GPGGA one, which dissects as follows:


*$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
*!* Where:
*!* GGA Global Positioning System Fix Data
*!* 123519 Fix taken at 12:35:19 UTC
*!* 4807.038,N Latitude 48 deg 07.038' N
*!* 01131.000,E Longitude 11 deg 31.000' E
*!* 1 Fix quality: 0 = invalid
*!* 1 = GPS fix (SPS)
*!* 2 = DGPS fix
*!* 3 = PPS fix
*!* 4 = Real Time Kinematic
*!* 5 = Float RTK
*!* 6 = estimated (dead reckoning) (2.3 feature)
*!* 7 = Manual input mode
*!* 8 = Simulation mode
*!* 08 Number of satellites being tracked
*!* 0.9 Horizontal dilution of position
*!* 545.4,M Altitude, Meters, above mean sea level
*!* 46.9,M Height of geoid (mean sea level) above WGS84
*!* ellipsoid
*!* (empty field) time in seconds since last DGPS update
*!* (empty field) DGPS station ID number
*!* *47 the checksum data, always begins with *

Of course, I didn't figure this out on my own, but got most of it from
http://www.gpsinformation.org/dale/nmea.htm.

The MSComm control has a property RThreshold (for receive threshold). I set this at 2. By default, it is set at 0. When set at 2, it makes the control receive 2 characters before it fires the OnComm event. If it is set at 0, the OnComm event does not fire at all. The OnComm event is really the heart of the MSComm control, this is where the action takes place. Simply put, all the characters are received and the string is parsed for the values contained in it. These values are then logged to a database table, and depending on what action we are currently executing, a method is called to execute that action.

The next major item is the graphing software. As I said in my previous post, I used NTGraph for this, another ActiveX control. To do plotting, simply feed 2 values to the PlotXY method and as long as they fit in the range of the graph (which can be dynamically altered), it will plot the values. If it is outside the range, you can change the values of the range, and all previously plotted points will automatically be replotted on their new spots on the graph.

The third major item is the computer voice. Now this is where it gets really easy. The voice is done using an ActiveX control included in all Windows version. I simply instatiated it in the init of my form, as such


thisform.oSapi=CREATEOBJECT("SAPI.spVoice.1")

then all you need to do to have it speak is the following:

thisform.oSapi.Speak("Keith is one helluva guy")

Of course, I didn't figure this out on my own, Calvin Hsia showed me the way.

Ok, that's it for today, before information overload sets in.