C library for parsing NMEA-0183 sentences on embedded systems. Zero heap allocation, multi-instance contexts, compile-time module selection to minimize binary size.
Use this if you need to: parse GPS/GNSS, AIS, radar, navigation, or sensor data from NMEA-0183 devices on microcontrollers or resource-constrained systems.
Don't use this if: you need NMEA-2000, need dynamic configuration, or want automatic sentence type detection without compile-time configuration.
| What | Why |
|---|---|
| Zero heap allocation | All state in caller-provided context - predictable memory usage |
| Multi-instance support | Run multiple independent parsers for redundant sensors |
| Modular architecture | Enable only needed modules to minimize binary size |
| Compile-time configuration | Strip out unused sentence types before compilation |
| ~100+ sentence types | Comprehensive coverage - see supported-sentences.md |
| Static library | Link with CMake - no dynamic dependencies |
#include "nmea.h"
// 1. Create context and config
nmea_context_t ctx;
nmea_config_t config = {
.enabled_modules = (1 << NMEA_MODULE_GNSS) | (1 << NMEA_MODULE_SENSOR),
.error_callback = NULL,
.validate_checksums = true
};
// 2. Initialize
if (nmea_init(&ctx, &config) != NMEA_OK) {
return -1;
}
// 3. Parse sentence (requires working buffer)
const char *sentence = "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47\r\n";
char buffer[128]; // Min 82 bytes required
if (nmea_parse(&ctx, sentence, strlen(sentence), buffer, sizeof(buffer)) == NMEA_OK) {
// 4. Access parsed data
nmea_gnss_state_t gnss;
if (nmea_get_gnss_data(&ctx, &gnss) == NMEA_OK) {
printf("Lat: %.6f, Lon: %.6f\n", gnss.latitude.degrees, gnss.longitude.degrees);
}
}
// 5. Cleanup when done
nmea_cleanup(&ctx);Working examples demonstrating common integration scenarios:
Basic GPS tracking: position, speed, altitude, time.
- Data: Latitude, longitude, altitude, speed, course, UTC time/date, fix quality
- Memory: ~200 bytes RAM, ~6 KB flash
- Complexity: Beginner
nmea_parse(&ctx, sentence, len, buffer, buf_size);
nmea_gnss_state_t gps;
nmea_get_gnss_data(&ctx, &gps);
printf("Position: %.6f, %.6f\n", gps.latitude.degrees, gps.longitude.degrees);Legacy marine equipment integration: depth sounders, wind instruments, compass, speed logs, temperature sensors.
- Data: Water depth, wind speed/direction, heading, speed through water, ROT, water temperature
- Memory: ~600 bytes RAM, ~15 KB flash
- Complexity: Intermediate
nmea_sensor_state_t sensors;
nmea_get_sensor_data(&ctx, &sensors);
printf("Depth: %.1f m, Wind: %.1f knots\n",
sensors.depth_below_transducer_meters,
sensors.wind_speed_knots);UART/serial port integration for Linux/POSIX systems. Includes buffering, error recovery, and statistics.
- Complexity: Intermediate
Multiple independent parser contexts for redundant GPS systems or separate data streams.
- Complexity: Intermediate
Memory optimization for resource-constrained microcontrollers.
- Complexity: Intermediate
Error handling with callbacks, statistics, recovery strategies, and health monitoring.
- Complexity: Advanced
All examples include:
- Complete, buildable code
- Detailed documentation
- Real-world use cases
- Platform-specific notes
See examples/ for complete list and doc/ for integration guides.
mkdir build && cd build
cmake ..
make
make install # Installs to system or CMAKE_INSTALL_PREFIXLink against libnmea.a and include nmea.h.
Modules and sentences can be disabled at compile-time in inc/nmea_config.h:
// Disable entire modules
#define NMEA_MODULE_AIS_ENABLED 0
#define NMEA_MODULE_RADAR_ENABLED 0
// Disable specific sentences
#define NMEA_SENTENCE_GGA_ENABLED 1 // Keep GPS position
#define NMEA_SENTENCE_RMC_ENABLED 1 // Keep recommended minimum
#define NMEA_SENTENCE_GSV_ENABLED 0 // Don't need satellites in viewSee inc/nmea_config.h for all configuration options.
Each module groups related sentence types:
- GNSS - GPS/GLONASS/Galileo position, velocity, time, satellites (GGA, RMC, GLL, GSA, GSV, etc.)
- AIS - Automatic Identification System messages (VDM, VDO, ABM, BBM)
- Navigation - Cross-track error, waypoint arrival, bearing/distance to waypoint (APB, BOD, BWC, RMB, etc.)
- Heading - True/magnetic heading, attitude, rate of turn (HDT, HDG, ROT, etc.)
- Sensor - Depth, water temperature, wind, pressure (DBT, DPT, MTW, MWV, etc.)
- Radar - Radar status and targets (TTM, TLL, etc.)
- Safety - Alarms and safety-related messages (ALA, ALR, etc.)
- Comm - Communication state and DSC (DSC, DSE, etc.)
- System - System state and text messages (TXT, VER, etc.)
- Attitude - Pitch, roll, heave (HMR, HSS, etc.)
- Waypoint - Waypoint/route management (WPL, RTE, etc.)
- Misc - Everything else
Core functions:
nmea_init(ctx, config)- Initialize parser contextnmea_parse(ctx, sentence, len, buffer, buf_size)- Parse one sentencenmea_cleanup(ctx)- Reset contextnmea_get_gnss_data(ctx, out)- Retrieve parsed GNSS datanmea_get_ais_data(ctx, out)- Retrieve parsed AIS data- (similar accessors for other modules)
See inc/nmea.h for full API documentation.
cd build
ctestUnit tests are in test/unit/, built with Google Test.
Context size depends on enabled modules. Typical configurations:
- GNSS only: ~200 bytes
- GNSS + Sensor: ~300 bytes
- All modules: ~1-2 KB
Use nmea_get_context_size() to query actual size for your configuration.
Buffer requirement: 82 bytes minimum for working buffer (use nmea_get_required_buffer_size()).
All functions return nmea_result_t:
nmea_result_t result = nmea_parse(&ctx, sentence, len, buf, buf_size);
if (result != NMEA_OK) {
printf("Error: %s\n", nmea_get_error_string(result));
}Optional error callback for real-time notification:
void my_error_handler(nmea_error_type_t type, nmea_result_t code,
const char *message, void *user_data) {
fprintf(stderr, "NMEA error: %s\n", message ? message : nmea_get_error_string(code));
}
nmea_config_t config = {
.error_callback = my_error_handler,
.error_callback_user_data = NULL,
// ...
};Complete guides and references in the doc/ directory:
Getting Started:
- Integration Guide - Step-by-step setup for CMake, Makefile, Arduino, PlatformIO
- Serial Port Integration - UART/serial connection examples (STM32, ESP32, Linux, Arduino)
- FAQ - Common questions and troubleshooting
Advanced Topics:
- Stream Parsing - Buffering strategies for continuous data
- Memory Optimization - Minimize RAM/flash usage
- Error Handling - Error recovery patterns
Reference:
- Supported Sentences - Complete list of 100+ sentence types
- Documentation Index - Browse all documentation
Examples:
- GPS Tracker - Simple GPS position tracking
- Marine Instruments - Depth, wind, compass, temperature
- Serial Stream - Real serial port integration
- Multi-Instance - Multiple GPS devices
- Minimal Memory - Memory optimization
- Error Handling - Error handling patterns
- All Examples - Browse all examples
MIT License - See LICENSE
- Documentation: doc/ and examples/
- Issues: https://github.com/FinOrr/embedded-nmea-0183/issues
- Questions: Check FAQ first