Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

NMEA GPS driver


  • Please log in to reply
19 replies to this topic

#1 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 02 June 2012 - 04:11 PM

I just finished writing a driver for NMEA GPS devices.

This is a code sample:
public static NmeaGps Gps = new NmeaGps();
public static OutputPort Led = new OutputPort(Pins.ONBOARD_LED, false);

public static void Main()
{
    // Binds all events to the GPS device
    Gps.GotFix += new NativeEventHandler(Gps_GotFix);
    Gps.LostFix += new NativeEventHandler(Gps_LostFix);
    Gps.PositionChanged += new NativeEventHandler(Gps_PositionChanged);
    // Starts the GPS device
    Debug.Print("Trying to get a fix...");
    Gps.Start();

    // Nice blinking LED effect when we have a fix
    while (true)
    {
        Led.Write(Gps.Fix);
        Thread.Sleep(450);
        Led.Write(!Gps.Fix);
        Thread.Sleep(50);
    }
}

static void Gps_PositionChanged(uint Unused, uint FixType, DateTime GPSTime)
{
    string Outp = "";
    Outp += "3D-Fix: " + Gps.Fix3D.ToString();
    Outp += ", Sattellites: " + Gps.Satellites.ToString();
    Outp += ", Time: " + Gps.GPSTime.ToString();
    Outp += ", Latitude: " + Gps.SLatitude;
    Outp += ", Longitude: " + Gps.SLongitude;
    Outp += ", Altitude: " + Gps.SAltitude;
    Outp += ", Knots: " + Gps.Knots.ToString() + " (" + Gps.Kmh.ToString() + " km/h)";
    Debug.Print(Outp);

    // If you want to translate this to a Bing Maps URL, try this:
    Debug.Print("http://www.bing.com/maps/?q=" + Tools.RawUrlEncode(Gps.Latitude.ToString() + " " + Gps.Longitude.ToString()));
}

static void Gps_GotFix(uint Unused, uint FixType, DateTime GPSTime)
{
    Debug.Print("We got a fix, yay!!");
}

static void Gps_LostFix(uint Unused, uint FixType, DateTime GPSTime)
{
    Debug.Print("We lost our GPS fix :(");
}

And yes, it also generates Bing Maps URLs so you can actually see on a map where your netduino has been :D

I've tested this with Sparkfun's GPS shield, but I believe this should work with all serial NMEA GPS devices.

Code can be downloaded at http://netmftoolbox.codeplex.com/
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 02 June 2012 - 09:21 PM

Oh awesome. I've been thinking about building some robots recently, and GPS makes robots all the more awesome. The online mapping link is a pretty neat bonus! Chris

#3 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 02 June 2012 - 09:27 PM

The online mapping link is a pretty neat bonus!

Thanks! I also made some code which wrote the data to SD which I could import into Google Maps. Perhaps I'll post that sample some day too :)
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#4 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 02 June 2012 - 09:30 PM

Thanks! I also made some code which wrote the data to SD which I could import into Google Maps. Perhaps I'll post that sample some day too :)

You've been busy! So what kind of cool projects could be done with this driver?

Chris

#5 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 02 June 2012 - 09:33 PM

You've been busy! So what kind of cool projects could be done with this driver?

I made it because I often ride my motor cycle, and use my mobile phone for tracking. Gives wonderful images when imported in google maps.
See for example this image:
Attached File  googlemaps.png   206.18KB   97 downloads
But I think a Netduino can do the same thing consuming lesser power.
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#6 Arbiter

Arbiter

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBrisbane, Australia

Posted 15 June 2012 - 04:47 AM

I wrote one of these. Do you find that you get a lot of malformed NMEA sentences? I've been unsure as to whether the problem is
  • misconfigured COM1
  • flaky serial driver
  • GPS chipset sending malformed packets


This, for example

$GPRMC,013909.000,A,2731.9582,S,15250.4890,E,0.00,,14PVTG,,T,,M,0.00,N,0.0,K*7E

is obviously two sentences mashed together with bytes missing in the middle.
One day, all this too shall parse.

#7 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 15 June 2012 - 06:08 AM

