Serial programming 2 in Qt

Source: Internet
Author: User
 
Qt Serial Port [Overview] 

Qt Serial Port provides basic functionality including configuration, I/O operations, acquisition and Setup of RS-232 pins signals.

 

This module currently does not support the following features:
* Terminal features, such as ECHO and CR/LF Control
* Text mode
* Configure read operation timeout and latency
* Tracking and notification when the RS-232 pin signal changes
To use these classes in your own applications, you must include the following declaration:
# Include <QtSerialPort/QtSerialPort>
To connect to this module, add the following content to the. pro file:
QT + = serialport

Class]

This module includes two classes:
QSerialPort: Provides the function of accessing the serial port.
QSerialPortInfo: Provides information about serial ports in the system.

[QSerialPort]

This class provides the function of accessing the serial port. You can use the QSerialPortInfo help class to obtain information about available serial ports on the system and enumerate all serial ports on the system. You can use this class to obtain the correct serial port name. You can pass an object of this class as a parameter of the setPort () or setPortName () method to specify the serial device to be accessed.
After configuring the serial port, you can call the open () method to open the serial port in read-only or write-only or read-write mode.
Note: The serial ports are mutually exclusive, Which means we cannot open an opened serial port.
After it is successfully enabled, QSerialPort tries to obtain the current configuration of the serial port and initialize it. You can also use setBaudRate (), setDataBits (), setParity (), setStopBits ()

And setFlowControl () method to reconfigure it. The status of the control pin is determined by isDataTerminalReady (), isRequestToSend (), and pinoutSignals. To change the control information, use the following methods: setDataTerminalReady () and setRequestToSend ().

Once you know that the serial port can be used for reading or writing, you can call the read () or write () method. The readline () and readAll () methods are optional. If the data cannot be read at one time, the remaining data will be stored in the QSerialPort's internal buffer. You can use setReadBufferSize () to set the buffer size. You can use the close () method to disable the serial port and cancel the I/O operation.
Take a look at the following example:

