1 /// This example shows how to use Boost.ASIO in order to read synchronously
2 /// NMEA data from a serial port.
5 #include <boost/asio.hpp>
6 #include <marnav/io/default_nmea_reader.hpp>
7 #include <marnav/nmea/nmea.hpp>
8 #include <marnav/nmea/rmc.hpp>
9 #include <marnav/nmea/io.hpp>
11 namespace marnav_example
14 /// Synchronous reading of the serial port using Boost.ASIO
15 class boost_asio_serial
: public marnav::io::device
18 boost_asio_serial(const std::string
& port
)
22 serial
.set_option(boost::asio::serial_port_base::baud_rate(4800));
25 virtual void open() override
{}
27 virtual void close() override
{ serial
.close(); }
29 virtual int read(char * buffer
, uint32_t size
) override
31 if ((buffer
== nullptr) || (size
== 0))
32 throw std::invalid_argument
{"invalid buffer or size"};
33 if (!serial
.is_open())
34 throw std::runtime_error
{"device not open"};
36 return boost::asio::read(serial
, boost::asio::buffer(buffer
, size
));
39 virtual int write(const char *, uint32_t) override
41 throw std::runtime_error
{"operation not supported"};
45 boost::asio::io_service io
;
46 boost::asio::serial_port serial
;
49 /// This subclassing is not really necessary, but hides the instantiation
50 /// of boost_asio_serial from normal usage (see function 'main'). This way
51 /// it is completley transparent whether or not Boost.ASIO is in use or not
52 /// from the perspective of just using it.
53 class sentence_reader
: public marnav::io::default_nmea_reader
56 sentence_reader(const std::string
& port
)
57 : default_nmea_reader(std::unique_ptr
<marnav::io::device
>{new boost_asio_serial
{port
}})
63 int main(int, char **)
65 using namespace marnav
;
67 // create and open the device for reading.
68 marnav_example::sentence_reader reader
{"/dev/ttyUSB0"};
72 // read and process NMEA sentences, bus synchronization is done automatically.
73 while (reader
.read_sentence(data
)) {
74 // data was successfully read from the NMEA bus, inclusive synchronization
75 // of NMEA sentences. This means it is possible to begin to listen on the
77 auto sentence
= nmea::make_sentence(data
);
79 // do something with the sentence, for example dump the position
80 if (sentence
->id() == nmea::sentence_id::RMC
) {
81 auto rmc
= nmea::sentence_cast
<nmea::rmc
>(sentence
);
82 std::cout
<< "latitude : " << nmea::to_string(rmc
->get_latitude()) << "\n";
83 std::cout
<< "longitude: " << nmea::to_string(rmc
->get_longitude()) << "\n";