Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    Pytrack RMC message

    Scheduled Pinned Locked Moved Expansion Board
    pytrackgnrmc
    9 Posts 4 Posters 2.6k Views 4 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • R Offline
      rolandvs
      last edited by

      I was playing with the Pytrack and needed the date/time from the GPS. The $GNRMC string provides the time, date, speed and direction information along with the coordinates.
      So I created a quick hack by adding this to the L76GNSS.py code. I only use date and time.

      # date time
      	def datetime(self, debug=False):
      		thetime, debug_timeout = None, False
      		if self.timeout != None:
      			self.chrono.start()
      		nmea = b''
      		while True:
      			if self.timeout != None and self.chrono.read() >= self.timeout:
      				self.chrono.stop()
      				chrono_timeout = self.chrono.read()
      				self.chrono.reset()
      				self.timeout_status = False
      				debug_timeout = True
      			if self.timeout_status != True:
      				gc.collect()
      				break
      			nmea += self._read().lstrip(b'\n\n').rstrip(b'\n\n')
      			gnrmc_idx = nmea.find(b'GNRMC') # find time data long lat
      			if gnrmc_idx >= 0:
      				gnrmc = nmea[gnrmc_idx:]
      				e_idx = gnrmc.find(b'\r\n')
      				if e_idx >= 0:
      					try:
      						gnrmc = gnrmc[:e_idx].decode('ascii')
      						gnrmc_s = gnrmc.split(',')
      						thetime = (gnrmc_s[1],gnrmc_s[9]) #return time and date
      					except Exception:
      						pass
      					finally:
      						nmea = nmea[(gnrmc_idx + e_idx):]
      						gc.collect()
      						break
      			else:
      				gc.collect()
      				if len(nmea) > 4096:
      					nmea = b''
      			time.sleep(0.1)
      		self.timeout_status = True
      		if debug and debug_timeout:
      			print('GPS timed out after %f seconds' % (chrono_timeout))
      			return(None)
      		else:
      			return(thetime)
      
      L 1 Reply Last reply Reply Quote 0
      • L Offline
        livius @rolandvs
        last edited by

        @rolandvs
        better is usuing some working code which exist on the web
        the best i have found is this:
        https://github.com/inmcm/micropyGPS/blob/master/micropyGPS.py

        it need some modifications and extend error handling.
        Also at the end you need to add GLONASS comands to the list.
        Work for me like a charm :)

        think about people first, then computers

        O 1 Reply Last reply Reply Quote 1
        • R Offline
          rolandvs
          last edited by

          Thanks, I'll give it a try. Looks good!

          1 Reply Last reply Reply Quote 0
          • O Offline
            ozeta @livius
            last edited by ozeta

            @livius hi, cannot code right now but i have some questions: what are glonass sentences?

            i see that micropygps uses:
            'GPRMC', 'GPGGA', 'GPVTG', 'GPGSA', 'GPGSV', 'GPGLL'

            from l76 documentation ( here: http://ecksteinimg.de/Datasheet/QuectelL76-LGNSS.pdf )
            gnsll fix uses:
            GPGSV, GLGSV, GNGLL, GNGSA
            in this list, oly gpgsv is implemented in micropyGPS. I can simply add and implement these other 3?

            L 1 Reply Last reply Reply Quote 0
            • L Offline
              livius @ozeta
              last edited by

              @ozeta
              Simply add something like this on the list:

               'GNGLL': gpgll
              

              and other commands. As you can see i attache GNGLL to already supported gpgll emthod

              think about people first, then computers

              O 1 Reply Last reply Reply Quote 0
              • O Offline
                ozeta @livius
                last edited by

                @livius hi, yesterday i figured it out and did this change on my own.

                as for error handling what do you refer to? i didn't have any trouble till today

                L 1 Reply Last reply Reply Quote 0
                • L Offline
                  livius @ozeta
                  last edited by

                  @ozeta
                  you can get IndexError in various places if message is somehow malformed.

                  think about people first, then computers

                  1 Reply Last reply Reply Quote 0
                  • U Offline
                    urblau
                    last edited by

                    this is my solution.....
                    works quite well , but somtimes i get an memory error....

                    from machine import Timer
                    import time
                    import gc
                    import binascii
                    import machine

                    class L76GNSS:

                    GPS_I2CADDR = const(0x10)
                    
                    def __init__(self, pytrack=None, sda='P22', scl='P21', timeout=None):
                        if pytrack is not None:
                            self.i2c = pytrack.i2c
                        else:
                            from machine import I2C
                            self.i2c = I2C(0, mode=I2C.MASTER, pins=(sda, scl))
                    
                        self.chrono = Timer.Chrono()
                    
                        self.timeout = timeout
                        self.timeout_status = True
                    
                        self.reg = bytearray(1)
                        self.i2c.writeto(GPS_I2CADDR, self.reg)
                    
                    def _read(self):
                        self.reg = self.i2c.readfrom(GPS_I2CADDR, 64)
                        return self.reg
                    
                    def _convert_coords(self, gngll_s):
                        gc.collect()
                        #lat = gngll_s[1]
                        lat = gngll_s[3]
                        lat_d = (float(lat) // 100) + ((float(lat) % 100) / 60)
                        #lon = gngll_s[3]
                        lon = gngll_s[5]
                        lon_d = (float(lon) // 100) + ((float(lon) % 100) / 60)
                        #if gngll_s[2] == 'S':
                        if gngll_s[4] == 'S':
                            lat_d *= -1
                        #if gngll_s[4] == 'W':
                        if gngll_s[6] == 'W':
                            lon_d *= -1
                        #zeit = gngll_s[5]
                        zeit = gngll_s[1]
                        #print("zeit", zeit)
                        geschw = gngll_s[7]
                        kurs = gngll_s[8]
                        datum = gngll_s[9]
                        return(lat_d, lon_d, zeit, datum, geschw, kurs)
                    
                    def coordinates(self, debug=False):
                        lat_d, lon_d, zeit, datum, geschw, kurs, debug_timeout = None, None, None, None, None, None, False
                        if self.timeout != None:
                            self.chrono.reset()
                            self.chrono.start()
                        nmea = b''
                        while True:
                            if self.timeout != None and self.chrono.read() >= self.timeout:
                                self.chrono.stop()
                                chrono_timeout = self.chrono.read()
                                self.chrono.reset()
                                self.timeout_status = False
                                debug_timeout = True
                            if self.timeout_status != True:
                                gc.collect()
                                break
                            gc.collect()#######################################################
                            if gc.mem_free() <= 25000:#########################################
                                print('##############################################################test1 %f' % (gc.mem_free()))##############################
                                machine.reset()################################################
                    
                            nmea += self._read().lstrip(b'\n\n').rstrip(b'\n\n')
                            #gngll_idx = nmea.find(b'GNGLL')
                            #print (nmea)
                            gngll_idx = nmea.find(b'GNRMC')
                            if gngll_idx >= 0:
                                gngll = nmea[gngll_idx:]
                                e_idx = gngll.find(b'\r\n')
                                if e_idx >= 0:
                                    try:
                                        gngll = gngll[:e_idx].decode('ascii')
                                        gngll_s = gngll.split(',')
                                        #print("gngll_s", gngll_s)
                                        lat_d, lon_d, zeit, datum, geschw, kurs = self._convert_coords(gngll_s)
                                    except Exception:
                                        pass
                                    finally:
                                        nmea = nmea[(gngll_idx + e_idx):]
                                        gc.collect()
                                        break
                            else:
                                gc.collect()
                                if len(nmea) > 4096:
                                    nmea = b''
                            time.sleep(0.1)
                        self.timeout_status = True
                        if debug and debug_timeout:
                            print('GPS timed out after %f seconds' % (chrono_timeout))
                            return(None, None, None, None, None, None)
                        else:
                            gc.collect()
                            return(lat_d, lon_d, zeit, datum, geschw, kurs)
                    
                    L 1 Reply Last reply Reply Quote 0
                    • L Offline
                      livius @urblau
                      last edited by livius

                      @urblau said in Pytrack RMC message:

                      gc.mem_free() <= 25000

                      why do you reset device under 25K free mem?
                      And you should analyze where you consume memory.

                      My pytrack work many days and collect and then send data to the server.

                      You must carefully manage strings and make calculations.
                      e.g. previously i have used some implementation from internet about HMC5883L
                      but when i saw how it eat memory on every run i go into optimized solution.
                      maybe this point you to some direction:
                      https://github.com/pycom/pycom-libraries/pull/8/files

                      sometimes python syntax is evil in limited memory world..

                      think about people first, then computers

                      1 Reply Last reply Reply Quote 0

                      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                      With your input, this post could be even better 💗

                      Register Login
                      • 1 / 1
                      • First post
                        Last post

                      Pycom on Twitter

                      Pycom