#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QModbusTcpClient>
#include <QModbusReply>
#include <QModbusDataUnit>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
QModbusTcpClient *My_client; //定义modbus连接客户端
/*****************************
*连接PLC设备,通过modbus协议
* 郝军方20210526
***************************/
void MainWindow::on_pushButtonConnect_clicked()
{
qDebug("connect");
QString ip=ui->lineEditIp->text();//从UI获取ip地址
QString port=ui->lineEditPort->text();//从UI获取端口信息
My_client=new QModbusTcpClient();//给连接实例化
My_client->setConnectionParameter(QModbusDevice::NetworkPortParameter,port);//配置连接端口
My_client->setConnectionParameter(QModbusDevice::NetworkAddressParameter,ip);//配置连接地址
My_client->setTimeout(3000);//配置超时3秒
My_client->setNumberOfRetries(3);//重复次数
if(My_client->connectDevice())//连接设备
{
ui->pushButtonConnect->setText("connected");
}
else {
ui->pushButtonConnect->setText("not connect");
}
qDebug()<<"连接状态:"<<My_client->state();//打印状态
}
/*****************
*
*断开连接,将通讯断开
*
* *****************/
void MainWindow::on_pushButtonDisconnect_clicked()
{
qDebug("disonnect");
QString ip=ui->lineEditIp->text();
QString port=ui->lineEditPort->text();
My_client->disconnectDevice();//断开设备
if(My_client->state()!=QModbusDevice::ConnectedState)
{
ui->pushButtonConnect->setText("connect");
}
else {
ui->pushButtonConnect->setText("not connect");
}
}
/***************************
*查看设备连接的状态
*
* ************************/
void MainWindow::on_pushButton_clicked()
{
int stutic=My_client->state();
QString s=QString("return:%d").arg(stutic);
QMessageBox::information(this,s,"stutic",QMessageBox::Ok,QMessageBox::NoButton);
}
/*********************
* 读取线圈数据
* ******************/
void MainWindow::on_pushButtonRead_clicked()
{
int tag=ui->lineEditTag->text().toInt();
QModbusDataUnit readUnit(QModbusDataUnit::Coils,tag,1);
if(auto *reply=My_client->sendReadRequest(readUnit,1))
{
if(!reply->isFinished())
{
connect(reply, &QModbusReply::finished,this,&MainWindow::readReady);
}
}
}
/*********************
* 获取到读取线圈的返回值
* 操函数,返回的数据
* ******************/
void MainWindow::readReady()
{
QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
if (!reply)
return;
qDebug("error:%d",reply->error());
if (reply->error() == QModbusDevice::NoError)
{
const QModbusDataUnit unit = reply->result();
// if(unit.startAddress()==30001){
bool res=unit.value(0);
qDebug("result:%d",res);
// QMessageBox::information(this,"return",QString(res),QMessageBox::Ok,QMessageBox::NoButton);
// }
QString r=QString::number(res);
ui->lineEditValue->setText(r);
}
else
{
}
reply->deleteLater(); // delete the reply
}
/**************************
* 写线圈数据
*
* ***********************/
void MainWindow::on_pushButtonWrite_clicked()
{
quint16 number1=static_cast<quint16>(1);//数据转化
int star_add=ui->lineEditTag->text().toInt();//ui获取写入地址
QModbusDataUnit writeUnit(QModbusDataUnit::Coils,star_add,number1);//写单元定义,线圈,首地址,数量
writeUnit.setValue(0,ui->lineEditValue->text().toInt());//设置写入单元的值
if(auto *reply=My_client->sendWriteRequest(writeUnit,1))//发送写入请求
{
if(!reply->isFinished())//请求结束
{
//连接操函数,匿名函数的写法
connect(reply, &QModbusReply::finished, this, [this, reply]() {
//协议错误
if (reply->error() == QModbusDevice::ProtocolError) {
qDebug() << (tr("Write response error: %1 (Mobus exception: 0x%2)")
.arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16),
5000);
//其他报错
} else if (reply->error() != QModbusDevice::NoError) {
qDebug()<< (tr("Write response error: %1 (code: 0x%2)").
arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
}
//返回对象删除
reply->deleteLater();
});
}
}
}
/***************************
*读取保存寄存器
*
* *************************/
void MainWindow::on_pushButton_readRegister_clicked()
{
qDebug()<<"进入"<<endl;
int star_add=ui->lineEditTag->text().toInt();//其实地址从ui获取
QModbusDataUnit ReadUnit(QModbusDataUnit::HoldingRegisters,star_add,1);//定义读取模块单元
qDebug()<<"寄存器进入"<<endl;
try {
if(!My_client)
return;
if(My_client->state()!=QModbusDevice::ConnectedState)
return;
if(auto *reply=My_client->sendReadRequest(ReadUnit,1))//发送读取到设备
{
if(!reply->isFinished())//读取结束
{
qDebug()<<"连接";
//消息调用读取寄存器槽函数
connect(reply,&QModbusReply::finished,this,&MainWindow::readRegister);
}
else
{
//清除内存
delete reply;
}
}
} catch (QString ex) {
qDebug()<<ex<<endl;
}
}
/***********************
*读取寄存器槽函数
*
* *********************/
void MainWindow::readRegister()
{
QModbusReply *replyer=qobject_cast<QModbusReply *>(sender());//将sender转化为modbus返回对象
if(!replyer)
{
return;
}
qDebug()<<replyer->error();//打印error数据
if(replyer->error()==QModbusDevice::NoError)//如果返回的error为no error时,需要将数据显示在ui
{
const QModbusDataUnit unit = replyer->result();
uint16_t res=unit.value(0);
qDebug()<<res<<endl;
QString r=QString::number(res);//数据转化为QString
ui->lineEditValue->setText(r);
}
else
{
qDebug()<< (tr("Write response error: %1 (code: 0x%2)").
arg(replyer->errorString()).arg(replyer->error(), -1, 16), 5000);
}
replyer->deleteLater();
}
/***************************
* 写存储寄存器槽函数
*
* *************************/
void MainWindow::on_pushButton_writeRegister_clicked()
{
qDebug()<<"准备写入holding寄存器数据 ";
int star_add=ui->lineEditTag->text().toInt();
int value=ui->lineEditValue->text().toInt();
QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters,star_add,1);//定义数据写入单元
// quint16 hex1=static_cast<quint16>(number);
writeUnit.setValue(0,value);//设置写入单元值
try {
if (auto *reply = My_client->sendWriteRequest(writeUnit, 1))
{// sendWriteRequest是向服务器写数据
if (!reply->isFinished()) { //reply Returns true when the reply has finished or was aborted.
//lambda表达式触发槽函数,
connect(reply, &QModbusReply::finished, this, [this, reply]() {
qDebug()<<"写入返回:"<<reply->error()<<endl;
qDebug()<<reply->result().values().first();
if (reply->error() == QModbusDevice::ProtocolError) {
qDebug() << (tr("Write response error: %1 (Mobus exception: 0x%2)")
.arg(rep
评论0