I just posted the first iteration of Serialzzz, a C++ library which provides asynchronous, event-driven I/O for interacting with UART devices on BeagleBone Black.
Today’s code drop is just the very first functional, initial pass – and is not production ready by any means! But it’s definitely enough to get you up
and running quickly… it is geared towards C++ Object Oriented
developers, who would otherwise struggle with the C I/O libraries
necessary to perform serial I/O. The library provides a SerialComm
object, which raises an event containing a message received on the UART.
To listen for the event, simply inherit from the SerialCommListener
class, and override the “handleMessage” method. SerialComm also provides
a method to write messages to the UART, and is thread-safe.
The next code drop will expose UART settings such as baud rate, width, parity, and stop bits. This initial pass is hard-coded to 9600 BAUD 8N1, though it is very simple to change.
You’ll find the source on github, here: https://github.com/zombiebabylabs/serialzzz.
Using it is pretty simple, here’s a quick example to get you started… first we create a class that extends zbl::SerialCommListener:
// ConsoleOutputListener.h #ifndef CONSOLEOUTPUTLISTENER_H_ #define CONSOLEOUTPUTLISTENER_H_ #include "serialzzz/SerialCommListener.h" class ConsoleOutputListener : public zbl::SerialCommListener { public: ConsoleOutputListener(); virtual ~ConsoleOutputListener(); // Override handleMessage, print message to standard out. virtual void handleMessage( const char * const message ); }; #endif /* CONSOLEOUTPUTLISTENER_H_ */
// ConsoleOutputListener.cpp #include "ConsoleOutputListener.h" #include <iostream> using namespace std; ConsoleOutputListener::ConsoleOutputListener() { } ConsoleOutputListener::~ConsoleOutputListener() { } void ConsoleOutputListener::handleMessage( const char * const message ) { cout << message << endl; } #endif /* CONSOLEOUTPUTLISTENER_H_ */
And then we define a quick main program, which will spend 5 minutes
listening on the serial port, displaying any incoming messages to the cout
stream.
// main.cpp #include <iostream> #include <unistd.h> #include "serialzzz/SerialComm.h" #include "serialzzz/SerialCommListener.h" #include "ConsoleOutputListener.h" using namespace zbl; using namespace std; int main() { SerialCommListener *listener = new ConsoleOutputListener(); SerialComm *comm = new SerialComm("/dev/ttyO1"); comm->registerSerialCommListener( listener ); comm->openPort(); sleep(300); comm->closePort(); delete comm; delete listener; return 0; }
Update I just added lambda support to Serialzzz, and you can now register callbacks for asynchronous message handling like so:
SerialComm *comm = new SerialComm("/dev/ttyO1"); comm->registerCallBack( [](const char * const msg) { cout << msg << endl; } );
registerCallBack accepts a function<void( const char * const )>
argument, and you can add as many as you need.
Both callbacks and listeners will be invoked, and I am leaving both in place for now, as I’m not convinced the SerialCommListener base class won’t be simpler for Java programmers adopting C++ on the BeagleBone. My preference is the callback, but I see value in both.