XIAOJIASONG
XIAOJIASONG
采纳率0%
2019-01-30 18:00

QT 中Modbus主机和下位机不能通信,不能下发数据,不能读取数据,拜托各位大神帮忙解决一下。

10

1.使用USB转串口测试了一下上位机中Modbus协议那部分程序,上位机机与下位机不能通信,不能下发数据,也不能读取数据。主机执行connectDevice()函数后,
APF_ModbusData->ModbusMaster->state() == QModbusDevice::ConnectedState成立,执行sendReadRequest()后,返回的指针对象调用error()函数后也没有错误。按理说state()返回值等于
QModbusDevice::ConnectedState表示Modbus网络应该已经连接上了,而且error()返回值也没错,但是为什么不能下发数据和读取数据呢?程序能正常执行,但是读取数据时,发送请求和读取数都不成功。
下面是我的代码,看Modbus线程中遥测部分的程序即可

2.Modbus处理数据的线程程序

#include "ModbusDataThread.h"
#include "GUIDataThread.h"
#include
#include

int DataMode = 2; //数据处理模式选择  1.遥调;2.遥测;3.遥信;
extern QMutex Mutex;

void ModbusDataThread::run()
{

APF_ModbusData = new ModbusData;

while(true)
{

    if(  APF_ModbusData->ModbusMaster->state() != QModbusDevice::ConnectedState)
    {
        int state1 = APF_ModbusData->ModbusMaster->state();
        qDebug() << "state1" << state1;
        APF_ModbusData->Modbus_Connection();
        msleep(2000);
    }

    if( APF_ModbusData->ModbusMaster->state() == QModbusDevice::ConnectedState )
    {

        int state3 = APF_ModbusData->ModbusMaster->state();
        qDebug() << "state3" << state3;
        qDebug() << "通信成功";

        while(true)
        {
            if( DataMode == 1 )                             //Modbus处理遥调数据
            {
                Mutex.lock();
                APF_ModbusData->RemoAdjust_DataTrans_Modbus();
                APF_ModbusData->Modbus_ReadWriteDatas_RemoAdjust(1);
                RemoAdjust_GUI = RemoAdjust_Modbus;
                //qDebug() << RemoAdjust_GUI;
                DataMode = 2;
                Mutex.unlock();
                msleep(2000);
            }

            if( DataMode == 2 )                           //Modbus处理遥测数据
            {
                Mutex.lock();
                qDebug() << "遥测";
                APF_ModbusData->Modbus_ReadDatas_RemoMea(1);
                RemoMea_GUI = RemoMea_Modbus;
                DataMode = 3;
                Mutex.unlock();
                msleep(2000);
            }

            if( DataMode == 3 )                           //Modbus处理遥信数据
            {
                Mutex.lock();
                qDebug() << "Modbus";
                qDebug() << "遥信";
                APF_ModbusData->Modbus_ReadDatas_RemoSignal(1);
                RemoSignal_GUI = RemoSignal_Modbus;
                DataMode = 2;
                Mutex.unlock();
                msleep(2000);
            }
        }
    }
}

delete APF_ModbusData->ModbusMaster;

}

3.设置串口参数和连接程序APF_ModbusData->Modbus_Connection();


void ModbusData::Modbus_Connection()
{
if (!ModbusMaster)
return;
QString portname = "/dev/ttyUSB0";
ModbusMaster->setConnectionParameter(QModbusDevice::SerialPortNameParameter,portname);
ModbusMaster->setConnectionParameter(QModbusDevice::SerialParityParameter,QSerialPort::NoParity);
ModbusMaster->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,QSerialPort::Baud9600);
ModbusMaster->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,QSerialPort::Data8);
ModbusMaster->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,QSerialPort::OneStop);

ModbusMaster->setTimeout(1000);
ModbusMaster->setNumberOfRetries(3);
ModbusMaster->connectDevice();

}

4.APF_ModbusData->Modbus_ReadDatas_RemoMea() ,此为遥测发送请求和读取数据的函数


void ModbusData::Modbus_ReadDatas_RemoMea(int serverAddress)
{
if (!ModbusMaster)
return;
QModbusDataUnit readRequest_RemoMea(QModbusDataUnit::InputRegisters,1,100);
if ( auto *Reply = ModbusMaster->sendReadRequest( readRequest_RemoMea, serverAddress))
{

    quint16 error_RemoMea = Reply->error();
    qDebug() << "error_RemoMea" << error_RemoMea;

    if ( !Reply->isFinished() )
    {
        bool a =  connect(Reply, &QModbusReply::finished, this, &ModbusData:: ReadReady_RemoMea);
        qDebug() << a;
    }
    else
    {
        delete Reply;
    }
}
else
{
    qDebug() << "request error";
}

}

5.插槽函数ReadReady_RemoMea()为函数Modbus_ReadDatas_RemoMea()中
connect(Reply, &QModbusReply::finished, this, &ModbusData:: ReadReady_RemoMea);关联的插槽函数。


void ModbusData::ReadReady_RemoMea()
{
QModbusReply *reply = qobject_cast(sender());

if (!reply)
    return;
if (reply->error() == QModbusDevice::NoError)
{
    RemoMea_Modbus = reply->result().values();             //返回读取的遥测数据
}
else
{
    qDebug() << "reply error";
}

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

}

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

相关推荐