This application uses the asio (asynchronous I/O) features in the Boost libraries along with the Boost serial_port implementation to read and display input from a serial port (e.g. GPS NMEA data). I also used experimental C++0x threading libraries and lambdas and tried the Boost implementation of the observer pattern - sockets and signals. I have yet to test this code on any other platform.
main.cpp
#include "headers.h" #include "SerialPort.h" using namespace std; using namespace boost::asio; int main() { //allow inter-mixing of wcout and cout calls (apparently non-standard) ios::sync_with_stdio(false); string portName = "/dev/ttyUSB1"; io_service ioService; io_service::work work(ioService); thread ioThread([&ioService] () { ioService.run(); }); SerialPort port(portName, 4800, ioService); port.LineReceived.connect([] (std::vector<char> const & line) { cout << &line[0] << endl; }); wcout << L"Listening on port: " << endl; cout << portName << endl; wcout << L"Press enter to stop listening..." << endl; wstring result; getline(wcin, result); wcout << L"Exiting..." << endl; ioService.stop(); ioThread.join(); }
headers.h
Separated for precompilation.#include <boost/asio.hpp> #include <boost/signal.hpp> #include <iostream> #include <vector> #include <thread> #include <functional>
SerialPort.h
#ifndef SERIALPORT_H #define SERIALPORT_H class SerialPort { public: SerialPort(std::string const & portName, int portSpeed, boost::asio::io_service & ioService); boost::signal<void(std::vector<char> const &)> LineReceived; private: void OnBytesRead(boost::system::error_code const &error, size_t bytesReceived); void BeginListening(); std::vector<char> _readBuffer; std::vector<char> _currentLine; boost::asio::serial_port _port; }; #endif // SERIALPORT_H
SerialPort.cpp
#include "headers.h" #include "SerialPort.h" using namespace std; using namespace boost::asio; SerialPort::SerialPort(string const & portName, int const portSpeed, io_service & ioService) : _readBuffer(1000), _port(ioService, portName) { _port.set_option(serial_port_base::baud_rate(portSpeed)); BeginListening(); } void SerialPort::BeginListening() { _port.async_read_some(buffer(&_readBuffer[0], _readBuffer.size()), [this](boost::system::error_code const &error, size_t bytesReceived) { this->OnBytesRead(error, bytesReceived); }); } void SerialPort::OnBytesRead(boost::system::error_code const &error, size_t bytesReceived) { if(error) { return; } for(size_t i = 0; i != bytesReceived; ++i) { char currentChar = _readBuffer[i]; switch(currentChar) { case '\r': break; case '\n': LineReceived(_currentLine); _currentLine.clear(); break; default: _currentLine.push_back(currentChar); } } BeginListening(); }
0 comments:
Post a Comment