Qt Modbus通讯

此文章不赘述基础理论

1. pro文件

QT   += serialbus

2 .H

添加头文件

#include <QModbusRtuSerialMaster>

3.Cpp

    QModbusRtuSerialMaster *modbusMaster;

    modbusMaster = new QModbusRtuSerialMaster;

//    modbusMaster->setConnectionParameter(QModbusDevice::SerialPortNameParameter, "COM1");
    modbusMaster->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::NoParity);//奇偶校验
    modbusMaster->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, QSerialPort::Baud115200);
    modbusMaster->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
    modbusMaster->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);
    modbusMaster->setTimeout(30);//等待回应时间

函数setTimeout函数介绍

void QModbusClient::setTimeout(int newTimeout)

Sets the newTimeout for this QModbusClient instance. The minimum timeout is 10 ms.

The timeout is used by the client to determine how long it waits for a response from the server. If the response is not received within the required timeout, the TimeoutError is set.

Already active/running timeouts are not affected by such timeout duration changes.

Note: Setter function for property timeout.

See also timeout and timeoutChanged().

打开串口(自行删除闲于代码)

    //打开串口
    if(modbusMaster->state() != QModbusDevice::ConnectedState)
    {
        if(!modbusMaster->connectDevice())
        {
            qDebug() << "串口打开失败";
            Custom_warning::Display("串口打开失败!", Custom_warning::OK);
        }
        else
        {
            //判断是否连接有用 01 03 9C 40 00 0A EA 49
            QList<quint16> data;
            if(!Modbus_Read(modbus_rtc_parameter.slave_address, QModbusDataUnit::InputRegisters,
                           SYSTEM_DISPLAY_REGISTER_ADDRESSS, 1, data, 0))
            {
                Custom_warning::Display("对接失败,请检查串口和设备地址是否正确", Custom_warning::OK);
                modbusMaster->disconnectDevice();//关闭串口
                return;
            }

            Pushbutton_State_Enabel("打开");

            //打开modbus读取
            timer1->start();

            //打开成功记录一下串口名字
            software_flag.user_habit_portname = ui->comboBox_port_name->currentText();

            emit Control_State(true);
        }
    }
    else
    {
        timer1->stop();

        modbusMaster->disconnectDevice();
        Pushbutton_State_Enabel("关闭");

        software_flag.communication_state = "空闲";

        emit Control_State(false);
    }

关闭串口

    //关闭modbus串口
    if(modbusMaster->state() != QModbusDevice::UnconnectedState)
    {
        modbusMaster->disconnectDevice();
    }

读取函数

下面所有函数Custom_warning::Display都是我自定义的提示框,你们可以改变为QMessageBox就可以。

 读取实例

QList<quint16> data;
data.clear();  

#define LD_CURRENT_REGISTER_LEN                 (20)//读取长度
#define LD_CURRENT_REGISTER_ADDRESSS            (40400)//读取地址

if(Modbus_Read(modbus_rtc_parameter.slave_address, QModbusDataUnit::HoldingRegisters,
           SEEP_PULSE_WIDTH_REGISTER_ADDRESSS, SEEP_PULSE_WIDTH_REGISTER_LEN, data, true))
{
      //读取成功
}
/**
* @brief 读取modbus
* @param serverAddress,:丛机地址
* @param type:读取的寄存器类型,QModbusDataUnit::InputRegisters
* @param newStartAddress:读取寄存器的起始地址
* @param newValueCount:要读取的寄存器个数
* @param array:读取的数组
* @param warning:报警开关
* @retval 成功true,失败false
*/
bool Modbus_Read(int serverAddress, QModbusDataUnit::RegisterType type, int newStartAddress, quint16 newValueCount, QList<quint16> &array, bool warning)
{
    //保持寄存器,起始地址为0,读取的寄存器数量为1。
    QModbusDataUnit readUnit(type, newStartAddress, newValueCount);

    //发送读取请求并将请求的结果保存在reply指针中,最后面是地址
    QModbusReply *reply = modbusMaster->sendReadRequest(readUnit, serverAddress);


    if(reply == nullptr)
    {
        qDebug() << "客户端发出无效请求";
        return false;
    }

    //应答没有终止,就一直等待,终止返回true
    while (!reply->isFinished())
    {
        QCoreApplication::processEvents();
    }

    //检查是否有错误码
    if (reply->error() == QModbusDevice::NoError)
    {
         QModbusDataUnit resultUnit = reply->result();

         for (int i = 0; i < static_cast<int>(resultUnit.valueCount()); ++i)
             array.append(resultUnit.value(i));

         return true;
    }
    else
    {
        qDebug()<<  "reply " << reply->errorString() << "寄存器:" << newValueCount << newStartAddress;//打印错误码状态
        if(warning)
            Custom_warning::Display("数据读取失败", Custom_warning::OK);
        return false;
    }
}

