element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Embedded and Microcontrollers
  • Technologies
  • More
Embedded and Microcontrollers
Blog C++ library for ST Teseo GPS - pt. 6: running library built-in requests, and free conversations
  • Blog
  • Forum
  • Documents
  • Quiz
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Embedded and Microcontrollers to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 24 Jul 2024 10:45 PM Date Created
  • Views 312 views
  • Likes 6 likes
  • Comments 0 comments
  • Teseo
  • gps
  • OO
  • teseo_c++
Related
Recommended

C++ library for ST Teseo GPS - pt. 6: running library built-in requests, and free conversations

Jan Cumps
Jan Cumps
24 Jul 2024

The Teseo-LIV3 GPS module (as used in shabaz ' GPS / Galileo / BeiDou / GLONASS receiver) talks UART and I2C. I'm writing an OO driver for it, for embedded systems. In this blog, how to invoke commands and get data back:

  • an overview of the NMEA commands that the library understands
  • how to invoke any other command, using the library lower level methods.

image
image: online API documentation, used throughout this post

Built-in NMEA commands 

Commands that return a single reply

These single-reply commands are supported: GLL, RMC, GGA, VTG. You pass it a string object, that will be filled with the reply. The return value is a bool. True if the reply is complete and valid.

image

example:

std::string reply;
uint count; // intentionally uninitialised
bool valid; // intentionally uninitialised

valid = gps.ask_gll(reply);
printf("GLL valid: %s.\r\n", valid ? "yes" : "no");
printf(reply.c_str());

result:

GLL valid: yes.
$GPGLL,5051.77054,N,00422.57581,E,070917.000,A,A*5B

Commands that return multiple replies

These multi-line-reply commands are supported: GSV, GSA. You pass it a vector of string object, that will be filled with the replies. And an unsigned int that will get the number of replies. The return value is a bool. True if the reply is complete and valid.

image

example:

std::vector<std::string> replies(NMEA_MAX_REPLIES); 
uint count; // intentionally uninitialised
bool valid; // intentionally uninitialised

valid = gps.ask_gsa(replies, count);
printf("GSA valid: %s. count: %u.\r\n", valid ? "yes" : "no", count);
std::for_each(replies.begin(), replies.begin() + count, [](auto &s) { 
    printf(s.c_str()); });

result:

GSA valid: yes. count: 2.
$GNGSA,A,3,15,07,27,08,30,,,,,,,,2.0,1.3,1.5*25
$GNGSA,A,3,65,74,73,,,,,,,,,,2.0,1.3,1.5*2C

How to invoke other commands 

You're not restricted to the supported commands. The teseo class allows you to send anything your heart desires. And you choose what you do with the answer. Get it as a raw std::string, get it split and validated by the class methods, ignore it, ...

The first 3 options below make it easy to call the remaining commands, with fairly high level support. In the last option, you get real low access.

Commands that return a single reply

Define the command and validation strings. Then use the teseo::ask_nmea() method. It will interpret the  returned stream, validate it and hand over the response data.

image

example:

// execute a custom command that returns one line
teseo::nmea_rr pstcmu("$PSTMNMEAREQUEST,800000,0\n\r", "$PSTMNMEAREQUEST,800000,0");
valid = gps.ask_nmea(pstcmu, reply);
printf("PSTMCPU valid: %s.\r\n", valid ? "yes" : "no");
printf(reply.c_str());

result:

PSTMCPU valid: yes.
$PSTMCPU,51.49,-1,98*4A

Commands that return multiple replies

Define the command and validation strings. Then use the teseo::ask_nmea_multiple() method. It will interpret the  returned stream, validate it and hand over the response data. It also reports the number of replies that are retrieved

image

Example:
The Dump Almanac functionality that I use here as example is slow. The GPS has to retrieve this information from backup memory and isn't fast at that. It's not a command you'd usually call, but I needed a multiline command that I hadn't used yet.

teseo::nmea_rr almanac("$PSTMDUMPALMANAC\n\r", "$PSTMDUMPALMANAC");
valid = gps.ask_nmea_multiple(almanac, replies, count);
printf("DUMPALMANAC valid: %s. count: %u.\r\n", valid ? "yes" : "no", count);
std::for_each(replies.begin(), replies.begin() + count, [](auto &s) { 
    printf(s.c_str()); });

result:

DUMPALMANAC valid: yes. count: 3.
$PSTMALMANAC,90,40,5a1409000046554920580b00aa9d00008a8f0600523b2c00eec03400fd78020004000000cf400000*79
$PSTMALMANAC,91,40,5b1409000046754a175a1b00a264070061010c00cb2b080120c0340006da020004000000cf400000*71
$PSTMALMANAC,92,40,5c1409000046854c02ec220064af090066430a00f42b0801acbf3400eecc020004000000cf400000*25

Commands that don't return a reply

You just create a std::string with the command, and call teseo::read(string). Terminate the string with an "\r\n" sequence.
The teseo::init() method has a few examples.

If you use this method for a command that actually returns a reply, you may have to add logic to discard that data from your communication channel (if it's buffered). The easiest way is to do a read anyway and then ignore what's returned.
For commands that just echo a status line, it's easier to use 
teseo::ask_nmea().

Going full custom

If none of the above scenarios fit your needs, you can write your own conversations using teseo::write() and teseo::read(), and interpret the results yourself.

You can even get lower level. You are the one that's providing the reader and writer that the teseo object will use. You can customise that - or completely replace it by your own implementation.
And: the teseo object does not own the communication channel. Your program does. It initialises it, and gives the teseo object a reader and writer. You can completely bypass the object if it fits your needs, and send / read raw data via the UART or I2C port. The class won't stop you and does not care. It doesn't keep state.

Where does it stop? 

The class is not thread-safe. The underlying communication channel (the I2C or UART port that you control) is most likely not thread safe unless it's guarded. The GPS IC itself is not thread safe. If you use multi-threading or multitasking, guard the object just like you would protect a UART port. Reserve before a query and release when done.

Where next?

This library serves you NMEA formatted GPS data. You still need to get the information out of those NMEA response strings.
I created an MNEA parser library that works well with this Teseo driver (and with many other GPS APIs and brands): C++ parser library for NMEA GPS data - pt. 1: ideas, concepts, early design . 
That library will create C++ objects for the NMEA replies, The data is transformed into meaningful data types and structures. 

image

Next post:  C++ library for ST Teseo GPS - pt. 7: 1.0 release with NMEA parser - stable 

visit the github repository (git clone https://github.com/jancumps/pico_gps_teseo.git)
view the online documentation
Link to all posts.

  • Sign in to reply
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube