本文介绍了通过Modbus TCP与CMMO-ST-C5-1-LKP Festo控制器进行Qt/C ++通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过Qt/C ++的Modbus与电机控制器通讯.

I am trying to commicate with a motor controller via modbus with Qt/C++.

我使用主要从Qt SerialBus adueditor示例获得的以下代码连接到该计算机:

I connect to it using this code that I took mainly from Qt SerialBus adueditor example:

    void Stepper::connect_device(){
    if (ui.pb_connect->text() == "Connect"){
    m_device = device;device->setParameters(0, 0x0000, 0x0000, 0x000F, 0x0000);
    m_device->setConnectionParameter(QModbusDevice::NetworkAddressParameter, ui.tcpAddressEdit->text());
    m_device->setConnectionParameter(QModbusDevice::NetworkPortParameter, ui.tcpPortEdit->text());
    m_device->setTimeout(1000);
    m_device->setNumberOfRetries(3);connect(m_device, &QModbusDevice::errorOccurred, this, [this](QModbusDevice::Error) {
        qDebug().noquote() << QStringLiteral("Error: %1").arg(m_device->errorString());
        reset();
        /*QMessageBox msgBox;
        msgBox.setWindowTitle("Modbus TCP Client");
        msgBox.setText("Connection error !");
        msgBox.exec();
        emit ui.pb_connect->clicked();*/
        return;
    }, Qt::QueuedConnection);

    connect(m_device, &QModbusDevice::stateChanged, [this](QModbusDevice::State state) {
        switch (state) {
        case QModbusDevice::UnconnectedState:
            qDebug().noquote() << QStringLiteral("State: Entered unconnected state.");
            ui.pb_connect->setEnabled(true);
            ui.pb_connect->setText("Connect");
            break;
        case QModbusDevice::ConnectingState:
            qDebug().noquote() << QStringLiteral("State: Entered connecting state.");
            ui.pb_connect->setEnabled(false);
            ui.pb_connect->setText("Trying to connect..");
            break;
        case QModbusDevice::ConnectedState:
            qDebug().noquote() << QStringLiteral("State: Entered connected state.");
            ui.pb_connect->setText("Disconnect");
            ui.pb_connect->setEnabled(true);
            break;
        case QModbusDevice::ClosingState:
            qDebug().noquote() << QStringLiteral("State: Entered closing state.");
            ui.pb_connect->setEnabled(true);
            ui.pb_connect->setText("Connect");
            break;
        case QModbusDevice::TimeoutError:
            qDebug().noquote() << QStringLiteral("State: Time out error.");
            QMessageBox msgBox;
            msgBox.setWindowTitle("Modbus TCP Client");
            msgBox.setText("Time out !");
            msgBox.exec();
        }
    });
    m_device->connectDevice();
}
else
{
    disconnectAndDelete();
}}

建立连接后,我使用此tcp pdu ="00000004084301000000000000"调试驱动器,调试了设备,由于通信中断,出现代码为"E047"的错误.问题是当我尝试进行重置(这是重置位的上升沿)时,我发送了这两个连续的帧,但是它不起作用,错误仍然存​​在.

Once the connection is established, I commission the drive using this tcp pdu = "00000004084301000000000000", the device is commissionned and an error with code "E047" occurs because the communication was interrupted. The problem is when I try to make a reset (which is a rising edge on the reset bit) I send these two consecutive frames, but it doesn't work, the error still remains.

void Stepper::reset(){
QModbusReply *reply = nullptr;
Data = "00000004084301000000000000";
QByteArray pduData = QByteArray::fromHex(Data.toLatin1());
reply = m_device->sendRawRequest(QModbusRequest(QModbusRequest::FunctionCode(0x0010), pduData), 0x01);

connect(reply, &QModbusReply::finished, [reply, this]() {
    qDebug() << "Receive: Asynchronous response PDU: " << reply->rawResult() << endl;
    Data = "00000004084B01000000000000";
    QByteArray pduData = QByteArray::fromHex(Data.toLatin1());
    QModbusReply *reply = nullptr;
    while (reply)
        reply = m_device >sendRawRequest(QModbusRequest(QModbusRequest::FunctionCode(0x0010), pduData), 0x01);
});}

我看了一下这个模拟器"Modbus TCP Client V1.0.0.12" Festo提供的https://www.festo.com/net/cs_cz/SupportPortal/default.aspx?q=modbus&tab=4 ,当我单击开始"按钮时,该帧将永久发送,然后可以单击复位位,从而消除了错误.仅当我单击停止"时,通信才会中断,并且会发生错误.通信运行时,我还可以执行其他操作,例如单击停止按钮或更改功能代码,是否使用多线程?在这种情况下,如何像该模拟器界面那样提供与控制器的持续通信?

I took a look at this simulator "Modbus TCP Client V1.0.0.12" https://www.festo.com/net/cs_cz/SupportPortal/default.aspx?q=modbus&tab=4 that festo offers,when I click "Start" button, the frame is sent permanently, then I can click on the reset bit and the error is eliminated. The communication is interrupted and the error occurs only when I click "Stop". When the communication is running I can do other things like clicking stop button or changing function code, is it using multithreading? In this case, how can I provide a continuous communication with the controller like this simulator interface?

单击此处查看modbus tcp模拟器图像

推荐答案

终于成功了,下面是代码:

It finally worked, here is the code:

void Stepper::reset(){
QTimer *timer1 = new QTimer(this);
timer1->setSingleShot(false);
timer1->start(100);
connect(timer1, &QTimer::timeout, [this]() {
    send_packet("00000004084301000000000000");
});
QTimer *timer2 = new QTimer(this);
timer2->setSingleShot(false);
timer2->start(100);
connect(timer2, &QTimer::timeout, [this]() {
send_packet("00000004084B01000000000000");
});}

send_packet函数就是这个函数:

The send_packet function is simply this function :

void Stepper::send_packet(QString Data){
QModbusReply *reply = nullptr;
QByteArray pduData = QByteArray::fromHex(Data.toLatin1());
reply = m_device->sendRawRequest(QModbusRequest(QModbusRequest::FunctionCode(0x0010), pduData), 0x01);
if (reply)
    return;}

这篇关于通过Modbus TCP与CMMO-ST-C5-1-LKP Festo控制器进行Qt/C ++通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 12:36
查看更多