Henke_83
Posts: 5
Joined: Tue Jan 06, 2015 10:18 am

Help with code for Pynmea2!

Sat Aug 29, 2015 7:33 am

I need help to get the right output for my Pynmea2. I don´t know what I have done wrong, but something is not right. It looks like the parsing with the Pynmea2.parse() doesn´t work as expected or I do something wrong with the data who should come in to pynmea2.
When I test in the Python console with the below message it works as supposed. But with my code below the output is not right.
Can someone help me to put me in the right direction what I have done wrong.

Here is the home of Pynmea2: https://github.com/Knio/pynmea2/blob/master/README.md

Code: Select all

>>> import pynmea2
>>> msg = pynmea2.parse("$GPGGA,184353.07,1929.045,S,02410.506,E,1,04,2.6,100.00,M,-33.9,M,,0000*6D")
>>> msg
<GGA(timestamp=datetime.time(18, 43, 53), lat='1929.045', lat_dir='S', lon='02410.506', lon_dir='E', gps_qual='1', num_sats='04', horizontal_dil='2.6', altitude=100.0, altitude_units='M', geo_sep='-33.9', geo_sep_units='M', age_gps_data='', ref_station_id='0000')>
Below is my code:

Code: Select all

import serial
import pynmea2
ser = serial.Serial('/dev/ttyAMA0',9600)
while 1:
     data = ser.readline()
     if (data.startswith("$GPGGA")):
         pynmea2.parse(data)
         print data
Here is my result:
The output is this: $GPGGA,184353.07,1929.045,S,02410.506,E,1,04,2.6,100.00,M,-33.9,M,,0000*6D
But I want the ouput to be like this: <GGA(timestamp=datetime.time(18, 43, 53), lat='1929.045', lat_dir='S', lon='02410.506', lon_dir='E', gps_qual='1', num_sats='04', horizontal_dil='2.6', altitude=100.0, altitude_units='M', geo_sep='-33.9', geo_sep_units='M', age_gps_data='', ref_station_id='0000')>

User avatar
DougieLawson
Posts: 39304
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Help with code for Pynmea2!

Sat Aug 29, 2015 10:45 am

If we look at the code in ../pynmea2/pynmea2/types/talker.py

Code: Select all

class GGA(TalkerSentence, ValidGGAFix, LatLonFix):
    fields = (
        ('Timestamp', 'timestamp', timestamp),
        ('Latitude', 'lat'),
        ('Latitude Direction', 'lat_dir'),
        ('Longitude', 'lon'),
        ('Longitude Direction', 'lon_dir'),
        ('GPS Quality Indicator', 'gps_qual', int),
        ('Number of Satellites in use', 'num_sats'),
        ('Horizontal Dilution of Precision', 'horizontal_dil'),
        ('Antenna Alt above sea level (mean)', 'altitude', float),
        ('Units of altitude (meters)', 'altitude_units'),
        ('Geoidal Separation', 'geo_sep'),
        ('Units of Geoidal Separation (meters)', 'geo_sep_units'),
        ('Age of Differential GPS Data (secs)', 'age_gps_data'),
        ('Differential Reference Station ID', 'ref_station_id'),
    )
that gives us all the data values that are parsed out of a $GPGGA sentence. So in our python code we can use

Code: Select all

#!/usr/bin/python

import pynmea2
msg = pynmea2.parse("$GPGGA,184353.07,1929.045,S,02410.506,E,1,04,2.6,100.00,M,-33.9,M,,0000*6D")
print msg.lat
print msg.lat_dir
print msg.lon
print msg.lon_dir
print msg.timestamp
print msg.gps_qual
print msg.num_sats
print msg.horizontal_dil
print msg.altitude
print msg.altitude_units
print msg.geo_sep
print msg.geo_sep_units
print msg.age_gps_data
print msg.ref_station_id
And that gets

Code: Select all

dougie@apollo:/tmp$ ./nmeadecode.py
1929.045
S
02410.506
E
18:43:53.070000
1
04
2.6
100.0
M
-33.9
M

0000
dougie@apollo:/tmp$
when we run it (with your data).

If you want to read a stream and pick out just the GGA sentences use something like this

Code: Select all

nmea = open(filename)

for sentence in nmea:
  try:
    pNMEA = pynmea2.parse(sentence)
    if isinstance(pNMEA, pynmea2.types.talker.GGA):
      # do stuff for GGA sentence here
  except:
    pass
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

Henke_83
Posts: 5
Joined: Tue Jan 06, 2015 10:18 am

Re: Help with code for Pynmea2!

Sun Aug 30, 2015 2:59 pm

Thank you for reply!
But as a newbie on Python - how should I use this in my code?

Why isn´t it possible to do the way I tried to do it? If I use the pynmea2.parse(data) - why does the data string not be a NMEAsentence? I thought If I would do like this the data would be parsed.
Why does print not print out the parsed data but only the raw data from the nmea string from the serial read?

Have I misunderstand something?

User avatar
DougieLawson
Posts: 39304
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Help with code for Pynmea2!

Sun Aug 30, 2015 7:28 pm

