Qt modbus通讯 client代码实现

Qt modbus通讯 client

  • 一、 代码
  • 二、qt自带例子参考

一、 代码

实测可用,记录一下

.h

#ifndef MODBUSTCPCLIENT_H
#define MODBUSTCPCLIENT_H

#include 
#include 
#include 
#include "qconfigbuilder.h"
QT_BEGIN_NAMESPACE

class QModbusClient;
class QModbusReply;


QT_END_NAMESPACE
class ModbusTcpClient : public QObject
{
    Q_OBJECT
public:
    explicit ModbusTcpClient(QObject *parent = nullptr);
    ~ModbusTcpClient();

    QString ip;//IP地址
    int port;//端口
    int networkstation=1;//站号
    bool isconnected=false;
    QList<quint16> m_holdingRegisters;

    void init();
    void initConfig();
    bool connectServer();
    bool disConnect();
    int responseTime=1000;//响应时间
    int numberOfRetries=3;//重连次数

    void onModbusStateChanged(int state);
    void  read(QModbusDataUnit::RegisterType type,int startaddr,int endaddr);
    void  write(QModbusDataUnit::RegisterType type,int startaddr,int endaddr,QList<quint16>&m_data);
    void onReadReady();
private:
    QModbusReply *lastRequest = nullptr;
    QModbusClient *modbusDevice = nullptr;
    QConfigBuilder* configBuilder;

signals:
    void sigErrorInfo(QString msg);
    void sigStateInfo(QString msg);
    void sigReadData(QModbusDataUnit unit);

};

#endif // MODBUSTCPCLIENT_H

.cpp

#include 
#include 
#include "modbustcpclient.h"

ModbusTcpClient::ModbusTcpClient(QObject *parent)
    : QObject{parent}{}

ModbusTcpClient::~ModbusTcpClient(){
    if (modbusDevice)
        modbusDevice->disconnectDevice();
    delete modbusDevice;
}
void ModbusTcpClient::init(){
    modbusDevice = new QModbusTcpClient(this);
    //================从配置文件中读取ip,port ,站号
    initConfig();
    connect(modbusDevice, &QModbusClient::errorOccurred, [this](QModbusDevice::Error) {
        emit sigErrorInfo(modbusDevice->errorString());
    });

    if (!modbusDevice) {
        emit sigErrorInfo("未能建立Modbus 客户端");
    } else {
        connect(modbusDevice, &QModbusClient::stateChanged,
                this, &ModbusTcpClient::onModbusStateChanged);//注册状态变化信号槽
    }
}

void ModbusTcpClient::initConfig(){
    //读取配置文件
    QString path = QCoreApplication::applicationDirPath()+"/config.ini";
    configBuilder=new QConfigBuilder(path);
    ip = configBuilder->getValue("ModbusTcpServer","IP").toString();
    port = configBuilder->getValue("ModbusTcpServer","Port").toUInt();
    delete configBuilder;
}

bool ModbusTcpClient::disConnect(){
    if (!modbusDevice)
        return false;
    modbusDevice->disconnectDevice();
    return true;
}

bool ModbusTcpClient::connectServer(){
    //    QThread::msleep(1000);
    if (!modbusDevice)
        return false;
    if (modbusDevice->state() != QModbusDevice::ConnectedState) {
        modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, port);
        modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, ip);
        modbusDevice->setTimeout(responseTime);
        modbusDevice->setNumberOfRetries(numberOfRetries);
        if (!modbusDevice->connectDevice()) {
            emit sigErrorInfo(tr("Connect failed: ") + modbusDevice->errorString());
            return false;
        } else {
            return true;
        }
    }else{
        return true;
    }
}

void ModbusTcpClient::onModbusStateChanged(int state)
{
    isconnected = (state != QModbusDevice::UnconnectedState);

    if (state == QModbusDevice::UnconnectedState)
        emit sigStateInfo("Modbus服务未连接");
    else if (state == QModbusDevice::ConnectedState)
        emit sigStateInfo("Modbus服务已连接");
}


void ModbusTcpClient::read(QModbusDataUnit::RegisterType type,int startaddr,int endaddr)
{
    if (!modbusDevice)
        return;
    quint16 numberOfEntries =quint16(endaddr - startaddr);// qMin(ui->readSize->currentText().toUShort(), quint16(endaddr - startaddr));
    QModbusDataUnit readrequest=   QModbusDataUnit(type, startaddr, numberOfEntries);

    if (auto *reply = modbusDevice->sendReadRequest(readrequest, networkstation)) {
        if (!reply->isFinished())
            connect(reply, &QModbusReply::finished, this, &ModbusTcpClient::onReadReady);
        else
            delete reply; // broadcast replies return immediately
    } else {
        emit sigErrorInfo(tr("读取错误: ") + modbusDevice->errorString());
    }
}

void ModbusTcpClient::onReadReady()
{
    auto reply = qobject_cast<QModbusReply *>(sender());
    if (!reply)
        return;

    if (reply->error() == QModbusDevice::NoError) {
        const QModbusDataUnit unit = reply->result();
        emit sigReadData(unit);

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

    reply->deleteLater();
}

void ModbusTcpClient::write(QModbusDataUnit::RegisterType type,int startaddr,int endaddr,QList<quint16>& m_data){
    quint16 numberOfEntries = quint16(endaddr - startaddr);
    QModbusDataUnit writeUnit= QModbusDataUnit(type, startaddr, numberOfEntries);
    for (qsizetype i = 0, total = writeUnit.valueCount(); i < total; ++i) {
        if (type == QModbusDataUnit::Coils)
            writeUnit.setValue(i, m_data[i]);
        else
            writeUnit.setValue(i, m_data[i]);
    }

    if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, networkstation)) {
        if (!reply->isFinished()) {
            connect(reply, &QModbusReply::finished, this, [this, reply]() {
                if (reply->error() == QModbusDevice::ProtocolError) {
                    emit sigErrorInfo(tr("Write response error: %1 (Modbus exception: 0x%2)")
                                      .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16));

                } else if (reply->error() != QModbusDevice::NoError) {
                    emit sigErrorInfo(tr("Write response error: %1 (Modbus exception: 0x%2)")
                                      .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16));
                }
                reply->deleteLater();
            });
        } else {
            // broadcast replies return immediately
            reply->deleteLater();
        }
    } else {
        emit sigErrorInfo(tr("Write error: ") + modbusDevice->errorString());
    }
}


二、qt自带例子参考

也可参照qt路径下自带的例子
Qt modbus通讯 client代码实现_第1张图片

你可能感兴趣的:(机器人,qt,开发语言)