Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

Hi everyone!
I wanted to share my new open-source library: light-nmea-micropython.
For years, micropyGPS was the only choice for MicroPython, but it’s slow (25 pps) and chokes the Garbage Collector with string allocations.
I built light_nmea specifically for 32-bit MCUs working with high-rate GNSS receivers (10-50 Hz):

  • 12x - 15x faster than micropyGPS on RP2040 (delivers 375 pps).
  • Minimum RAM allocation on the hot path (parse_line) — no string slicing, no GC freezes.
  • Modern GNSS support: Parses 7 constellations (GPS, GLONASS, Galileo, BeiDou, QZSS, NavIC, Multi-GNSS).
  • Includes a UART stream reader with a ring buffer and a built-in anti-spam packet filter.

https://github.com/octaprog7/light-nmea-micropython

You must be logged in to vote

Replies: 4 comments · 4 replies

Comment options

mattytrentini
Jul 9, 2026
Collaborator Sponsor

Roman, this looks excellent, well done!

As for running this in MicroPython, it's so very close to being even easier to use - you have a package.json but it installs differently to what's described in your README. Ideally we should be able to install and run the MicroPython example...but mip is installing it like so:

>docker run -ti --rm micropython/unix
MicroPython v1.28.0 on 2026-05-26; linux [GCC 12.2.0] version
Type "help()" for more information.
>>> import mip
>>> mip.install("github:octaprog7/light-nmea-micropython")
Installing github:octaprog7/light-nmea-micropython/package.json to /root/.micropython/lib
Copying: /root/.micropython/lib/light_nmea/__init__.py
Copying: /root/.micropython/lib/light_nmea/conv_to_hrf.py
Copying: /root/.micropython/lib/light_nmea/nmea0183_parser.py
Copying: /root/.micropython/lib/light_nmea/nmea0183_stats.py
Copying: /root/.micropython/lib/light_nmea/nmea0183_stream.py
Done
>>> from light_nmea import LightNMEA
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: no module named 'light_nmea.LightNMEA'

If you update your package.json it should be possible to make this work - and running tests on the unix port should also be just a small step away too.

You must be logged in to vote
1 reply
@octaprog7
Comment options

Hi Matt!

I have refactored the entire repository to use absolute imports and explicitly mapped the destination folders as lib/light_nmea/ inside package_json.

Please try reinstalling via mip!

Comment options

Run this command in your PC terminal to download the package straight to your connected device:

mpremote mip install github:octaprog7/light-nmea-micropython

Terminal Output:

Install github:octaprog7/light-nmea-micropython
Installing github:octaprog7/light-nmea-micropython/package.json to /lib
Installing: /lib/light_nmea/__init__.py
Installing: /lib/light_nmea/conv_to_hrf.py
Installing: /lib/light_nmea/nmea0183_parser.py
Installing: /lib/light_nmea/nmea0183_stats.py
Installing: /lib/light_nmea/nmea0183_stream.py
Done

Hardware Execution Test

To verify the installation, execute your test script on the hardware using mpremote exec:

mpremote exec "exec(open('test_light_nmea.py').read())"

Real Hardware Execution Log (ESP32):

Platform: esp32
Version: 3.4.0; MicroPython v1.26.0 on 2025-08-09

[1] Imports OK!
[2] Parsed RMC. Lat: 48.1173, Lon: 11.516666

[3] CSV Output:
1,0,48.1173,11.516666,41.4848,84.4,,12:35:19,23.03.2094,SBAS,RTK Fixed,

[4] TXT Output:
Fix: Yes
satellites: 0
latitude: 48.117300°
longitude: 11.516666°
speed: 41.5 km/h
course: 84.4°
time: 12:35:19 UTC
date: 23.03.2094
You must be logged in to vote
0 replies
Comment options

Verification Script (test_light_nmea.py)

You can use the following script to verify package functionality directly on your hardware. It tests component initialization, NMEA line parsing, and data formatting output:

import sys
from light_nmea import LightNMEA, to_format, FMT_CSV, FMT_TXT

# Print system specs
print(f"Platform: {sys.platform}")
print(f"Version: {sys.version}")

# 1. Verify top-level absolute package imports
print("\n[1] Imports OK!")

# 2. Initialize the pre-allocated parser
parser = LightNMEA()

# 3. Feed a raw byte sentence (RMC) into the parser loop
nmea_rmc = b"$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A"
parser.parse_line(nmea_rmc)

print(f"[2] Parsed RMC. Lat: {parser.latitude}, Lon: {parser.longitude}")

# 4. Verify formatting engine conversions (CSV and TXT layout)
csv_out = to_format(parser, FMT_CSV)
txt_out = to_format(parser, FMT_TXT)

print(f"\n[3] CSV Output:\n{csv_out}")
print(f"\n[4] TXT Output:\n{txt_out}")

print("\n[SUCCESS] All tests passed on hardware!")
You must be logged in to vote
3 replies
@mattytrentini
Comment options

mattytrentini Jul 13, 2026
Collaborator Sponsor

Installation looks resolved! However, that particular NMEA string returns False from parse_line. Is that expected?

MicroPython v1.28.0 on 2026-05-26; linux [GCC 12.2.0] version
Type "help()" for more information.
>>> import mip
>>> mip.install("github:octaprog7/light-nmea-micropython")
Installing github:octaprog7/light-nmea-micropython/package.json to /root/.micropython/lib
Copying: /root/.micropython/lib/light_nmea/__init__.py
Copying: /root/.micropython/lib/light_nmea/conv_to_hrf.py
Copying: /root/.micropython/lib/light_nmea/nmea0183_parser.py
Copying: /root/.micropython/lib/light_nmea/nmea0183_stats.py
Copying: /root/.micropython/lib/light_nmea/nmea0183_stream.py
Done
>>> from light_nmea import LightNMEA
>>> parser = LightNMEA()
>>> nmea_rmc = b"\$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A"
>>> parser.parse_line(nmea_rmc)
False

The output from subsequent methods (latitude, lognitude, to_format) look incorrect - eg None for lat/long.

@octaprog7
Comment options

Hi Matt!

An unnecessary backslash sneaked into my example code (\$ instead of $).

Because of that, the parser correctly identified it as an invalid NMEA sentence and rejected it. As you noticed, it safely leaves the coordinates as None and reports "No Fix", which prevents garbage data from corrupting the navigation state.

Here is the exact output with the leading backslash:

[2] Parsed RMC. Lat: None, Lon: None
[3] CSV Output:
0,0,,,,,,,,GPS,Unknown,
[4] TXT Output:
Fix: No
satellites: 0
@mattytrentini
Comment options

mattytrentini Jul 13, 2026
Collaborator Sponsor

That's got it! Sorry, I should have picked up on that.

Now I'll have to keep my eyes open for a GPS project. 😛

Comment options

@octaprog7 Some years ago I wrote an asynchronous GPS client which attempts to improve on the parsing efficiency of MicropyGPS but I think you've taken it further :)

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.