写入函数

写入实例

    if(Modbus_Read(modbus_rtc_parameter.slave_address, QModbusDataUnit::HoldingRegisters,
                   40005, 1, data, 1))
    {
        //写入成功后函数
    }
/**
* @brief 写入modbus
* @param serverAddress,:丛机地址
* @param type:写入寄存器类型,QModbusDataUnit::InputRegisters
* @param newStartAddress:写入寄存器的起始地址
* @param newValueCount:要写入的寄存器个数
* @param array:写入的数组
* @param warning:报警开关
* @retval 成功true,失败false
*/
bool Modbus_Write(int serverAddress, QModbusDataUnit::RegisterType type, int newStartAddress, quint16 newValueCount, QList<quint16> array, bool warning)
{
    static int count = 0;
    QModbusDataUnit writeUnit(type, newStartAddress, newValueCount);

    for(int i = 0; i < newValueCount; i++)
        writeUnit.setValue(i, array.value(i));

    QModbusReply *reply = modbusMaster->sendWriteRequest(writeUnit, serverAddress);

    if(reply == nullptr)
    {
        qDebug() << "客户端发出无效请求";
        if(warning)
             Custom_warning::Display("数据写入失败", Custom_warning::OK);
        return false;
    }

    while (!reply->isFinished())
    {
        QCoreApplication::processEvents();
    }

    if (reply->error() == QModbusDevice::NoError)
    {
        qDebug()<< count++ << " 写入成功";
        return true;
    }
    else
    {
        qDebug()<< count++ << "写入失败reply  " + reply->errorString();
        if(warning)
            Custom_warning::Display("数据写入失败", Custom_warning::OK);

    }
    return false;
}

  3.3打印

/**
* @brief 十进制字符串打印
* @param datat 数据
* @param type quint16,数据类型
*/
QString Decimal_Printing(QList<quint16> datat, QString type)
{
    QString str = "str ";
    str.append(QString::number(datat.length()) + " = ");
    for(int i = 0; i < datat.length(); i++)
    {
        if(type == "quint16")
            str.append(QString::number(datat.value(i)) + " ");
        else if(type == "qint16")
            str.append(QString::number(static_cast<qint16>(datat.value(i))) + " ");
    }
    return str;
}


/**
* @brief 十六进制字符串打印
*/
QString Hex_Printing(QList<quint16> datat)
{
    uint8_t array_data[datat.length() * 2];
    uint8_t temp = 0;
    int count = 0;

    for(int i = 0; i < datat.length() * 2; i+=2)
    {
        array_data[i] = (datat.value(count) & 0xFF);
        array_data[i+1] = ((datat.value(count) >> 8) & 0xFF);
        count++;
    }


    for(int i = 0; i < datat.length() * 2; i+=2)
    {
        temp = 0;
        temp = array_data[i];
        array_data[i] = array_data[i+1];
        array_data[i+1] = temp;
    }

    QByteArray byte;
    byte.resize(datat.length() * 2);

    for(int i = 0; i < datat.length() * 2; i++)
        byte[i] = array_data[i];

    QString ret = "HEX ";
    ret.append(QString::number(datat.length() * 2) + " = ");
    for(int i = 0; i < byte.count(); i++)
        ret.append(QString("%1 ").arg((uchar)byte.at(i), 2, 16, (QChar)'0'));

    return ret.toUpper();
}

modbus通讯数据保存参数QT Modbus通讯数据获取-CSDN博客

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值