QT技巧系列(9)QModbusTcpClient客户端程序示例及代码

QT技巧系列(9)QModbusTcpClient使用Modbus Tcp客户端程序示例及代码

 

 本文详细介绍了采用QModbusTcpClient类作为MODBUS客户端程序的主要流程和主要函数示例代码,供大家参考。

包含文件:

#include <QModbusDataUnit>

#include <QModbusTcpClient>

#include <QModbusRtuSerialMaster>

1、首先连接到服务端

构造函数中

  //QModbusClient *modbusDevice;

  modbusDevice = new QModbusTcpClient(this);

  connect(modbusDevice, &QModbusClient::stateChanged,

          this, &loraThread::onStateChanged);//连接状态发生改变时处理函数(connect or discennect

 

连接函数代码:

void loraThread::connectJzq()
{
    qDebug()<<"开始连接线程:"<<QThread::currentThread();  //显示当前线程的数值


    if(!modbusDevice)
    {
        return;
    }

    if(modbusDevice->state() != QModbusDevice::ConnectedState)
    {

        const QUrl url = QUrl::fromUserInput("192.168.2.111:502"); //;//获取IP和端口号
        modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, url.port());
        modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, url.host());

        modbusDevice->setTimeout(500);
        modbusDevice->setNumberOfRetries(3);

        if(!modbusDevice->connectDevice())//连接失败
        {
            isConnected = false;
        }
        else//成功连接
        {
            isConnected = true;
        }
    }
    else
    {
        isConnected = false;
        modbusDevice->disconnectDevice();
        //emit change2Con();
    }
    qDebug() << modbusDevice->state();

}

 2、发送读或写请求到服务端

 写请求代码:

给QModbusDataUnit赋值后发送写请求sendWriteRequest,写到相应寄存器中的相应位置,操作成功,没有发生错误的话sendWriteRequest将返回一个QModbusReply,否则返回空指针。当reply完成或放弃后reply->isFinished()将返回true。

void loraThread::on_writeTor(QString t)
{
    if (!modbusDevice)
        return;



    QModbusDataUnit writeUnit = QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 4, 2);
    for (uint i = 0; i < writeUnit.valueCount(); i++)
    {
        int ii = static_cast<int>(i);
        int j = 4*ii;
        QString st = t.mid (j,4);
        bool ok;
        int hex =st.toInt(&ok,16);//将读取到的数据转换为16进制发送
        quint16 qhex =static_cast<quint16>(hex);
       // qDebug()<<writeUnit.valueCount();
        writeUnit.setValue(ii,qhex);

    }

    if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, 1)) {//1->modbus 地址
        if (!reply->isFinished()) {
            connect(reply, &QModbusReply::finished, this, [this, reply]() {
                if (reply->error() == QModbusDevice::ProtocolError)
                {

                    emit statusBar(tr("Write response error: %1 (Mobus exception: 0x%2)")
                                                          .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16));
                } else if (reply->error() != QModbusDevice::NoError)
                {

                    emit statusBar(tr("Write response error: %1 (code: 0x%2)").
                                                  arg(reply->errorString()).arg(reply->error(), -1, 16));
                }
                reply->deleteLater();
            });
        } else {
            // broadcast replies return immediately
            reply->deleteLater();
        }
    } else {

        emit statusBar(tr("Write error: ") + modbusDevice->errorString());
    }

}

 

 

读请求代码:

发送sendReadRequest读请求,成功则异步函数回调处理读回的数据,错误则进行相应的处理。代码如下:

void loraThread::readDevice()
{

    if(!isConnected)return;
    if (!modbusDevice)
    {
        return;
    }

    qDebug()<<"read device";

    QModbusDataUnit readUnit = QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 520, 50);

    if (auto *reply = modbusDevice->sendReadRequest(readUnit, 1))   //1->modbus设备地址
    {
        if (!reply->isFinished())
        {
            connect(reply, &QModbusReply::finished, this, &loraThread::toReadReady);
        }
        else
        {
            delete reply; // broadcast replies return immediately
        }
    }
    else
    {
        //emit statusBar(tr("Read error: ") + modbusDevice->errorString());
    }


 
QThread::msleep(1);

}

读请求成功异步回调函数处理读回的数据,参考代码如下:

void loraThread::toReadReady()
{
//QModbusReply这个类存储了来自client的数据,sender()返回发送信号的对象的指针
    auto reply = qobject_cast<QModbusReply *>(sender());
    if (!reply)
    {
        return;
    }

    if (reply->error() == QModbusDevice::NoError)
    {
        //处理成功返回的数据
       const QModbusDataUnit unit = reply->result();
        //quint16 stat = unit.value(1);  //状态(位与关系)

       。。。。。。
 
    }
    else if (reply->error() == QModbusDevice::ProtocolError)
    {
       emit statusBar(tr("Read response error: %1 (Mobus exception: 0x%2)").
                      arg(reply->errorString()).
                       arg(reply->rawResult().exceptionCode(), -1, 16));

    }
    else
    {
       emit statusBar(tr("Read response error: %1 (code: 0x%2)").
                       arg(reply->errorString()).
                       arg(reply->error(), -1, 16));

    }

    reply->deleteLater();

}

状态变化处理代码:

void loraThread::onStateChanged(int state)//连接状态发生改变时处理函数(connect or discennect)

{

    if (state == QModbusDevice::UnconnectedState)
    {
        //ui->connectButton_2->setText(tr("Connect"));
        isConnected = false;
        //emit updateCount("0,0");

    }
    else if (state == QModbusDevice::ConnectedState)
    {
        //ui->connectButton_2->setText(tr("Disconnect"));
        isConnected = true;
    }
}

注:实战示例,解疑答惑。

           --不间端地思考,实时地批判你的工作!

发布了19 篇原创文章 · 获赞 6 · 访问量 1130

猜你喜欢

转载自blog.csdn.net/ydyuse/article/details/104533428