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

Example GPS Code


  • Please log in to reply
15 replies to this topic

#1 Patrick

Patrick

    Advanced Member

  • Members
  • PipPipPip
  • 54 posts
  • LocationTampa

Posted 13 August 2010 - 08:56 PM

I'm at a point with my GPS code that it's still pretty much project agnostic so I thought some people may find it helpful to see.

I'm using this GPS...

...and I have it connected to my Netduino as follows:
Netduino GPS
DIO0 TTL TX
DIO1 TTL RX
5V Vcc
Gnd Gnd

I also had to add the SerialPort reference to the project as Chris explains here.

Using the following code, I seem to be getting an acceptable number of statements when polling 2 times a second and am not missing too many statements. There is some basic error handling in the code where I only accept statements that start with $ and have a * (checksum indicator) in them.

I think it's a nice jumping off spot for a GPS integration. I hope it's helpful!

using System;
using System.Collections;
using System.IO.Ports;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace Netduino_GPS
{
    public class Program
    {
        public static void Main()
        {
            //create a connection to the led to show we're running
            OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
            
            //instantiate the serial port connection                          
            SerialPort serialPort = new SerialPort("COM1", 4800, Parity.None, 8, StopBits.One);              
            serialPort.Open();            

            while (true)
            {      
                int bytesToRead = serialPort.BytesToRead;                              
                
                //start reading the stream
                if (bytesToRead > 0)
                {
                    //blink the LED to show we got data
                    led.Write(true);
                    Thread.Sleep(100);
                    led.Write(false);

                    // get the waiting data
                    byte[] buffer = new byte[bytesToRead];
                    serialPort.Read(buffer, 0, buffer.Length);
 
                    //only accept a statement starting with $
                    if (buffer[0] != 36)
                        continue;

                    //copy the byte array to a readable string
                    String str = new String(System.Text.Encoding.UTF8.GetChars(buffer));                    
                    
                    //break up string into statements
                    String delimStr = "\r";
                    char[] delim = delimStr.ToCharArray();
                    string[] statements = null;  
                    statements = str.Split(new Char[] { '\r','\n' });

                    for (int i = 0; i < statements.Length; i++)
                    {
                        //only accept statements with a checksum
                        String currStatement = statements[i];
                        if (currStatement.Length > 0 && currStatement.IndexOf("*") >= 0)
                            parseNMEA(statements[i]);
                    }
                }

                //poll every half second
                Thread.Sleep(500); 
            }               
        }

        private static void parseNMEA(String statement)
        {   
            String statementType = statement.Substring(0, 6);

            switch (statementType)
            {
                case "$GPGGA":
                    ProcessGPGGA(statement);
                    break;
                case "$GPGSA":
                    ProcessGPGSA(statement);
                    break;
                case "$GPGSV":
                    ProcessGPGSV(statement);
                    break;
                case "$GPRMC":
                    ProcessGPRMC(statement);
                    break;
                default:
                    Debug.Print("Unrecognized NMEA String: " + statement);
                    break;
            }
        }

        private static void ProcessGPGGA(String nmeaStatement)
        {
            Debug.Print(nmeaStatement);
            /*
            $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 *
             */
        }

        private static void ProcessGPGSA(String nmeaStatement)
        {
            Debug.Print(nmeaStatement);
            /*
            $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39

            Where:
                 GSA      Satellite status
                 A        Auto selection of 2D or 3D fix (M = manual) 
                 3        3D fix - values include: 1 = no fix
                                                   2 = 2D fix
                                                   3 = 3D fix
                 04,05... PRNs of satellites used for fix (space for 12) 
                 2.5      PDOP (dilution of precision) 
                 1.3      Horizontal dilution of precision (HDOP) 
                 2.1      Vertical dilution of precision (VDOP)
                 *39      the checksum data, always begins with *
             */
        }

        private static void ProcessGPGSV(String nmeaStatement)
        {
            Debug.Print(nmeaStatement);
            /*
            $GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75

            Where:
                  GSV          Satellites in view
                  2            Number of sentences for full data
                  1            sentence 1 of 2
                  08           Number of satellites in view

                  01           Satellite PRN number
                  40           Elevation, degrees
                  083          Azimuth, degrees
                  46           SNR - higher is better
                       for up to 4 satellites per sentence
                  *75          the checksum data, always begins with *
             */
        }

        private static void ProcessGPRMC(String nmeaStatement)
        {
            Debug.Print(nmeaStatement);

            /*
            $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A

            Where:
                 RMC          Recommended Minimum sentence C
                 123519       Fix taken at 12:35:19 UTC
                 A            Status A=active or V=Void.
                 4807.038,N   Latitude 48 deg 07.038' N
                 01131.000,E  Longitude 11 deg 31.000' E
                 022.4        Speed over the ground in knots
                 084.4        Track angle in degrees True
                 230394       Date - 23rd of March 1994
                 003.1,W      Magnetic Variation
                 *6A          The checksum data, always begins with *
             */
        }
    } 
}


