asynycio as_GPS

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
User avatar
romeotango
Posts: 29
Joined: Tue Jun 16, 2015 10:52 am
Location: Germany

Re: asynycio as_GPS

Post by romeotango » Mon Jan 27, 2020 7:17 am

@pythoncoder
Yeah, that works just like you said it would. But unfortunately with my device it does not recognize position messages, the callback is not called.
My first step was do add these not supported sentences GNGLL and GPGLL to the list.
Now all records can be handled by the parser.
The NMEA data records contain the talker-id at the beginning. This indicates which system was used for the current NMEA record.
Nowadays almost all GPS receivers can use several systems at the same time to get an optimal position determination.
Then the talker-id is <GN>.
NMEA messages are shown with heading $Gxyyy, where x stands for the satellite system (P = GPS, SBAS, QZSS, L = GLONASS, A = Galileo, B = BeiDou, N = Any combination of GNSS) and yyy for the type of message (e.g. ZDA=Time & Date).
This is irrelevant for selecting the appropriate NMEA data set.
- Suggestion: use only the 3 letters behind, the rest is discarded.



But another step is necessary.
Parsing NMEA
['GNRMC', '105120.00', 'A', '5207.48262', 'N', '00838.29766', 'E', '0.473', '', '220120', '', '', 'A', '6F']
The records at the position, 8 (speed), 10, 11 (Mag Var) are empty.
This leads to an error during the conversion to float, which then discards the data set.
My first approach was to simply convert the empty in fields segs to 0. Using a list-comprehension?
This would then be required for every record, so it always takes time.
The alternative would be an if-statement before the float calculation. But that would be 2 extra if-queries.
Hence my question about the time needed:
I want to track at high frequency.
I try to use a board like LoPy or FiPy or one of the new boards.

The GPS receivers I currently use are from u-blox®.
So they offer another version: PUBX.
Here are all the data I need in one line.
But the configuration is quite different from MTK commands.
And again a Windows program.

So I go on and on with great pleasure - and a lot of time.
Like riding a motorbike: The way is the goal.

User avatar
romeotango
Posts: 29
Joined: Tue Jun 16, 2015 10:52 am
Location: Germany

Re: asynycio as_GPS

Post by romeotango » Mon Jan 27, 2020 7:33 am

@gersch07
The first step in dealing with RAM is to precompile your libraries from -.py to -.mpy
Look upwards in thread for the windows-exe.
Worked, but not to good.
And testing and codechanging is very time-consuming.
I used the docker-container mentioned above.
Was a bit of work to install the correct toolchain in it. Pycom documentation worked. The PATH in bash-source file has to be changed on every run, but that are just some seconds and copy&paste
Is about the same as the stone age man who found a BIC lighter :) It works, but he does not know why.