You've misunderstood the way the data is returned from the pynmea2 library. It creates an instance of a GGA object for a $GPGGA sentence.

I wrote this code to decode all the stuff that my GPS receiver sends

Code: Select all

#!/usr/bin/python

import pynmea2
filename = "/tmp/nmea.raw" # <== CHANGE ME to the NMEA serial device
nmea = open(filename)

for sentence in nmea:
  try:
    pNMEA = pynmea2.parse(sentence)
    if isinstance(pNMEA, pynmea2.types.talker.BOD):
      print "BOD"
      print '\tBearing True:', pNMEA.bearing_t
      print '\tBearing True Type:', pNMEA.bearing_t_type
      print '\tBearing Magnetic:', pNMEA.bearing_mag
      print '\tBearing Magnetic Type:', pNMEA.bearing_mag_type
      print '\tDestination:', pNMEA.dest
      print '\tStart:', pNMEA.start

    if isinstance(pNMEA, pynmea2.types.talker.RMC):
      print "RMC"
      print "\tTimestamp:", pNMEA.timestamp
      print '\tStatus:', pNMEA.status
      print "\tLatitude:", pNMEA.lat
      print "\tLatitude Direction:", pNMEA.lat_dir
      print "\tLongitude:", pNMEA.lon
      print "\tLongitude Direction:", pNMEA.lon_dir
      print "\tSpeed Over Ground:", pNMEA.spd_over_grnd
      print "\tTrue Course:", pNMEA.true_course
      print "\tDatestamp:", pNMEA.datestamp
      print "\tMagnetic Variation:", pNMEA.mag_variation
      print "\tMagnetic Variation Direction:", pNMEA.mag_var_dir

    if isinstance(pNMEA, pynmea2.types.talker.RMB):
      print "RMB"
      print '\tStatus:', pNMEA.status
      print "\tCross Track Error:", pNMEA.cross_track_error
      print "\tCross Track Error, direction to correct:", pNMEA.cte_correction_dir
      print "\tOrigin Waypoint ID:", pNMEA.origin_waypoint_id
      print "\tDestination Waypoint ID:", pNMEA.dest_waypoint_id
      print "\tDestination Waypoint Latitude:", pNMEA.dest_lat
      print "\tDestination Waypoint Lat Direction:", pNMEA.dest_lat_dir
      print "\tDestination Waypoint Longitude:", pNMEA.dest_lon
      print "\tDestination Waypoint Lon Direction:", pNMEA.dest_lon_dir
      print "\tRange to Destination:", pNMEA.dest_range
      print "\tTrue Bearing to Destination:", pNMEA.dest_true_bearing
      print "\tVelocity Towards Destination:", pNMEA.dest_velocity
      print "\tArrival Alarm:", pNMEA.arrival_alarm

    if isinstance(pNMEA, pynmea2.types.talker.RTE):
      print "RTE"
      print "\tNumber of sentences in sequence:", pNMEA.num_in_seq
      print "\tSentence Number:", pNMEA.sen_num
      print "\tStart Type:", pNMEA.start_type
      print "\tName or Number of Active Route:", pNMEA.active_route_id

    if isinstance(pNMEA, pynmea2.types.talker.GLL):
      print "GLL"
      print '\tLatitude:', pNMEA.lat
      print '\tLatitude Direction:', pNMEA.lat_dir
      print '\tLongitude:', pNMEA.lon
      print '\tLongitude Direction:', pNMEA.lon_dir
      print '\tTimestamp:', pNMEA.timestamp
      print '\tStatus:', pNMEA.status
      print "\tFAA mode indicator:", pNMEA.faa_mode

    if isinstance(pNMEA, pynmea2.types.talker.GSA):
      print "GSA"
      print '\tMode:', pNMEA.mode
      print '\tMode fix type:', pNMEA.mode_fix_type
      print '\tSV ID01:', pNMEA.sv_id01
      print '\tSV ID02:', pNMEA.sv_id02
      print '\tSV ID03:', pNMEA.sv_id03
      print '\tSV ID04:', pNMEA.sv_id04
      print '\tSV ID05:', pNMEA.sv_id05
      print '\tSV ID06:', pNMEA.sv_id06
      print '\tSV ID07:', pNMEA.sv_id07
      print '\tSV ID08:', pNMEA.sv_id08
      print '\tSV ID09:', pNMEA.sv_id09
      print '\tSV ID10:', pNMEA.sv_id10
      print '\tSV ID11:', pNMEA.sv_id11
      print '\tSV ID12:', pNMEA.sv_id12
      print '\tPDOP (Dilution of precision):', pNMEA.pdop
      print '\tHDOP (Horizontal DOP):', pNMEA.hdop
      print '\tVDOP (Vertical DOP):', pNMEA.vdop

    if isinstance(pNMEA, pynmea2.types.talker.GSV):
      print "GSV"
      print '\tNumber of messages of type in cycle:', pNMEA.num_messages
      print '\tMessage Number:', pNMEA.msg_num
      print '\tTotal number of SVs in view:', pNMEA.num_sv_in_view
      if int(pNMEA.snr_1) > 0:
        print '\tSV #1'
        print '\t\tSV PRN number:', pNMEA.sv_prn_num_1
        print '\t\tElevation in degrees:', pNMEA.elevation_deg_1
        print '\t\tAzimuth, deg from true north:',pNMEA.azimuth_1
        print '\t\tSNR:', pNMEA.snr_1
      if int(pNMEA.snr_2) > 0:
        print '\tSV #2'
        print '\t\tSV PRN number:',pNMEA.sv_prn_num_2
        print '\t\tElevation in degrees:', pNMEA.elevation_deg_2
        print '\t\tAzimuth, deg from true north:', pNMEA.azimuth_2
        print '\t\tSNR:', pNMEA.snr_2
      if int(pNMEA.snr_3) > 0:
        print '\tSV #3'
        print '\t\tSV PRN number:', pNMEA.sv_prn_num_3
        print '\t\tElevation in degrees:', pNMEA.elevation_deg_3
        print '\t\tAzimuth, deg from true north:', pNMEA.azimuth_3
        print '\t\tSNR:', pNMEA.snr_3
      if int(pNMEA.snr_4) > 0:
        print '\tSV #4'
        print '\t\tSV PRN number:', pNMEA.sv_prn_num_4
        print '\t\tElevation in degrees:', pNMEA.elevation_deg_4
        print '\t\tAzimuth, deg from true north:', pNMEA.azimuth_4
        print '\t\tSNR:', pNMEA.snr_4

    if isinstance(pNMEA, pynmea2.types.talker.GGA):
      print "GGA"
      print '\tTimestamp:', pNMEA.timestamp
      print '\tLatitude:', pNMEA.lat
      print '\tLatitude Direction:', pNMEA.lat_dir
      print '\tLongitude:', pNMEA.lon
      print '\tLongitude Direction:',pNMEA.lon_dir
      print '\tGPS Quality Indicator:', pNMEA.gps_qual
      print '\tNumber of Satellites in use:', pNMEA.num_sats
      print '\tHorizontal Dilution of Precision:', pNMEA.horizontal_dil
      print '\tAntenna Alt above sea level (mean):', pNMEA.altitude
      print '\tUnits of altitude (metres):', pNMEA.altitude_units
      print '\tGeoidal Separation:', pNMEA.geo_sep
      print '\tUnits of Geoidal Separation:', pNMEA.geo_sep_units
      print '\tAge of Differential GPS Data (secs):', pNMEA.age_gps_data
      print '\tDifferential Reference Station ID:', pNMEA.ref_station_id

  except:
    pass

