[SOLVED] How to work with the Serial Port in Qt



  • Hello

    I have problems with the Serial Port.

    First problem.
    I installed Virtual Serial Port driver. And I created pair COM1-COM2. But my application cannot open the port COM1. I receive this message: "The filename, directory name, or volume label syntax is incorrect"

    Second problem.
    Okay, the port isn't opened but when I check "m_port.isOpen()" is occur this error:

    http://i7.pixs.ru/storage/5/4/8/288png_1750629_13532548.png

    Third problem.
    When I close the window I receive the run time error.

    This is my code.
    I've written my own exception:
    PortError.h
    [CODE]
    #ifndef PORTERROR_H
    #define PORTERROR_H

    #include <stdexcept>
    #include <string>

    class PortError : public std::runtime_error
    {
    public:
    PortError( const std::string &errorText ) : std::runtime_error( "" )
    {
    m_message = "Error: " + errorText;
    }

    virtual ~PortError() throw()
    {
    
    }
    
    virtual const char *what() const throw()
    {
        return m_message.c_str();
    }
    
    std::string getMessage()
    {
        return m_message;
    }
    

    private:
    std::string m_message;
    };

    #endif // PORTERROR_H
    [/CODE]

    I use it like this:
    [CODE]
    void MainWindow::on_startTransmissionButton_clicked()
    {
    QString text = ui->valueForSendingLineEdit->text();
    QByteArray data;
    data.append( text );
    try {
    m_sender->send( data );
    } catch ( const PortError &e ) {
    QMessageBox::information( this, "Error", QString( e.what() ) );
    return;
    } catch ( ... ) {
    QMessageBox::information( this, "Error", "Error: unknown exception" );
    return;
    }
    }
    [/CODE]

    [CODE]
    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    try {
        m_sender = new Sender( "COM1" );
    } catch ( const PortError &e ) {
        QMessageBox::information( this, "Error", QString( e.what() ) );
    } catch ( ... ) {
        QMessageBox::information( this, "Error", "Error: unknown exception" );
    }
    

    }
    [/CODE]

    Sender.h
    [CODE]
    #ifndef SENDER_H
    #define SENDER_H

    #include <QSerialPort>
    #include <QString>
    #include "PortError.h"

    class Sender
    {
    public:
    Sender( const QString &portName,
    QSerialPort::BaudRate baudRate = QSerialPort::Baud9600,
    QSerialPort::DataBits dataBits = QSerialPort::Data8,
    QSerialPort::Parity parity = QSerialPort::NoParity,
    QSerialPort::StopBits stopBits = QSerialPort::OneStop,
    QSerialPort::FlowControl flowControl = QSerialPort::NoFlowControl );

    ~Sender();
    
    void send( const QByteArray &data ) throw( PortError );
    

    private:
    QSerialPort m_port;
    QString m_portName;
    QSerialPort::BaudRate m_baudRate;
    QSerialPort::DataBits m_dataBits;
    QSerialPort::Parity m_parity;
    QSerialPort::StopBits m_stopBits;
    QSerialPort::FlowControl m_flowControl;
    };

    #endif // SENDER_H
    [/CODE]

    Sender.cpp
    [CODE]
    #include "Sender.h"

    Sender::Sender(const QString &portName,
    QSerialPort::BaudRate baudRate,
    QSerialPort::DataBits dataBits,
    QSerialPort::Parity parity,
    QSerialPort::StopBits stopBits,
    QSerialPort::FlowControl flowControl ) :
    m_port( portName ),
    m_baudRate( baudRate ),
    m_dataBits( dataBits ),
    m_parity( parity ),
    m_stopBits( stopBits ),
    m_flowControl( flowControl )
    {
    // Set the port name
    m_port.setPortName( m_portName );

    // Open the port
    if ( !m_port.open( QIODevice::WriteOnly ) ) {
        throw PortError( m_port.errorString().toStdString() );
    }
    
    m_port.setBaudRate( m_baudRate );
    m_port.setDataBits( m_dataBits );
    m_port.setParity( m_parity );
    m_port.setStopBits( m_stopBits );
    m_port.setFlowControl( m_flowControl );
    

    }

    Sender::~Sender()
    {
    m_port.close();
    }

    void Sender::send( const QByteArray &data ) throw( PortError )
    {
    // Write data to the port
    if ( m_port.write( data ) == -1 ) {
    throw PortError( m_port.errorString().toStdString() );
    }
    }
    [/CODE]



  • I delete the m_sender object here:
    [CODE]
    MainWindow::~MainWindow()
    {
    delete ui;
    delete m_sender;
    }
    [/CODE]



  • The main problem: my application crash when I call .isOpen() Method. Why? Who can say the reason?

    [CODE]
    void Sender::send( const QByteArray &data ) throw( PortError )
    {
    if ( !m_port.isOpen() ) {
    throw PortError( m_port.errorString().toStdString() );
    }

    // Write data to the port
    if ( m_port.write( data ) == -1 ) {
        throw PortError( m_port.errorString().toStdString() );
    }
    

    }[/CODE]

    P.S. You see that it is very simple application


  • Lifetime Qt Champion

    Hi,

    Please run your application using a debugger, it will tell you exactly where the code is crashing



  • I've written. Here: "if ( !m_port.isOpen() )" in my last post. And I see this message:
    http://i6.pixs.ru/storage/4/6/9/288png_9391611_13540469.png


  • Lifetime Qt Champion

    Indeed, but running with the debugger, it will show you the stack trace and that would be more useful to help finding where the problem is.



  • I was helped here: [url]http://www.prog.org.ru/index.php?topic=27520[/url]

    The error on this line "m_port( portName ),"
    [CODE]
    Sender::Sender( const QString &portName,
    QSerialPort::BaudRate baudRate,
    QSerialPort::DataBits dataBits,
    QSerialPort::Parity parity,
    QSerialPort::StopBits stopBits,
    QSerialPort::FlowControl flowControl ) :
    m_port( portName ),
    m_baudRate( baudRate ),
    m_dataBits( dataBits ),
    m_parity( parity ),
    m_stopBits( stopBits ),
    m_flowControl( flowControl )
    {
    // Set the port name
    m_port.setPortName( m_portName );[/CODE]

    I should have written m_portName instead m_port.

    I replaced "QSerialPort m_port;" on "QSerialPort m_serialPort;" And I delete the m_portName because I can to write m_serialPort( portName ) in the "Sender" constructor.

    It is my project: [url]https://github.com/8Observer8/ComPort[/url]


  • Lifetime Qt Champion

    Since you are using exceptions, please take a look at the corresponding chapter in Qt's documentation.



  • Please, show me what do you mean? Cannot I use exceptions?


  • Lifetime Qt Champion

    Yes, you can, but there are some rules. Read "this":http://qt-project.org/doc/qt-5/exceptionsafety.html



  • Thank you very much! :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.