I used the official uasyncio Version2 library as described in peterhinch's tutorial and appended it as frozen bytecode.
That solved the RAM-problems.
A machine.reset() after each test ist useful, otherwise the famous guru-meditation occurs :(
So my LOPY uses uasyncio as frozen code and the as_GPS was as real python-code in the /lib-directory.
Access via ftp and code changes are easy to apply.

If you are interested in my docker container, i can upload it on any way you want to...
Last edited by romeotango on Mon Jan 27, 2020 2:41 pm, edited 2 times in total.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: asynycio as_GPS

Post by pythoncoder » Mon Jan 27, 2020 9:09 am

This should work, and has been tested, with official uasyncio V2.

The traceback suggests that the data from your GPS hardware is somehow provoking a bug in my code. I'll look into this.
Peter Hinch
Index to my micropython libraries.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: asynycio as_GPS

Post by pythoncoder » Mon Jan 27, 2020 10:58 am

[EDITED]
@gersch07 The traceback suggests you are getting malformed sentences from your GPS. A sentence should be of form

$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

where the $ and * characters delineate the data start and end of the actual data. The code appears not to be finding the *. This is puzzling as I check for its presence earlier. To find out what's going on I suggest you put in a print statement at this point to see exactly what is being received before it fails:

Code: Select all

    async def _run(self, loop):
        while True:
            res = await self._sreader.readline()
            print(res)  # Received line
            try:
I was only able to test this with the Adafruit GPS receiver. It does seem that there is some variation between hardware types.

Please let me know the outcome of your testing: is this a common or infrequent failure?
Peter Hinch
Index to my micropython libraries.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: asynycio as_GPS

Post by pythoncoder » Mon Jan 27, 2020 12:07 pm

@romeotango Evidently my GPS never sends empty fields, so I never saw this error.

I think the cautious approach is to assume any numeric field may be empty and to define a function gfloat which can accept them and replace all float conversions with gfloat:

Code: Select all

def gfloat(s):
    if s:
        return float(s)
    return 0.0
As for the two letter prefix perhaps it can safely be discarded.
Peter Hinch
Index to my micropython libraries.

User avatar
romeotango
Posts: 29
Joined: Tue Jun 16, 2015 10:52 am
Location: Germany

Re: asynycio as_GPS

Post by romeotango » Mon Jan 27, 2020 2:35 pm

['GNRMC', '105120.00', 'A', '5207.48262', 'N', '00838.29766', 'E', '0.473', '', '220120', '', '', 'A', '6F']
The sentence i printed ist already the cleaned version, i checked the output before and it ist correct.
pythoncoder wrote:
Mon Jan 27, 2020 12:07 pm
@romeotango Evidently my GPS never sends empty fields, so I never saw this error.

I think the cautious approach is to assume any numeric field may be empty and to define a function gfloat which can accept them and replace all float conversions with gfloat:

Code: Select all

def gfloat(s):
    if s:
        return float(s)
    return 0.0
As for the two letter prefix perhaps it can safely be discarded.
ACK for both!

Due to my plan to receive messages with 5-10Hz I want to configure my u-blox®-GPS-Receiver to send just the necessary sentence.
For backwards compatibility I send some NMEA sentences once per second or once per 30? seconds, especially those which give more satellites information
For me it seems to be best to disable nearly all messages but
$PUBX, which incorporates all information i want to use and i need. With 5Hz oder 10Hz.
With PUBX, 000, ... i can get all in one line. So the transmitted data volume is small and it can be parsed in a whole.
It contains RMC, GLL, VTG, GGA,, GSA in one line.

https://www.u-blox.com/sites/default/fi ... Public.pdf

Page 138 of 407
31.3.2 POSITION (PUBX,00) 31.3.2.1 Lat/Long Position Data
Supported on:
• u-blox 8 / u-blox M8 protocol versions 15, 15.01, 16, 17, 18, 19, 19.1, 19.2, 20, 20.01,
20.1, 20.2, 20.3, 22, 23 and 23.01
Description
Lat/Long Position Data
$PUBX,00,time,lat,NS,long,EW,altRef,navStat,hAcc,vAcc,SOG,COG,vVel,diffAge,HDOP,VDOP,TDOP,numSvs,reserved,DR,*cs<CR><LF>
$PUBX,00,081350.00,4717.113210,N,00833.915187,E,546.589,G3,2.1,2.0,0.007,77.52,0.007,,0.92,1.19,0.77,9,0,0*5F
message-id.+identf, lat , , lon. , , alt. , ,hor,ver,speed,cours,vert ,,HDOP,VDOP,TDOP,#,R,CRC
time navstatus velocity of satellites used
accuracy

sorry for the linebreak :(
def _pubx00(self, gps_segments):
has to be developed.
Lots of information, thank you for thinking about it...

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: asynycio as_GPS

Post by pythoncoder » Mon Jan 27, 2020 6:07 pm

I've pushed an update. This has two changes:
  • Float conversion returns 0.0 if the field is blank.
  • The sentence type is now checked to reject proprietary sentences (1st char 'P') but otherwise ignore the 1st 2 characters. Thus GLRMC, GPRMC and GNRMC will all be parsed as RMC.
@gersch07 I still haven't figured out why your error is occurring but the suggested print statement should help.

These issues are not related to uasyncio: the library's usage of uasyncio is straightforward.

The problems are down to GPS units sending data in formats that I hadn't encountered from the Adafruit unit. With help from you guys these should easily be fixed.
Peter Hinch
Index to my micropython libraries.

User avatar
romeotango
Posts: 29
Joined: Tue Jun 16, 2015 10:52 am
Location: Germany

Re: asynycio as_GPS

Post by romeotango » Mon Jan 27, 2020 6:43 pm

I love this lambda constructs, but have some problems to create them...

Just started to implement PUBX in my fork.
I will publish it to you, when it is tested.
You are really fast!

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: asynycio as_GPS

Post by pythoncoder » Tue Jan 28, 2020 9:58 am

I have now pushed an update to fix the problem seen by @gersch07

I think a malformed line must have been received where the first character was a "*". This sort of thing can happen, for example if the host is rebooted while the GPS is running. The code now performs a basic sanity check before processing a line.

Thanks @gersch07 and @romeotango for these reports - it's always useful when people test with different hardware setups.
Peter Hinch
Index to my micropython libraries.

User avatar
romeotango
Posts: 29
Joined: Tue Jun 16, 2015 10:52 am
Location: Germany

Re: asynycio as_GPS

Post by romeotango » Tue Jan 28, 2020 12:27 pm

Code: Select all

        
        seg0 = segs[0][1:]  # discard $
        segx = seg0[2:]  # Discard 1st 2 chars
        segs = segs[:-1]  # and checksum
Error in last line?
segs = segx[:-1] # and checksum[/code]
................!!.............

Post Reply