#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 13 August 2010 - 10:14 PM

Great start to a GPS parser. Wow, Netduino is just barely more than a week old and you guys have really started pulling some cool code and projects together.

#3 Chris Seto

Chris Seto

    Advanced Member

  • Members
  • PipPipPip
  • 405 posts

Posted 14 August 2010 - 12:56 AM

Very nice. I will be doing a GPS project soon and I think I will use part of your code, or all, if you are done by then. Thanks for your contribution!

#4 kingpin2k

kingpin2k

    Member

  • Members
  • PipPip
  • 23 posts
  • LocationUSA

Posted 15 August 2010 - 06:33 AM

Just a FYI, using gpsinformation I've been working on the language parsing for the GPS sentences. I've got GGA and RMC complete. My GPS (Microsoft Pharos something or other) supports those 4 sentence types as well. Once the project forum section is up I'll post the code. I imagine I'll be done with it all tomorrow sometime.
Homer: [Meeting Aliens] Please don't eat me! I have a wife and kids. Eat them!

#5 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 15 August 2010 - 06:44 AM

Just a FYI, using gpsinformation I've been working on the language parsing for the GPS sentences. I've got GGA and RMC complete. My GPS (Microsoft Pharos something or other) supports those 4 sentence types as well. Once the project forum section is up I'll post the code. I imagine I'll be done with it all tomorrow sometime.


The new Project showcase forum is all ready for you...as of about one minute ago :)

#6 kingpin2k

kingpin2k

    Member

  • Members
  • PipPip
  • 23 posts
  • LocationUSA

Posted 15 August 2010 - 07:27 AM

Done and done. Thanks!
Homer: [Meeting Aliens] Please don't eat me! I have a wife and kids. Eat them!

#7 Johnny Five

Johnny Five

    Member

  • Members
  • PipPip
  • 29 posts

Posted 22 September 2010 - 10:58 PM

Thanks Patrick. Definitely going to be using this :) Hope I can give back to your project at some point!

#8 Patrick

Patrick

    Advanced Member

  • Members
  • PipPipPip
  • 54 posts
  • LocationTampa

Posted 23 September 2010 - 04:05 PM

Thanks Patrick. Definitely going to be using this :)

Hope I can give back to your project at some point!


You're quite welcome! Can't wait to see that balloon fly!

#9 kingpin2k

kingpin2k

    Member

  • Members
  • PipPip
  • 23 posts
  • LocationUSA

Posted 24 September 2010 - 01:00 AM

You launchin a weather balloon? My friend and I did it last year, it was a ton of fun. We took over 800 pictures at ~80k elevation. It was sweet, good luck if you're doing it!
Homer: [Meeting Aliens] Please don't eat me! I have a wife and kids. Eat them!

#10 Patrick

Patrick

    Advanced Member

  • Members
  • PipPipPip
  • 54 posts
  • LocationTampa

Posted 24 September 2010 - 01:21 PM

You launchin a weather balloon? My friend and I did it last year, it was a ton of fun. We took over 800 pictures at ~80k elevation. It was sweet, good luck if you're doing it!


It was quite the strange coincidence to find that Johhny 5 was also planning a high altitude balloon launch but it's been fun watching our project come together in parallel, yet different ways.

@kingpin2k, I'm using your GPS parser as the backbone of my project. Everytime I get a GPS message, I'm logging the gps and sensor data to my sd card in kml format with the goal of being able to view the entire trip in Google Earth, immediately after recovery.

In case anyone is interested, I picked up this very affordable, TTL level GPS that supports high altitude operations.

If anyone is interested, I have a couple google docs that I'm using to track my progress and will be posting my code soon to the google repository; just drop me a line for access.

