QModbusClient的链接与注意点

QModbusClient

以使用Modbus Tcp为例看看客户端怎么写程序

首先连接到服务端

QModbusTcpClient *client = new QModbusTcpClient();
client->setConnectionParameter(QModbusDevice::NetworkAddressParameter, "192.168.0.1");
client->setConnectionParameter(QModbusDevice::NetworkPortParameter, 502);
client->connectDevice();

这样就连接上服务端了,下面可以发送请求了

发送读或写请求到服务端

写请求

QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, 40003, 1); // write 1 value in address 40003
writeUnit.setValue(0, 0x253); 
//这里先建好QModbusDataUnit

if (auto *reply = client->sendWriteRequest(writeUnit, 1))
//发送写请求
{
    if (!reply->isFinished())
    {
        connect(reply, &QModbusReply::finished, this, [this, reply]() 
        {
            if (reply->error() != QModbusDevice::NoError)               
                    // error in reply

                reply->deleteLater();
            });
    }
    else
    {
        if (reply->error() != QModbusDevice::NoError)           
            // error in reply

        // broadcast replies return immediately
        reply->deleteLater();
    }
}
else
{
    // error in request
}

先建个QModbusDataUnit,下面是Qt帮助文档中的介绍

QModbusDataUnit is a container class representing single bit and 16 bit word entries in the Modbus register.QModbusDataUnit can be used for read and write operations

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

读请求

QModbusDataUnit readUnit(QModbusDataUnit::InputRegisters, 40006, 1); // just read input register 40006 

if (auto *reply = client->sendReadRequest(readUnit, 255)) // client id 255
{
    if (!reply->isFinished())
    {
        // connect the finished signal of the request to your read slot
        connect(reply, &QModbusReply::finished, this, &YourClass::readReady);
    }
    else
    {
        delete reply; // broadcast replies return immediately
    }
}
else
{
    // request error
}
YourClass::readReady
{
    QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
    if (!reply)
        return;

    if (reply->error() == QModbusDevice::NoError)
    {
        const QModbusDataUnit unit = reply->result();
        int startAddress = unit.startAddress(); // the start address, here 40006
        int value = unit.value(0); // value of the start address + 0
        ... 

    }
    else
    {
        // reply error
    }

    reply->deleteLater(); // delete the reply 
}

应该注意的问题
看看QModbusClient帮助文档中的一句话

QModbusClient has an asynchronous API. When the finished slot is called, the parameter it takes is the QModbusReply object containing the PDU as well as meta-data (Addressing, etc.).

这意味着

The API of the QModbusDevice classes are asynchronous. That means when you callclient->connectDevice() your client is not “really” connected to your server. The function just send an event to the event loop. When the application enters the event loop the event will be executed.The QModbusDevice class has some signals to control your connection state and error message.

所以我们应该

Check the client state with yout slot. Before reading registers ensure that the client is in connected state.

因此所有代码在一个函数中是不对的,像这样

