QModbusDevice connect/disconnect



  • Hello everyone,

    I'm useing the QModbusDevice class to exchange data over a serial bus with an external device.

    So far everything works fine, but the programm needs to be as fool proof as possible, so I need to catch wrong parameters, reconnects, etc.

    When I call void QModbusDevice::disconnectDevice(), the state QModbusClient does not change from QModbusDevice::ClosingState to QModbusDevice::UnconnectedState and therefore does not accept new parameters and does not allow a reconnect.

    I was able to circumvent this by re-initializating the QModbusClient. But there has to be a better way.

    The question:
    What is the right way to disconnect a QModbusClient?

    Here, the 2 functions I wrote, that handle the Connect/Disconnet:

    void Modbus::connectDevice(bool connect)
    {
        qDebug() << "connectDevice" << connect << mDevice->state();
    
        if(connect){
            switch (mDevice->state()) {
            
            case QModbusDevice::ClosingState:
            case QModbusDevice::ConnectedState:
            case QModbusDevice::ConnectingState:
                mDevice->deleteLater();
                mDevice = new QModbusRtuSerialMaster(this);
                setupSignalSlots();
                QTimer::singleShot(100,this, [=]{setConnectParamter(m_port,m_paramter);});
                break;
            
            case QModbusDevice::UnconnectedState:
            default:
                if(!mDevice->connectDevice()){
                    emit signalModbusError("Verbindungsfehler: "+mDevice->errorString());
                    mDevice->disconnectDevice();
                }
                break;
            }
        }else{
            mDevice->disconnectDevice();
        }
    }
    
    void Modbus::setConnectParamter(QString port, QList<int> Paramter)
    {
        qDebug() << "setConnectParamter" << port << Paramter;
        if(!mDevice){
            qDebug() << "Error setConnectParamter";
            emit signalModbusError("Modbus not initialised!");
            return;
        }
        if(Paramter.size() >= 7){
            m_paramter = Paramter; m_port = port;
            mDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,port);
            mDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, Paramter[0]);
            mDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,Paramter[1]);
            mDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,Paramter[2]);
            mDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,Paramter[3]);
            mDevice->setTimeout(Paramter[4]);
            mDevice->setNumberOfRetries(Paramter[5]);
            deviceID = Paramter[6];
            connectDevice(true);
        }else{
            qDebug() << " Error setConnectParamter, Parameter mismatch";
        }
    }
    


  • Excuse , do you have the answer to this question? I encountered the same problem.



  • @tangxinzhou I'm afraid I do not have a solid solutions. I'm running a workaround now.

    Let me post it for you:

    void connectDevice(bool connect)
    {
        if(connect){
            switch (mDevice->state()) {
    
            case QModbusDevice::ClosingState:
            case QModbusDevice::ConnectedState:
            case QModbusDevice::ConnectingState:
                mDevice->deleteLater();
                mDevice = new QModbusRtuSerialMaster(this);
                setupSignalSlots();
                QTimer::singleShot(100,this, [=]{setConnectParamter(m_port,m_paramter);});
                break;
    
            case QModbusDevice::UnconnectedState:
            default:
                if(!mDevice->connectDevice()){
                    emit signalModbusError(mDevice->errorString());
                    mDevice->disconnectDevice();
                }
                break;
            }
        }else{
            stopPoll();
            mDevice->disconnectDevice();
            QTimer::singleShot(200,this,[=]{checkDisconnected();});
        }
    }
    
    void checkDisconnected()
    {
        if(mDevice->state() != QModbusDevice::UnconnectedState){
            mDevice->deleteLater();
            mDevice = new QModbusRtuSerialMaster(this);
            setupSignalSlots();
        }
    }
    

Log in to reply
 

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