Strange QSerialport Problem



  • Hi,

    i want to write a small library to communicate with an external device using a virtual COM-Port.
    Open the port an sending data works fine and the device also sends a correct response with about 6ms delay (i can see it on Oscilloscope).

    However i can't read data using the asynchronous (non-blocking) approach.

    The Idea was that I send a command to the device and the using QTimer::singleShot to wait some time and call a Slot that reads the response. The Problem is that i get "QIODevice::read: device not open" error when trying to read data in my receiving-Slot but if i try to read in my sending-function there is no error.

    Here's the Code:

    @typedef struct{
    bool b_is_alive;
    bool b_is_setup;
    double f64_voltage;
    double f64_current;
    bool b_OutputIsOn;
    bool b_CurrentLimitActive;
    QString q_FailString;
    }ST_LPS_OUT;

    typedef struct{
    QString q_ComPortName;
    double f64_Voltage;
    double f64_CurrentLimit;
    bool b_EnableOutput;
    }ST_LPS_SETUP;

    class libZentroLPS358 : public QObject
    {
    Q_OBJECT
    public:
    explicit libZentroLPS358(QObject *parent = 0);
    public slots:
    void LPSsetup(ST_LPS_SETUP st_setup);
    void AwaitingResponse(void);
    signals:
    void LPSnewData(ST_LPS_OUT st_out);

    private:
    bool ConnectLPS(QString q_portname);
    QSerialPort* pq_comport;
    ST_LPS_SETUP st_setupold;
    ST_LPS_OUT st_out;
    };@

    @bool libZentroLPS358::ConnectLPS(QString q_portname)
    {
    bool b_ret;
    bool b_continue;
    float64 f64_wait_ms;
    QString q_response;
    uint8 au8_buffer[256];
    uint8 u8_errorcounter;

    //Create Comport instance
    //pq_comport->QSerialPort::~QSerialPort();
    pq_comport = new QSerialPort();
    QSerialPort* pq_comport = new QSerialPort(q_portname);
    b_ret = pq_comport->open( QIODevice::ReadWrite);
    if(!b_ret)
    {
        qDebug() << "failed to create com port instance";
        return true;
    }
    
    //Set up Comport
    pq_comport->setBaudRate(38400);
    pq_comport->setFlowControl(QSerialPort::HardwareControl);
    pq_comport->setDataBits(QSerialPort::Data8);
    pq_comport->setParity(QSerialPort::NoParity);
    pq_comport->setStopBits(QSerialPort::OneStop);
    
    //Ask Device to Identify itself
    pq_comport->setRequestToSend(true);
    pq_comport->write("*IDN?\r\n");
    b_ret = pq_comport->waitForBytesWritten(f64_wait_ms);
    
    QTimer::singleShot(50, this, SLOT(AwaitingResponse()));
    

    }

    void libZentroLPS358::AwaitingResponse(void)
    {
    pq_comport->waitForReadyRead(500);
    char buff[256];
    int i = pq_comport->read(buff,255);
    }@



  • Are you sure your QSerialPort object is alive and can be accessed when you try to access it from AwaitingResponse?



  • It should, i dont know why it should get closed within some ms. I moved the relevant code to as small new Project and get the same Error. Maybe you can compile and try it on your machine?

    Download:
    http://s000.tinyupload.com/?file_id=61057583527003946336

    Output on my PC looks like this:
    @-> MainWindow constructor
    -> ConnectLPS Slot
    INFO: setting up com port done
    INFO: Comport is still open
    INFO: sending *IDN? command
    INFO: Comport is still open
    INFO: transfer complete
    INFO: Comport is still open
    INFO: starting Timer
    -> AwaitingResponse Slot
    ERROR: Comport is not open!!!@

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    ui->textBrowser->append("-> MainWindow constructor");
    emit(ConnectLPS());
    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::ConnectLPS(void)
    {
    ui->textBrowser->append("-> ConnectLPS Slot");
    bool b_ret;
    float64 f64_wait_ms;

    pq_comport = new QSerialPort();
    QSerialPort* pq_comport = new QSerialPort("COM1");
    b_ret = pq_comport->open( QIODevice::ReadWrite);
    if(!b_ret)
    {
        ui->textBrowser->append("ERROR: failed to create com port instance");
        return;
    }
    
    //Set up Comport
    pq_comport->setBaudRate(38400);
    pq_comport->setFlowControl(QSerialPort::HardwareControl);
    pq_comport->setDataBits(QSerialPort::Data8);
    pq_comport->setParity(QSerialPort::NoParity);
    pq_comport->setStopBits(QSerialPort::OneStop);
    ui->textBrowser->append("INFO: setting up com port done");
    if(pq_comport->isOpen()) ui->textBrowser->append("INFO: Comport is still open");
    else ui->textBrowser->append("ERROR: Comport is not open!!!");
    
    //Ask Device to Identify itself
    pq_comport->setRequestToSend(true);
    pq_comport->write("*IDN?\r\n");
    ui->textBrowser->append("INFO: sending *IDN? command");
    if(pq_comport->isOpen()) ui->textBrowser->append("INFO: Comport is still open");
    else ui->textBrowser->append("ERROR: Comport is not open!!!");
    
    b_ret = pq_comport->waitForBytesWritten(f64_wait_ms);
    ui->textBrowser->append("INFO: transfer complete");
    if(pq_comport->isOpen()) ui->textBrowser->append("INFO: Comport is still open");
    else ui->textBrowser->append("ERROR: Comport is not open!!!");
    
    ui->textBrowser->append("INFO: starting Timer");
    QTimer::singleShot(200, this, SLOT(AwaitingResponse()));
    

    }

    void MainWindow::AwaitingResponse(void)
    {
    ui->textBrowser->append("-> AwaitingResponse Slot");
    if(pq_comport->isOpen()) ui->textBrowser->append("INFO: Comport is still open");
    else ui->textBrowser->append("ERROR: Comport is not open!!!");

    pq_comport->waitForReadyRead(500);
    char buff[256];
    int i = pq_comport->read(buff,255);
    

    }
    @



  • I'd try to move
    @ pq_comport = new QSerialPort();@

    to the constructor.



  • Ah, that the Mistake:
    @pq_comport = new QSerialPort();
    QSerialPort* pq_comport = new QSerialPort(q_portname);@
    i overwrite my global pq_comport with a local Object of the same name. I obviously forget to comment out or delete the "QSerialPort* pq_comport = new QSerialPort(q_portname);"

    Thank you


Log in to reply
 

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