YourClass::connect()
{
QModbusTcpClient *client=new QModbusTcpClient();
client->setConnectionParameter(QModbusDevice::NetworkAddressParameter,"192.168.0.201");
client->setConnectionParameter(QModbusDevice::NetworkPortParameter,502);
client->connectDevice();

QModbusDataUnit readUnit(QModbusDataUnit::Coils,00000,4);
if (auto *reply=client->sendReadRequest(readUnit,255)){

...
}

应该

MyClass::connectToModbusServer()
{
   QModbusTcpClient *client=new QModbusTcpClient();
   client->setConnectionParameter(QModbusDevice::NetworkAddressParameter,"192.168.0.201");
   client->setConnectionParameter(QModbusDevice::NetworkPortParameter,502);

   if (client->connectDevice())
   {
      connect(client, &QModbusTcpClient::stateChanged, this, &MyClass::onStateChanged); 
      connect(client, &QModbusTcpClient::errorOccurred, this, &MyClass::onErrorOccurred); 
   }
   else
      qDebug() << client->errorString();
}

MyClass::readCoil()
{
   QModbusDataUnit readUnit(QModbusDataUnit::Coils,00000,4);
}

原文链接:QModbusClient

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: qmodbusclient是一个用于Modbus通信的客户端库。Modbus是一种通信协议,用于连接各种设备,如传感器和执行器。qmodbusclient提供了一种方便的方式来与Modbus设备进行通信。 qmodbusclient具有以下主要特: 1. 支持主/从模式:qmodbusclient可以用作Modbus主站或从站。作为主站,可以发送请求命令并接收响应;作为从站,可以接收请求并发送响应。 2. 支持不同的传输方式:qmodbusclient支持串行传输和以太网传输。这意味着它可以与不同类型的设备进行通信,无论是通过串口连接还是通过网络连接。 3. 支持多种数据类型:qmodbusclient可以处理包括位(Coil)、字(Holding Register)、输入位(Input Coil)和输入字(Input Register)在内的不同类型的Modbus数据。 4. 提供易于使用的API:qmodbusclient的API设计简单明了,易于使用。它提供了一组函数来读取和写入Modbus数据,并提供了错误处理机制。 5. 支持异步操作:qmodbusclient支持异步操作,允许同时处理多个Modbus请求。这使得可以同时与多个设备进行通信,提高了通信效率。 总之,qmodbusclient是一个功能强大且易于使用的Modbus客户端库。它为开发人员提供了一种简便的方式来实现与Modbus设备的通信,并支持多种传输方式和数据类型。无论是从事Modbus通信的开发者还是终端用户,都可以从使用qmodbusclient中受益。 ### 回答2: qmodbusclient是一个开源的Modbus客户端库,用于与Modbus设备建立通信并进行数据传输。Modbus是一种常用的通信协议,用于在工业自动化系统中连接和控制设备。 qmodbusclient提供了一些实用的功能,如读取和写入Modbus设备的寄存器,发送和接收Modbus协议的原始数据包等。通过使用该库,开发人员可以轻松地与各种Modbus设备进行通信,并实现数据的读取和控制操作。 使用qmodbusclient需要先创建一个Modbus客户端对象,然后通过配置连接参数,如串口号、波特率等,建立与Modbus设备的连接。连接成功后,可以使用提供的函数进行数据的读取和写入操作。 例如,可以使用qmodbusclient提供的函数读取设备的输入寄存器,获取设备当前的状态数据。还可以使用写入功能,向设备的保持寄存器写入控制指令,实现对设备的远程控制。 qmodbusclient的使用还可以通过信号和槽机制来实现异步操作,如建立连接成功的信号、读写操作完成的信号等。 总之,qmodbusclient作为一个开源的Modbus客户端库,提供了丰富的功能和便捷的API,方便开发人员实现与Modbus设备的通信和控制。无论是在工业自动化领域还是其他领域,qmodbusclient都是一个强大且易用的工具。 ### 回答3: QModbusClient是一个用于Modbus通信协议的Qt库,它使开发人员可以在他们的Qt应用程序中实现Modbus客户端功能。 Modbus是一种通信协议,用于在工业自动化领域中连接和通信不同的设备。它允许设备之间以特定的格式交换数据,并使用不同的功能码来执行不同的操作,例如读取数据、写入数据等。 QModbusClient提供了一组易于使用的函数和类,以帮助开发人员轻松地实现Modbus客户端的功能。它允许开发人员创建一个与Modbus服务器进行通信的连接,读取和写入寄存器中的数据,并处理不同的Modbus异常。 使用QModbusClient,开发人员可以使用TCP或串行通信两种方式与Modbus服务器进行通信。在TCP通信中,开发人员需要指定服务器的IP地址和端口号,而在串行通信中,需要指定串行端口的名称和波特率等参数。 QModbusClient还提供了一些信号和槽机制,允许开发人员实时地监控和处理Modbus服务器发送的数据,以及处理与服务器之间的连接状态。这使得开发人员可以根据实际需求实现自己的逻辑和功能。 总之,QModbusClient是一个强大且易于使用的库,用于在Qt应用程序中实现Modbus客户端功能。它提供了丰富的功能和灵活性,使开发人员能够轻松地与Modbus服务器进行通信,并处理数据交换和连接状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值