`Patrick

#11 Chris Seto

Chris Seto

    Advanced Member

  • Members
  • PipPipPip
  • 405 posts

Posted 06 October 2010 - 10:04 PM

Psssst!: http://mfgps.codeplex.com Any contributions would be VERY much appreciated.

#12 Crispin

Crispin

    Advanced Member

  • Members
  • PipPipPip
  • 65 posts
  • LocationLondon, England, Earth

Posted 07 October 2010 - 03:53 PM

Psssst!: http://mfgps.codeplex.com

Any contributions would be VERY much appreciated.



You have a PM
--
Take a seat, I'll be right with you.

#13 Chris Seto

Chris Seto

    Advanced Member

  • Members
  • PipPipPip
  • 405 posts

Posted 07 October 2010 - 03:59 PM

...And you too! :) Thanks for your interest!

#14 Crash_Overload

Crash_Overload

    New Member

  • Members
  • Pip
  • 7 posts
  • LocationTexas

Posted 21 April 2011 - 11:50 PM

hello i am new to netduino and i have the exact same gps chip and i ran the test code and i get nothing it does not even make it to the debug statemenst

#15 Patrick

Patrick

    Advanced Member

  • Members
  • PipPipPip
  • 54 posts
  • LocationTampa

Posted 22 April 2011 - 01:24 AM

The GPS code kingpin posted is MUCH more robust than what I have, so you should certainly use that.

Even still; the code I posted should work. Are you sure you have it wired correctly? Any errors?

#16 AMD_Fusion

AMD_Fusion

    New Member

  • Members
  • Pip
  • 7 posts

Posted 01 August 2011 - 10:30 AM

Hi,

I’m having trouble converting an Arduino GPS code to C#. I’m trying to display latitude, longitude, date, time, speed and altitude.

What are the Netduino equivalent of NewSoftSerial and TinyGPS libraries?

I have stacked a Sparkfun GPS shield (with EM-406 GPS module) on top of a Netduino and hooked up to a 20x4 LCD.

http://tronixstuff.w...apter-17-–-gps/

Any help is welcome. Thanks in advance.

Here’s the Arduino code – example 17.2.


// necessary libraries
#include <NewSoftSerial.h>
#include <TinyGPS.h>
#include <LiquidCrystal.h>

// initialize the LiquidCrystal library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 2, 3);

// Define which pins you will use on the Arduino to communicate with your
// GPS. In this case, the GPS module's TX pin will connect to the
// Arduino's RXPIN which is pin 3.
#define RXPIN 0 // GPS TX pin connects to Arduino D0 (thankfully by default)
#define TXPIN 1 // GPS RX pin connects to Arduino D1. You could change these if making your own hardware
#define GPSBAUD 4800 // baud rate of our EM-406 GPS module. Change for your GPS module if different

// Create an instance of the TinyGPS object
TinyGPS gps;
// Initialize the NewSoftSerial library to the pins you defined above
NewSoftSerial uart_gps(RXPIN, TXPIN);

// This is where you declare prototypes for the functions that will be
// using the TinyGPS library.
void getgps(TinyGPS &gps);

// In the setup function, you need to initialize two serial ports; the
// standard hardware serial port (Serial()) to communicate with your
// terminal program an another serial port (NewSoftSerial()) for your
// GPS.
void setup()
{
uart_gps.begin(GPSBAUD); // setup sketch for data output speed of GPS module
// set up the LCD's number of rows and columns:
lcd.begin(20, 4);
lcd.clear();
lcd.setCursor(2,1);
lcd.print("* My First GPS *");
lcd.setCursor(3,2);
lcd.print("tronixstuff.com");
delay(5000);
lcd.clear();
lcd.setCursor(2,1);
lcd.print("Waiting for lock");
}

// This is the main loop of the code. All it does is check for data on
// the RX pin of the ardiuno, makes sure the data is valid NMEA sentences,
// then jumps to the getgps() function.
void loop()
{
while(uart_gps.available()) // While there is data on the RX pin...
{
int c = uart_gps.read(); // load the data into a variable...
if(gps.encode©) // if there is a new valid sentence...
{
getgps(gps); // then grab the data, and display on LCD
}
}
}

// The getgps function will get and print the values we want.
void getgps(TinyGPS &gps)
{
// Define the variables that will be used
float latitude, longitude;
// Then call this function
gps.f_get_position(&latitude, &longitude);
// clear LCD
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Lat: ");
lcd.print(latitude,5);
lcd.setCursor(0,1);
lcd.print("Long: ");
lcd.print(longitude,5);
// Same goes for date and time
int year;
byte month, day, hour, minute, second, hundredths;
gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);
// Print data and time
lcd.setCursor(1,2);
lcd.print(hour, DEC);
lcd.print(":");
if (minute<10)
{
lcd.print("0");
lcd.print(minute, DEC);
} else if (minute>=10)
{
lcd.print(minute, DEC);
}
lcd.print(":");
if (second<10)
{
lcd.print("0");
lcd.print(second, DEC);
} else if (second>=10)
{
lcd.print(second, DEC);
}
lcd.print(" ");
lcd.print(day, DEC);
lcd.print("/");
lcd.print(month, DEC);
lcd.print("/");
lcd.print(year, DEC);
lcd.setCursor(0,3);
lcd.print(gps.f_altitude());
lcd.print("m ");
lcd.print(gps.f_speed_kmph());
lcd.print("km/h");

}

Posted Image




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.