I wrote one of these. Do you find that you get a lot of malformed NMEA sentences?

Not at all I think. Actually, I'm not 100% sure, I just added the XOR data check, so invalid data is just discarded, and I got plenty of valid data to work with.
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#8 Arbiter

Arbiter

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBrisbane, Australia

Posted 18 June 2012 - 01:24 AM

If you have the time and inclination, I'd be interested to know what percentage of sentences are discarded so I can compare with my own rig. I'm using the ITEAD Studio gps shield and I'm starting to wonder if I should give up on NMEA sentences and write a SIRF III binary protocol driver.
One day, all this too shall parse.

#9 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 18 June 2012 - 06:19 AM

I won't add statistics in it for now, since it'll require more testing, memory and performance, but if you use the attached version, and the code loop below, you'll see how much data is thrown away.

public static void Main()
{
    Gps = new NmeaGps("COM2", 4800);
    Gps.Start();
    while (true)
    {
        Debug.Print(Gps.BytesAccepted + " bytes accepted, " + Gps.BytesDiscarded + " bytes discarded");
        Thread.Sleep(1000);
    }
}

I found my GPS module has a 100% accepted ratio.

Attached Files


"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#10 Arbiter

Arbiter

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBrisbane, Australia

Posted 29 June 2012 - 05:56 AM

Thanks Stef. I finally got a chance to pursue this. It seems I was lazy and didn't check the sum, leaving it to my exception handlers to cope with bad data. In other respects your code works much the same as mine. I'm thinking about switching from a push to a pull model. As you know, by default these modules emit a constant stream of NMEA sentences, and there are commands for setting the rate at which the various sentence types are emitted. I call this push mode because the GPS pushes out position reports. The maximum rate is 1Hz in because the interval unit is seconds and the interval parameter is an integer. You can also set rates of zero, which effectively stops the unit from pushing. The datasheets for my GPS board claim a maximum positioning rate of 5Hz. I think that in order to get positions every 200ms I will have to put the unit in pull mode and poll it five times a second. I think pull mode has merit for other applications too, because it can reduce the load on the CPU.
One day, all this too shall parse.

#11 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 29 June 2012 - 08:50 AM

I finally got a chance to pursue this. It seems I was lazy and didn't check the sum, leaving it to my exception handlers to cope with bad data.

I indeed added all checks virtually possible. But still, my GPS module didn't sent any broken data.

I'm thinking about switching from a push to a pull model. As you know, by default these modules emit a constant stream of NMEA sentences, and there are commands for setting the rate at which the various sentence types are emitted.

Indeed. I didn't implement such things just to keep it compatible with (almost) all generic NMEA devices. Extended command sets aren't always available. But if you really need many fixes per second, I recommend to do so. Since my class is 100% open source, adding such things should be easy. Saves you the time taking care of all checks including the XOR checksum.
Feel free to use my code!
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#12 Arbiter

Arbiter

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBrisbane, Australia

Posted 02 July 2012 - 12:20 AM

Thank you, that's very kind, but your code is much too big for my purposes; my app does quite a lot else.One of the advantages of pull mode is that you don't have to support many message formats - just RMC for the date and GGA for CoG and HDOP.
One day, all this too shall parse.

#13 Arbiter

Arbiter

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBrisbane, Australia

Posted 02 July 2012 - 12:36 PM

If anyone is interested I have succeeded in using the ITEADSTUDIO EB-365 Sirf III shield in pull mode. This is much better adapted to logger style applications than the standard mode because
  • No async code is required.
  • CPU load is lighter.
  • Memory loads are shorter lived.
  • Power requirements are lower.
With the class as written you just invoke the Update method, and then datetime, lat, lng, alt, hdop, cog, kph and fix type are all available from properties of the Sirf object, ready for inclusion in the log entry.
One day, all this too shall parse.

#14 bytepoet

bytepoet

    New Member

  • Members
  • Pip
  • 2 posts

Posted 13 July 2012 - 11:59 AM

very interested, please share!

#15 Arbiter

Arbiter

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBrisbane, Australia

