Arduino + Qt with QextSerialPort

Last time I showed you a little play-around with Arduino and two servos.

Reminder: arduino-double-servo-sketch

Since my aim is to use it to control a webcam built on top of the two servos I have a program with a GUI that can do some image processing. I want to be able to control my “webcam-head” via the GUI so I need to send messages to the Arduino from my Qt (surprised?:D) application. I chose QextSerialPort because a friend of mine got nice experiences with it. I work with Ubuntu but it is also available on Windows systems.

Steps:

Get QextSerialPort library from here: QextSerialPort at google code
Compile it using Qt Creator so you will get libqextserial.so files (or dll-s on Windows).

The enumerator and listener examples are great so if you want something for a quick test, use them. If it compiles but you got runtime error messages like:

Starting /home/mzperx/projects/used/qextserial/qextserialport/examples/enumerator-build-desktop/enumerator…

~/projects/qextserial/qextserialport/examples/enumerator-build-desktop/enumerator: error while loading shared libraries: libqextserialport.so.1: cannot open shared object file: No such file or directory

Or libqextserialportd.so.1 (if you are compiling in Debug mode, the library files with “d” postfix will be used. To avoid this error you will have to move the library files to somewhere in your LD_LIBRARY_PATH: in my case it is /usr/lib/. I got the idea from this thread: qt-interest/2004-01/thread00713-0.html

Outcome:

The code on Arduino is the same as the last time, and the code I handle this from Qt is something like this:

void MainWindow::on_usbConnectBtn_clicked()
{
    if(port == 0 || (port != 0 && port->isOpen()))
    {
        port = new QextSerialPort("/dev/ttyUSB0", QextSerialPort::EventDriven);
        port->setBaudRate(BAUD9600);
        // check the baud rate on your Arduino since it has to be the same
        // as set with Serial.begin(...)
        port->setFlowControl(FLOW_OFF);
        port->setParity(PAR_NONE);
        port->setDataBits(DATA_8);
        port->setStopBits(STOP_2);

        if(port->open(QIODevice::ReadWrite) == true)
        {
            connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
            qDebug() << "listening for data on" <portName();
        }
        else
        {
            qDebug() << "device failed to open:" <errorString();
        }
    }
    else
    {
        port->close();
    }
}

void MainWindow::on_moveServoBtn_clicked()
{
    QByteArray bytes;
    bytes.append(QString::number(ui->servoChooserSpin->value()).toAscii())
            .append(QString::number(ui->angleChooserSpin->value()).toAscii());

    port->write(bytes);
    port->flush();
}

void MainWindow::onReadyRead()
{
    QByteArray bytes;
    int a = port->bytesAvailable();
    bytes.resize(a);
    port->read(bytes.data(), bytes.size());
    //qDebug() << "bytes read:" << bytes.size();

    bytesReceived.append(bytes);

    // only do input if all of it has been received.
    // without this the serial port transports line of messages
    // with only 3 or 4 bytes at a time
    if(bytes.contains('\n'))
    {
        qDebug() << QString::fromAscii(bytesReceived);
        bytesReceived.clear();
    }
}

Advertisements

16 thoughts on “Arduino + Qt with QextSerialPort

  1. that’s the simples tutorial about qt+arduino. But I figured half of it by myself. You can consider adding MainWindow.h and .pro files. Also a ui design screenshot would be great so people can see the object names. And there’s an undeclared identifier bytesReceived is it a Qstring or what??

    1. It was not my intention to release the full code, just wanted to give the reader the basic concepts.
      If you think I can attach a .zip of the whole project to the post.

  2. You used usb connection with qextserial? I want to do the same thing with an infeneon micro through usb , but i have read that qextserial lib is only for serial port not for usb…

  3. I use windows platform but when i run the example of qextserial port ,it can see only COM and PCI not USB… The infeneon micro that i use sends the data serial throw usb…. Can you advice me?

    1. Your device is on one of the COM ports. At least it should be if the driver is ok. I suggest you carefully read the documentation of your chip.

  4. Thanks for your help…. I finally can read data from my microcontroller!!! But now i can not write data. I have connected 2 windows xp pcs with a cable throw com1 port. I send data with this function:

    void MainWindow::sendData(){

    QByteArray bytes(“text”);
    char *k;
    k=bytes.data();
    qDebug()<isOpen()==true){//int j=bytes.size();
    port->write(k,4);
    }
    else{
    qDebug()<<"closed";
    }

    }

    but the teraterm that i use in the other pc , dont retrieve data….

    please help me!

    Thanks in advance

  5. hey mate I’ve installed qextserialport and all the examples are also working, but for some reason I am unable to control the arduino with my servos. I’ve tried to copy your code here on my qt, however I am getting an error that portName & errorString were not declared.
    C:\Qt_Programs\fleshmahcines\mainwindow.cpp:-1: In member function ‘void MainWindow::onReadyRead()’:
    C:\Qt_Programs\fleshmahcines\mainwindow.cpp:63: error: ‘bytesReceived’ was not declared in this scope
    C:\Qt_Programs\fleshmahcines\mainwindow.cpp:-1: In member function ‘void MainWindow::on_moveServoBtn_clicked()’:
    C:\Qt_Programs\fleshmahcines\mainwindow.cpp:48: error: ‘class Ui::MainWindow’ has no member named ‘servoChooserSpin’

    Can you please send me your code for this program. It’d be really helpful for me.

    1. Of course you are missing them since I only posted the piece of code that matters!

      Note that this project is more or less a year old and was in this beta state ever since. The code is not really well separated since it’s quite short.
      I suggest to look around the mainwindow.* files.
      One more thing: I’m working with Ubuntu so I’m not sure if this will work on Windows.

      http://buggers.svn.sourceforge.net/viewvc/buggers/magyarokamarson2012/used_stuff/usbservo-laserpointer-webcam/

  6. Dear Bmagyar could you please upload the main.cpp file of this QT project. I have problem is connect function. You have initialized the file pointer for “port” on in usbConnectBtn_clicked() function. But the “port” variable is not accessible from onReadyRead() why >??

  7. Before qextSerialPort, how did people writing Qt/pyQt applications access the serial port?

    Regarding your goal of controlling a webcam via an arduino, not exactly the same, but there’s a nice instructable on how to control an Arduino using a camera!
    http://www.instructables.com/id/How-to-Control-almost-anything-with-a-3D-camera-in/

    BTW, I understand you chose qt as the gui, but what are your thoughts on other GUIs and platforms? GTK+? Lego Mindstorms EV3? Matlab/Simulink + 3d Animation / Virtual Reality Toolboxes?

  8. Well, there not much magic to QExtSerialPort, it’s only a Qt-style abstraction layer on top of libusb.

    Your question related to the GUI is not really clear to me. The EV3 is the robot + the fancy IDE to develop things, matlab is a language for math, simulink is a simulator, and virtual reality toolboxes are a big overpowered solutions for my needs of being able to click 2 buttons to move a servo 🙂

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s