Posts Tagged ‘boost’

Qt and serial ports

April 23, 2010

Update Jun 22, 2011 : Fixed a bug for compiling under visual studio 2010.

This is intended to be a small add-on to the article I’ve posted on my website which explains how to use boost’s asio library to interface with serial ports from C++ code. This blog post focuses on a topic not covered in the article: using serial ports in Qt GUI applications.

Since serial ports are used primarily to interface a computer with a microcontroller, we’ll focus on this case.

The additional problem that occurs when the application has a GUI is the result of two restrictions that GUI applications have:

  • The thread that runs the GUI event loop should not block for long periods of time (say, more than a second). If this happens, the GUI “freezes” and this annoys users who think the application has crashed and usually force-quit it.
  • Code that updates the GUI should not be called from threads different from the main thread.

Now, if the microcontroller never sends data to the serial port unless the computer sends a command to it, and replies are always fast there is no problem.

Let’s show a basic protocol of this kind:

  • The PC can send the command “A” to the microcontroller.
  • If the microcontroller receives “A”, it reads an ADC channel and sends the value back to the PC

As said, in this case there is no problem. A possible GUI would have a button to read the value, and a label to show the result.

Such an application can easily use the TimeoutSerial class, with code to write the letter “A” in the callback of the button, immediately followed by a read from the serial port to get the result and show it on the GUI. The timeout, set to an appropriate value (such as 500ms) would ensure that the GUI won’t freeze even if something goes wrong, and the programmer can catch the TimeoutException to show an error message to the user.

But what to do if the command takes much time to complete, say 10 seconds? In this case this simple approach won’t work, because the GUI will freeze for ten seconds with the main thread waiting for the response from the serial port.

And what to do with a protocol like this?

  • The microcontroller sends the value read from the ADC 20 times a second.

In this case the PC application should always listen on the serial port for incoming data.

Well, who has read my article will probably think of using the AsyncSerial class, which allows to register a callback that will be called every time some data arrives from the serial port.

But also this approach won’t work, because of the constraint that the GUI code can be called only from the main thread, but AsyncSerial calls the callback from a separate thread.

To show how to solve this problem I’ve written a class, called QAsyncSerial which is a wrapper class for AsyncSerial that uses Qt’s system of signals and slots. It basically emits a signal every time a line is received from the serial port, and because signals and slots are thread safe, the code works as expected.

To show everything in practice, this is a simple GUI that uses QAsyncSerial running on Linux:

This simple GUI allows to select a serial port and open it (the baud rate is fixed to 115200, 8N1 format). Once it is opened, there is a line where to write text to send to the serial port while received text is showed below.

The code of the QAsyncSerial class and of the GUI example is posted at the end of the original article (here). It is meant to be compiled with QtCreator. If you try to compile it don’t forget to edit the line “-L/usr/local/lib” in the SerialGUI.pro file to point to where you have the boost libraries installed.

Last note, since the Qt libraries are cross platform, here’s the same application running on a Mac:

Serial ports and C++

September 14, 2009

Update Jun 22, 2011: Fixed a bug for compiling under visual studio 2010.

I’ve added a new article to my website. You can read it here. This article explains how to interface with serial ports from C++. Applications include communicating with an Arduino, the Fonera or any microcontroller. It presents four classes to access serial ports, starting from simple string read/write to advanced asyncronous I/O.

All the code is based on the Boost.asio library, so the code is portable across operating systems.

If you have comments, or find bugs, post them as comment to this blog post.

Measuring time durations

September 14, 2009

Today on the poul‘s mailing list someone asked: “How to measure the time spent in a function?”. I replied with the code that I use for that purpose, but later I thought that it was an interesting question, so I’m posting the solution here on the blog.

The solution is to use the boost date_time library. It is simple, portable (works on Linux, Win and Mac) and precise, since the time is printed in microseconds.

Here is an example code that shows how to profile a function:

#include <iostream>
#include <boost/date_time.hpp>

void f()
{
 for(volatile int i=0;i<100000;i++) ;
}

int main()
{
 using namespace std;
 using namespace boost::posix_time;

 ptime t1(microsec_clock::local_time());
 f();
 ptime t2(microsec_clock::local_time());

 cout<<t2-t1<<endl;
}

Just replace f() with the function you want to profile. Of course you can profile the time spent running your entire program by putting the whole program between the declaration of t1 and t2.

The time is printed in this format:

./test
00:00:00.000620

To be able to compile the program, you need to link with the boost_system library. With the g++ compiler you must add -lboost_system when linking.

Of course you need to have the boost libraries installed. On Linux type:

sudo apt-get install libboost-dev libboost-thread-dev

While on Windows, get this compiler that comes with boost precompiled.


Follow

Get every new post delivered to your Inbox.

Join 30 other followers