close(filename)
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

Henke_83
Posts: 5
Joined: Tue Jan 06, 2015 10:18 am

SOLVED! Re: Help with code for Pynmea2!

Mon Aug 31, 2015 10:46 am

Thanks again for explanation - It become very advanced with all scripts. I contacted the maker of Pynmea2 and got a nice working solution. See the finished code.

Code: Select all

import serial
import pynmea2
ser = serial.Serial('/dev/ttyAMA0',9600)
while 1:
     data = ser.readline()
     if (data.startswith("$GPGGA")):
         msg = pynmea2.parse(data)
         print repr(msg)

Cyborg21
Posts: 4
Joined: Mon Jan 11, 2016 7:32 pm

Re: Help with code for Pynmea2!

Mon Jan 11, 2016 7:51 pm

Hello,
It's my first post on this forum.
I need to extract information from Adafruit ultimate GPS on a Raspberry 2.
I use pynmea lib and the serial port on python3, and I have a problem to use different information (time, latitude, ....)

My code is something like this :

Code: Select all

import pynmea2
import serial

GPSrx = serial.Serial("/dev/ttyAMA0", 9600)

While 1: 
  GPSbuf = GPSrx.readline()
  GPSstr = str(GPSbuf)
  msg = pynmea2.parse(GPSstr)
.....
My program fails when I update with serial method, but it works good if I initialize a string like :

Code: Select all

 GPSbuf = "$GPGGA,184353.07,1929.045,S,02410.506,E,1,04,2.6,100.00,M,-33.9,M,,0000*6D")
Is anybody with a begining of solution for me ?

Chears,
Cyb

Cyborg21
Posts: 4
Joined: Mon Jan 11, 2016 7:32 pm

Re: Help with code for Pynmea2!

Tue Jan 12, 2016 7:34 am

Hi,
I think that I found an explanation for my problem.
My GPS doesn't transmitt only GPGAA frame. It transmits GPGGA, and GPGSA, ....
In my code, I make a parse without frame conditions, and if I parse and I want to extract timestanp from a none GPGGA trame, python is not happy.

I try this and I'll be back.

Cyb

User avatar
DougieLawson
Posts: 39304
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Help with code for Pynmea2!

Thu Jan 14, 2016 7:18 am

Take a look at
https://code.google.com/p/pynmea/

There's more than one sentence received by your GPS that carries the current time. The $GPRMC sentence includes a time stamp.

Before using your GPS receiver you must disable the serial console using sudo raspi-config
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

Return to “Python”