Posted 16 July 2012 - 06:29 AM

I should probably mention that this code does not implement its own retry or timeout recovery because I use it with my own task manager which imposes a maximum execution time on each of the tasks given to it. I have never seen the GPS fail to answer but it is possible and for anything you intend to release into the wild you will need some sort of task manager (irrespective of whether my Sirf code is in use). It's possible to specify timeouts directly on the SerialPort object if you don't want to go as far as writing a process manager. I just didn't because I have a broader approach to failures. To use it, create an instance of the Sirf class and call the Init() method. All of the parameters are optional and default configuration uses COM1, 9600, 8N1 which is the default configuration of the ITEASTUDIO EB-365. There's a pair of jumpers on the board. You MUST set INT0 to ON otherwise you can't talk to the EB-365 (OFF is listen-only mode). I have INT1 set to OFF but I don't think it makes any difference.

Attached Files

  • Attached File  Sirf.cs   4.29KB   34 downloads

One day, all this too shall parse.

#16 uyasduh

uyasduh

    New Member

  • Members
  • Pip
  • 2 posts

Posted 18 July 2012 - 12:46 AM

You've been busy! So what kind of cool projects could be done with this driver?

#17 Arbiter

Arbiter

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationBrisbane, Australia

Posted 18 July 2012 - 10:52 AM

You've been busy! So what kind of cool projects could be done with this driver?



You sound eerily like Chris.

High-resolution vehicle tracking. In the normal push mode, 1Hz is the fastest update you can get. In pull mode, you can get 5Hz out of the EB-365. There are faster chipsets (pololu.com sells a 10Hz unit) but I would have to write a new driver.

In my day job I deal with commercial vehicle tracking. The units upload their data to our server. This effectively puts it in escrow from a legal perspective, which makes it admissible as evidence. We are occasionally called upon to provide forensic data to police, and as much as they like having reliable positional and accelerometer data at 1Hz I can tell you with certainty that they would be over the moon with 5Hz.
One day, all this too shall parse.

#18 Paolo Patierno

Paolo Patierno

    Advanced Member

  • Members
  • PipPipPip
  • 169 posts
  • LocationItaly

Posted 15 August 2012 - 11:06 AM

Which GPS shield have you used with Netduino and with this driver ?

Paolo.

I just finished writing a driver for NMEA GPS devices.


Paolo Patierno

Microsoft MVP on Windows Embedded & IoT

Azure Advisor

Twitter : @ppatierno
Linkedin : paolopatierno
Blog : DevExperience

Blog : Embedded101
?


#19 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 15 August 2012 - 12:46 PM

Which GPS shield have you used with Netduino and with this driver ?

Paolo.

I used Sparkfuns GPS Shield with the EM-406A GPS Module.
But NMEA is a protocol used by many GPS devices, and the shield is 'just breaking out' the correct connections (RX+TX) to the serial port on the Netduino, so it should work with different GPS setups as well.
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#20 ahmedfme

ahmedfme

    Member

  • Members
  • PipPip
  • 14 posts
  • LocationEgypt

Posted 28 April 2013 - 10:17 AM

[color=rgb(37,51,64);font-family:'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;font-size:13px;]i have got skylab skm53 module and i try to connect to netduino plus 2 .[/color]
[color=rgb(37,51,64);font-family:'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;font-size:13px;]i connect Rx to d1 and Tx to d0 and 5v and gnd and then used your sample code .[/color]
[color=rgb(37,51,64);font-family:'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;font-size:13px;]but always i gor slatitude = 8960.0000,N[/color]
[color=rgb(37,51,64);font-family:'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;font-size:13px;]and slongitude = 00000.0000,E[/color]
[color=rgb(37,51,64);font-family:'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;font-size:13px;]saltitude = 137.0,M[/color]
[color=rgb(37,51,64);font-family:'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;font-size:13px;]and fix = false and sat=0[/color]
[color=rgb(37,51,64);font-family:'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;font-size:13px;]i have tried in home and outdoor and nothing change.[/color]
[color=rgb(37,51,64);font-family:'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;font-size:13px;]i appreciate any help[/color]






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.