int numRead = 0, numReadTotal = 0;char buffer[50];forever {    numRead  = serial.read(buffer, 50);    // Do whatever with the array    numReadTotal += numRead;    if (numRead == 0 && !serial.waitForReadyRead())        break;}

When the serial port connection is closed or an error occurs, waitForReadyRead () returns false.
Blocking serial programming is different from non-blocking serial programming. The blocked serial port does not require event loops and requires very little code. However, in a GUI application, congested serial port operations should be used only in non-GUI threads to avoid freezing the user interface. For more information, see the sample program.
The QSerialPort class can be used with stream operations of QTextStream and QDataStream (operator <() and operator> ()). Note one thing: Make sure that sufficient data is available before using the operator> ()'s overload function to read data.

[QSerialPortInfo]

Provides the existing serial port information in the system.
Use the static functions of this class to obtain a series of QSerialPortInfo objects. Each QSerialPort object in the list represents a separate serial port, which can be used to obtain the serial port name,

System Path, description, and manufacturer information. The QSerialPortInfo class can also be used as an input parameter for the setPort () method of the QSerialPort class.

[Example] [Example 1] shows the serial port information available on the system

Example 1 shows how to use the QSerialInfo class to obtain available serial ports on the system and display information of all serial ports:

[Source code]

#include <QTextStream>#include <QCoreApplication>#include <QtSerialPort/QSerialPortInfo>QT_USE_NAMESPACEint main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    QTextStream out(stdout);    QList<QSerialPortInfo> serialPortInfoList = QSerialPortInfo::availablePorts();    out << QObject::tr("Total number of ports available: ") << serialPortInfoList.count() << endl;    foreach (const QSerialPortInfo &serialPortInfo, serialPortInfoList) {        out << endl            << QObject::tr("Port: ") << serialPortInfo.portName() << endl            << QObject::tr("Location: ") << serialPortInfo.systemLocation() << endl            << QObject::tr("Description: ") << serialPortInfo.description() << endl            << QObject::tr("Manufacturer: ") << serialPortInfo.manufacturer() << endl            << QObject::tr("Vendor Identifier: ") << (serialPortInfo.hasVendorIdentifier() ? QByteArray::number(serialPortInfo.vendorIdentifier(), 16) : QByteArray()) << endl            << QObject::tr("Product Identifier: ") << (serialPortInfo.hasProductIdentifier() ? QByteArray::number(serialPortInfo.productIdentifier(), 16) : QByteArray()) << endl            << QObject::tr("Busy: ") << (serialPortInfo.isBusy() ? QObject::tr("Yes") : QObject::tr("No")) << endl;    }    return 0;}
[The running effect is as follows]

[Example 2]: display the available serial port information of the system-graphic interface version [Source Code ]:

#include <QApplication>#include <QWidget>#include <QVBoxLayout>#include <QLabel>#include <QtSerialPort/QSerialPortInfo>QT_USE_NAMESPACEint main(int argc, char *argv[]){    QApplication a(argc, argv);    QWidget w;    w.setWindowTitle(QObject::tr("Info about all available serial ports."));    QVBoxLayout *layout = new QVBoxLayout;    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {        QString s = QObject::tr("Port: ") + info.portName() + "\n"                    + QObject::tr("Location: ") + info.systemLocation() + "\n"                    + QObject::tr("Description: ") + info.description() + "\n"                    + QObject::tr("Manufacturer: ") + info.manufacturer() + "\n"                    + QObject::tr("Vendor Identifier: ") + (info.hasVendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : QString()) + "\n"                    + QObject::tr("Product Identifier: ") + (info.hasProductIdentifier() ?QString::number(info.productIdentifier(), 16) : QString()) + "\n"                    + QObject::tr("Busy: ") + (info.isBusy() ? QObject::tr("Yes") : QObject::tr("No")) + "\n";        QLabel *label = new QLabel(s);        layout->addWidget(label);    }    w.setLayout(layout);    w.show();    return a.exec();}
[The running result is as follows ]:

[Example 3]: main device of blocking Programming

This example shows how to use the QSerialPort synchronization API in a non-GUI thread.

QSerialPort supports two programming methods:

* Asynchronous (non-blocking) mode. When the control is returned to the Qt event loop, the corresponding operations are scheduled and executed. After the QSerial operation is completed, a signal is triggered. For example:

QSerialPort: write () method. When data is sent to the serial port, QSerialPort triggers bytesWirtten ().

* Synchronous (blocking) mode. In non-GUI and multi-threaded applications, we can call the waitFor... () function (for example, QSerialPort: waitForReadyRead () to block the call thread before it completes.

In this example, we will show how to use the synchronous method and how to use the Asynchronous Method in the Terminal example.

The purpose of this example is to show you a mode: simplify the code without making the UI unresponsive. The congested serial programming API in Qt can simplify the code, but because of its blocking feature, we must only use it in Non-GUI threads. However, unlike most people, using QThread does not make your application more complex.

This example is the main program, and there is a corresponding slave program example. The main program sends the request to the slave program through the serial port and waits for the response.

The following is the main thread class we have defined, which integrates the self-QThread:

[Source code]

class MasterThread : public QThread{    Q_OBJECTpublic:    MasterThread(QObject *parent = 0);    ~MasterThread();    void transaction(const QString &portName, int waitTimeout, const QString &request);    void run();signals:    void response(const QString &s);    void error(const QString &s);    void timeout(const QString &s);private:    QString portName;    QString request;    int waitTimeout;    QMutex mutex;    QWaitCondition cond;    bool quit;};

In the run function of a thread, data is written to the serial port. The Code is as follows:

// write request        QByteArray requestData = currentRequest.toLocal8Bit();        serial.write(requestData);        if (serial.waitForBytesWritten(waitTimeout)) {            // read response            if (serial.waitForReadyRead(currentWaitTimeout)) {                QByteArray responseData = serial.readAll();                while (serial.waitForReadyRead(10))                    responseData += serial.readAll();                QString response(responseData);                emit this->response(response);            } else {                emit timeout(tr("Wait read response timeout %1")                             .arg(QTime::currentTime().toString()));            }        } else {            emit timeout(tr("Wait write request timeout %1")                         .arg(QTime::currentTime().toString()));        }

[Example 4]: block-type programming as a slave device

The program is similar to the above, that is, the starting thread, the thread reads data from the serial port:

[Source code]

       if (serial.waitForReadyRead(currentWaitTimeout)) {//! [7] //! [8]            // read request            QByteArray requestData = serial.readAll();            while (serial.waitForReadyRead(10))                requestData += serial.readAll();//! [8] //! [10]            // write response            QByteArray responseData = currentRespone.toLocal8Bit();            serial.write(responseData);            if (serial.waitForBytesWritten(waitTimeout)) {                QString request(requestData);//! [12]                emit this->request(request);//! [10] //! [11] //! [12]            } else {                emit timeout(tr("Wait write response timeout %1")                             .arg(QTime::currentTime().toString()));            }//! [9] //! [11]        } else {            emit timeout(tr("Wait read request timeout %1")                         .arg(QTime::currentTime().toString()));        }
The running result is as follows ]:

[Example 5]: non-blocking Programming

The Terminal example shows how to use Qt Serial Port to create a simple Terminal.
This example shows the main features of the QSerialPort class, such as configuration and I/O implementation. In this example, the QSerialPortInfo class is also called to obtain available serial port information in the system.
QSerialPort supports two basic programming methods:
* Asynchronous (non-blocking) mode. When the control is returned to the Qt event loop, the operation can be scheduled and executed. When the operation is completed, QSerialPort will trigger a signal. For example, the QSerialPort: write () function will return immediately without blocking the write operation. When data is sent to the serial port, QSerialPort triggers the bytesWritten () signal.
* Synchronous (blocking) mode. In non-GUI and multi-threaded applications, you can call the waitFor... () function (for example, QSerialPort: waitForReadyRead () to suspend the call thread until the operation is completed.
This example shows the asynchronous programming method.
The example contains some GUI widgets:
Main Window: the Main Window of the application, including all the logic work of serial programming, including configuration, I/O processing, etc., inherited from QMainWindow.
Console: the central part of the main window, showing the sent and received data. This class inherits from the QPlainTextEdit class.
Set dialog window: the dialog box used to configure the serial port also displays information about the available serial ports on the system.

[Source code]

This program mainly shows the asynchronous operation method, that is, calling the write and read functions, and setting the corresponding slot functions.

After you click the connect menu, the following signal-slot connection will be triggered.

connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));

Input characters on the terminal will trigger the following signal-slot connection

connect(console, SIGNAL(getData(QByteArray)), this, SLOT(writeData(QByteArray)));

//! [6]void MainWindow::writeData(const QByteArray &data){    serial->write(data);}//! [6]//! [7]void MainWindow::readData(){    QByteArray data = serial->readAll();    console->putData(data);}//! [7]
[The running effect is as follows]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.