A lightweight C++ library for communicating with u-blox ZED-F9 series GNSS modules on Linux systems, designed for headless environments where u-center is not available.
- Serial communication with u-blox GNSS modules
- UBX protocol message formatting and parsing
- Checksum calculation and validation
- ACK/NAK response handling
- Extensible message support system
- Header-only implementation for easy integration
Currently implemented messages:
- UBX-MON-VER - Retrieves software and hardware version information
- Linux-based operating system
- C++ compatible compiler
- Serial port access to u-blox device (typically
/dev/ttyACM0) - Proper permissions to access serial devices
- Clone the repository:
git clone <repository-url>
cd ublox-controller- Include the header in your project:
#include "lib/ublox_controller.h"- Compile your application with the necessary flags:
g++ your_application.cpp -o your_application#include "lib/ublox_controller.h"
int main() {
UbloxController controller("/dev/ttyACM0");
if (!controller.openSerialPort()) {
std::cerr << "Failed to open serial port" << std::endl;
return 1;
}
// Send a message with empty payload (poll request)
if (controller.sendUBXMessage(0x0A, 0x04, {})) {
std::vector<uint8_t> response;
if (controller.readUBXMessage(0x0A, 0x04, response)) {
// Process response
}
}
controller.closeSerialPort();
return 0;
}To add support for new UBX messages, create a new .cpp file following this format:
Use the format: UBX-{CLASS}-{ID}.cpp (e.g., UBX-CFG-PRT.cpp)
#include <iostream>
#include "lib/ublox_controller.h"
// UBX message definitions
#define UBX_CLS_EXAMPLE 0xXX // Replace with actual class
#define UBX_ID_EXAMPLE 0xXX // Replace with actual ID
using namespace std;
int main()
{
UbloxController controller;
if (!controller.openSerialPort()) {
cout << "Failed to open serial port" << endl;
return 1;
}
// Create payload if needed, or use empty vector for poll requests
vector<uint8_t> payload = {
// Add payload bytes here
};
cout << "Sending UBX message..." << endl;
if (!controller.sendUBXMessage(UBX_CLS_EXAMPLE, UBX_ID_EXAMPLE, payload)) {
cerr << "Failed to send message." << endl;
return 1;
}
// Wait for ACK/NAK if required
int ackResult = controller.waitForAck(UBX_CLS_EXAMPLE, UBX_ID_EXAMPLE);
if (ackResult != ACK) {
cerr << "Message not acknowledged" << endl;
return 1;
}
// Read response if expected
vector<uint8_t> response;
if (controller.readUBXMessage(UBX_CLS_EXAMPLE, UBX_ID_EXAMPLE, response)) {
// Parse response according to message specification
cout << "Response received successfully" << endl;
// Add your parsing logic here
}
controller.closeSerialPort();
return 0;
}I welcome contributions to expand the library's message support! To add a new UBX message:
- Study the message specification in the u-blox protocol documentation
- Create a new .cpp file following the naming convention above
- Implement the message using the provided template
- Test thoroughly with your hardware
- Submit a pull request with your implementation
- UBX class and message ID
- Payload structure (if any)
- Response format (if any)
- Any special handling requirements
The library provides several error codes:
ACK(1): Message acknowledgedNAK(0): Message not acknowledgedERROR_TIMEOUT(-1): Response timeoutERROR_CHECKSUM(-2): Checksum validation failedSOCK_NOT_OPEN(-3): Serial port not open
The library configures the serial port with these settings:
- Baud rate: 38400 (default for ZED-F9 modules)
- 8 data bits, no parity, 1 stop bit
- No flow control
- Raw mode (non-canonical)
- u-blox ZED-F9R Protocol Specification
- u-center Software (for testing and validation)
For issues and questions:
- Check the u-blox protocol documentation
- Review existing message implementations
- Create an issue in the GitHub repository
This library is not affiliated with or endorsed by u-blox. Always verify message formats and behaviors against the official u-blox protocol documentation.