commit
d63d454cc5
8 changed files with 860 additions and 0 deletions
@ -0,0 +1,73 @@ |
|||
# This file is used to ignore files which are generated |
|||
# ---------------------------------------------------------------------------- |
|||
|
|||
*~ |
|||
*.autosave |
|||
*.a |
|||
*.core |
|||
*.moc |
|||
*.o |
|||
*.obj |
|||
*.orig |
|||
*.rej |
|||
*.so |
|||
*.so.* |
|||
*_pch.h.cpp |
|||
*_resource.rc |
|||
*.qm |
|||
.#* |
|||
*.*# |
|||
core |
|||
!core/ |
|||
tags |
|||
.DS_Store |
|||
.directory |
|||
*.debug |
|||
Makefile* |
|||
*.prl |
|||
*.app |
|||
moc_*.cpp |
|||
ui_*.h |
|||
qrc_*.cpp |
|||
Thumbs.db |
|||
*.res |
|||
*.rc |
|||
/.qmake.cache |
|||
/.qmake.stash |
|||
|
|||
# qtcreator generated files |
|||
*.pro.user* |
|||
|
|||
# xemacs temporary files |
|||
*.flc |
|||
|
|||
# Vim temporary files |
|||
.*.swp |
|||
|
|||
# Visual Studio generated files |
|||
*.ib_pdb_index |
|||
*.idb |
|||
*.ilk |
|||
*.pdb |
|||
*.sln |
|||
*.suo |
|||
*.vcproj |
|||
*vcproj.*.*.user |
|||
*.ncb |
|||
*.sdf |
|||
*.opensdf |
|||
*.vcxproj |
|||
*vcxproj.* |
|||
|
|||
# MinGW generated files |
|||
*.Debug |
|||
*.Release |
|||
|
|||
# Python byte code |
|||
*.pyc |
|||
|
|||
# Binaries |
|||
# -------- |
|||
*.dll |
|||
*.exe |
|||
|
@ -0,0 +1,33 @@ |
|||
QT += core gui serialbus |
|||
|
|||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets |
|||
|
|||
CONFIG += c++11 |
|||
|
|||
# The following define makes your compiler emit warnings if you use |
|||
# any Qt feature that has been marked deprecated (the exact warnings |
|||
# depend on your compiler). Please consult the documentation of the |
|||
# deprecated API in order to know how to port your code away from it. |
|||
DEFINES += QT_DEPRECATED_WARNINGS |
|||
|
|||
# You can also make your code fail to compile if it uses deprecated APIs. |
|||
# In order to do so, uncomment the following line. |
|||
# You can also select to disable deprecated APIs only up to a certain version of Qt. |
|||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 |
|||
|
|||
SOURCES += \ |
|||
main.cpp \ |
|||
mainwindow.cpp \ |
|||
mymodbustcp.cpp |
|||
|
|||
HEADERS += \ |
|||
mainwindow.h \ |
|||
mymodbustcp.h |
|||
|
|||
FORMS += \ |
|||
mainwindow.ui |
|||
|
|||
# Default rules for deployment. |
|||
qnx: target.path = /tmp/$${TARGET}/bin |
|||
else: unix:!android: target.path = /opt/$${TARGET}/bin |
|||
!isEmpty(target.path): INSTALLS += target |
@ -0,0 +1,11 @@ |
|||
#include "mainwindow.h" |
|||
|
|||
#include <QApplication> |
|||
|
|||
int main(int argc, char *argv[]) |
|||
{ |
|||
QApplication a(argc, argv); |
|||
MainWindow w; |
|||
w.show(); |
|||
return a.exec(); |
|||
} |
@ -0,0 +1,65 @@ |
|||
#include "mainwindow.h" |
|||
#include "ui_mainwindow.h" |
|||
|
|||
MainWindow::MainWindow(QWidget *parent) |
|||
: QMainWindow(parent) |
|||
, ui(new Ui::MainWindow) |
|||
{ |
|||
ui->setupUi(this); |
|||
modbusTcpClient = new MyModbusTcp(); |
|||
} |
|||
|
|||
MainWindow::~MainWindow() |
|||
{ |
|||
delete ui; |
|||
} |
|||
|
|||
|
|||
void MainWindow::on_connectBTN_clicked() |
|||
{ |
|||
modbusTcpClient->connectModbusTcp(); |
|||
} |
|||
|
|||
void MainWindow::on_disconnectBTN_clicked() |
|||
{ |
|||
modbusTcpClient->disconnectModbusTcp(); |
|||
} |
|||
|
|||
void MainWindow::on_ontimeBTN_clicked() |
|||
{ |
|||
// modbusTcpClient->onTimeReadHR();
|
|||
|
|||
timer1 = new QTimer(this); //启动定时器,100ms
|
|||
connect(timer1, SIGNAL(timeout()), this, SLOT(ontimeRead())); |
|||
timer1->start(100); // 每隔1000ms
|
|||
// modbusTcpClient->readMultipleHR(0,20,1);
|
|||
|
|||
} |
|||
|
|||
void MainWindow::ontimeRead(){ |
|||
modbusTcpClient->readMultipleHR(0, 20, 1); |
|||
QString buf; |
|||
// int len = sizeof(modbusTcpClient->dataRCV)/sizeof(modbusTcpClient->dataRCV[0]);
|
|||
for(int i= 0; i<30; i++){ |
|||
buf.append(QString::number(modbusTcpClient->dataRCV[i])); |
|||
buf.append(" "); |
|||
} |
|||
ui->textEdit->setText(buf); |
|||
} |
|||
|
|||
void MainWindow::on_stopOntimeBTN_clicked() |
|||
{ |
|||
timer1->stop(); |
|||
timer1->deleteLater(); |
|||
} |
|||
|
|||
void MainWindow::on_pushButton_clicked() |
|||
{ |
|||
modbusTcpClient->writeSingleFloat(0, -3.14f, 1); |
|||
} |
|||
|
|||
void MainWindow::on_pushButton_2_clicked() |
|||
{ |
|||
float dataSend[3] = {0.0f, 1.1f, -2.3f}; |
|||
modbusTcpClient->writeMultipleHR(0, 6, dataSend, 1); |
|||
} |
@ -0,0 +1,50 @@ |
|||
#ifndef MAINWINDOW_H |
|||
#define MAINWINDOW_H |
|||
|
|||
#include <QMainWindow> |
|||
#include "mymodbustcp.h" |
|||
|
|||
QT_BEGIN_NAMESPACE |
|||
namespace Ui { class MainWindow; } |
|||
QT_END_NAMESPACE |
|||
|
|||
class MainWindow : public QMainWindow |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
MainWindow(QWidget *parent = nullptr); |
|||
~MainWindow(); |
|||
QTimer *timer1; |
|||
MyModbusTcp *modbusTcpClient = nullptr; |
|||
|
|||
private slots: |
|||
/**
|
|||
* @brief on_connectBTN_clicked 连接 |
|||
*/ |
|||
void on_connectBTN_clicked(); |
|||
/**
|
|||
* @brief on_disconnectBTN_clicked 断开连接 |
|||
*/ |
|||
void on_disconnectBTN_clicked(); |
|||
/**
|
|||
* @brief on_ontimeBTN_clicked 持续读 |
|||
*/ |
|||
void on_ontimeBTN_clicked(); |
|||
/**
|
|||
* @brief on_stopOntimeBTN_clicked 停止读 |
|||
*/ |
|||
void on_stopOntimeBTN_clicked(); |
|||
/**
|
|||
* @brief ontimeRead 持续都写 |
|||
*/ |
|||
void ontimeRead(); |
|||
|
|||
void on_pushButton_clicked(); |
|||
|
|||
void on_pushButton_2_clicked(); |
|||
|
|||
private: |
|||
Ui::MainWindow *ui; |
|||
}; |
|||
#endif // MAINWINDOW_H
|
@ -0,0 +1,192 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>MainWindow</class> |
|||
<widget class="QMainWindow" name="MainWindow"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>800</width> |
|||
<height>600</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>MainWindow</string> |
|||
</property> |
|||
<widget class="QWidget" name="centralwidget"> |
|||
<layout class="QGridLayout" name="gridLayout"> |
|||
<item row="0" column="0"> |
|||
<widget class="QTextEdit" name="textEdit"> |
|||
<property name="minimumSize"> |
|||
<size> |
|||
<width>300</width> |
|||
<height>100</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="0" column="1"> |
|||
<layout class="QVBoxLayout" name="verticalLayout"> |
|||
<item> |
|||
<widget class="QPushButton" name="connectBTN"> |
|||
<property name="minimumSize"> |
|||
<size> |
|||
<width>150</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>300</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="font"> |
|||
<font> |
|||
<pointsize>14</pointsize> |
|||
</font> |
|||
</property> |
|||
<property name="text"> |
|||
<string>连接</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QPushButton" name="disconnectBTN"> |
|||
<property name="minimumSize"> |
|||
<size> |
|||
<width>150</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>300</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="font"> |
|||
<font> |
|||
<pointsize>14</pointsize> |
|||
</font> |
|||
</property> |
|||
<property name="text"> |
|||
<string>断开连接</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QPushButton" name="ontimeBTN"> |
|||
<property name="minimumSize"> |
|||
<size> |
|||
<width>150</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>300</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="font"> |
|||
<font> |
|||
<pointsize>14</pointsize> |
|||
</font> |
|||
</property> |
|||
<property name="text"> |
|||
<string>持续读</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QPushButton" name="stopOntimeBTN"> |
|||
<property name="minimumSize"> |
|||
<size> |
|||
<width>150</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>300</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="font"> |
|||
<font> |
|||
<pointsize>14</pointsize> |
|||
</font> |
|||
</property> |
|||
<property name="text"> |
|||
<string>停止持续读</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QPushButton" name="pushButton"> |
|||
<property name="minimumSize"> |
|||
<size> |
|||
<width>150</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>300</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="font"> |
|||
<font> |
|||
<pointsize>14</pointsize> |
|||
</font> |
|||
</property> |
|||
<property name="text"> |
|||
<string>写单个f</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QPushButton" name="pushButton_2"> |
|||
<property name="minimumSize"> |
|||
<size> |
|||
<width>150</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>300</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="font"> |
|||
<font> |
|||
<pointsize>14</pointsize> |
|||
</font> |
|||
</property> |
|||
<property name="text"> |
|||
<string>写多个</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<widget class="QMenuBar" name="menubar"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>800</width> |
|||
<height>21</height> |
|||
</rect> |
|||
</property> |
|||
</widget> |
|||
<widget class="QStatusBar" name="statusbar"/> |
|||
</widget> |
|||
<resources/> |
|||
<connections/> |
|||
</ui> |
@ -0,0 +1,325 @@ |
|||
#include "mymodbustcp.h" |
|||
|
|||
MyModbusTcp::MyModbusTcp() |
|||
{ |
|||
modbusDevice = new QModbusTcpClient(); |
|||
//有错误发生时,发出提示
|
|||
connect(modbusDevice, &QModbusClient::errorOccurred, this, &MyModbusTcp::errorOccurred_Slot); |
|||
//状态改变
|
|||
if(modbusDevice == nullptr){ |
|||
qDebug()<<"cannot create modbus client"; |
|||
} |
|||
else{ |
|||
connect(modbusDevice, &QModbusClient::stateChanged, this, &MyModbusTcp::stateChanged_SLot); |
|||
} |
|||
} |
|||
/**
|
|||
* @brief MyModbusTcp::timeGoBy 等待tms |
|||
* @param time |
|||
* @param t |
|||
*/ |
|||
void MyModbusTcp::timeGoBy(QTime time, int t){ |
|||
time.start(); //设定time为当前时间
|
|||
while(time.elapsed() < t){ //等待时间流逝500ms
|
|||
QCoreApplication::processEvents(); //处理事件
|
|||
} |
|||
} |
|||
//===================================数据类型转换===============================
|
|||
/**
|
|||
* @brief MyModbusTcp::float2Word 将浮点数f转化为2个8位数据存放在word数组中 |
|||
* @param f 待转换的浮点数 |
|||
* @param word 转换后的word数组 |
|||
*/ |
|||
void MyModbusTcp::float2Word(float f, unsigned int *word) |
|||
{ |
|||
unsigned long longdata = 0; |
|||
longdata = *(unsigned long*)&f; //注意,会丢失精度
|
|||
word[0] = (longdata & 0xFFFF0000) >> 16; |
|||
word[1] = (longdata & 0x0000FFFF); |
|||
} |
|||
|
|||
/**
|
|||
* @brief MyModbusTcp::word2Float 将2个word数据转化为浮点数 |
|||
* @param p 指向word数组的指针 |
|||
* @param dataTransformed 转化后的浮点数 |
|||
*/ |
|||
void MyModbusTcp:: word2Float(unsigned int *p, float dataTransformed) |
|||
{ |
|||
dataTransformed=0; |
|||
unsigned long longdata = 0; |
|||
longdata = (*p<< 16) + (*(p+1) << 0); |
|||
dataTransformed = *(float*)&longdata; |
|||
} |
|||
|
|||
//==========================================modbustcp====================
|
|||
/**
|
|||
* @brief MyModbusTcp::errorOccurred_Slot 有错误发生 |
|||
*/ |
|||
void MyModbusTcp::errorOccurred_Slot(){ |
|||
qDebug()<<"new error"<<modbusDevice->errorString(); |
|||
} |
|||
|
|||
/**
|
|||
* @brief MyModbusTcp::stateChanged_SLot 状态改变 |
|||
*/ |
|||
void MyModbusTcp::stateChanged_SLot(){ |
|||
if(modbusDevice->state() == QModbusDevice::UnconnectedState){ |
|||
qDebug()<<"Tcp Client未连接到server"; |
|||
} |
|||
else if(modbusDevice->state() == QModbusDevice::ConnectingState){ |
|||
qDebug()<<"正在连接"; |
|||
} |
|||
else if(modbusDevice->state() == QModbusDevice::ConnectedState){ |
|||
qDebug()<<"已连接"; |
|||
} |
|||
else if(modbusDevice->state() == QModbusDevice::ClosingState){ |
|||
qDebug()<<"已关闭"; |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief MyModbusTcp::connectModbusTcp 连接ModbusTcp |
|||
*/ |
|||
void MyModbusTcp::connectModbusTcp() |
|||
{ |
|||
if(!modbusDevice){ |
|||
return; |
|||
} |
|||
if(modbusDevice->state() != QModbusDevice::ConnectedState){ |
|||
modbusDevice->setConnectionParameter(QModbusClient::NetworkAddressParameter,"192.168.9.71"); |
|||
modbusDevice->setConnectionParameter(QModbusClient::NetworkPortParameter,502); |
|||
modbusDevice->setTimeout(2000); //设置超时
|
|||
modbusDevice->setNumberOfRetries(3); //重试
|
|||
if(!modbusDevice->connectDevice()){ |
|||
qDebug()<<"连接失败"; |
|||
} |
|||
else { |
|||
qDebug()<<"连接成功"; |
|||
} |
|||
}else{ |
|||
// QMessageBox::information(this, "提示", "ModBusTcp已经连接");
|
|||
return; |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief MyModbusTcp::disconnectModbusTcp 断开连接 |
|||
*/ |
|||
void MyModbusTcp::disconnectModbusTcp() |
|||
{ |
|||
if(modbusDevice->state() != QModbusDevice::ConnectedState){ |
|||
// QMessageBox::critical(this, "错误", "MosBusTcp未连接");
|
|||
return; |
|||
} |
|||
modbusDevice->disconnectDevice(); |
|||
qDebug()<<"ModBusTCP断开连接"; |
|||
// ui->stageShwoPlain->appendPlainText("与下位机断开连接成功!");
|
|||
} |
|||
|
|||
//===========================================数据发送、接收======================
|
|||
/**
|
|||
* @brief MyModbusTcp::writeSingleFloat 将单个float写入保持性寄存器 |
|||
* @param address 写入的保持性寄存器地址 |
|||
* @param dataSend 写入的数据 |
|||
* @param serverID id |
|||
*/ |
|||
void MyModbusTcp::writeSingleFloat(int address, float dataSend, int serverID = 1){ |
|||
if(modbusDevice->state() != QModbusDevice::ConnectedState){ |
|||
// QMessageBox::critical(this, "错误", "MosBusTcp未连接");
|
|||
return; |
|||
} |
|||
QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters,address,2); |
|||
unsigned int word[2]; |
|||
float2Word(dataSend, word); |
|||
writeUnit.setValue(0, word[0]); |
|||
writeUnit.setValue(1, word[1]); |
|||
if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, serverID)) {// ui->spinBox_SerAddress->value()是server address sendWriteRequest是向服务器写数据
|
|||
if (!reply->isFinished()) { //reply Returns true when the reply has finished or was aborted.
|
|||
//接收响应信息
|
|||
connect(reply, &QModbusReply::finished, this, [this, reply]() { |
|||
if (reply->error() == QModbusDevice::ProtocolError) { //接收到的响应信息是协议错误
|
|||
qDebug() << "写入数据错误:" << reply->errorString(); |
|||
} else if (reply->error() != QModbusDevice::NoError) { //接收到的响应消息是其它错误
|
|||
qDebug() << "写入数据错误: " << reply->errorString(); |
|||
}else { //接收到的消息没有错误 一般没有必要解析响应消息
|
|||
const QModbusDataUnit data = reply->result(); |
|||
// qDebug() << "消息数据个数:" << data.valueCount() << " :" << data.values();
|
|||
} |
|||
reply->deleteLater(); |
|||
}); |
|||
} else { // broadcast replies return immediately
|
|||
reply->deleteLater(); |
|||
} |
|||
} else { |
|||
qDebug() << "sendWriteRequest Error: " << reply->errorString(); |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief MyModbusTcp::writeSingleWord 写入单个word(int) |
|||
* @param i 地址 |
|||
* @param w 写入的数据 |
|||
*/ |
|||
void MyModbusTcp::writeSingleWord(int i, int w){ |
|||
QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters,i,1); |
|||
writeUnit.setValue(0, w); |
|||
if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, 1)) {// ui->spinBox_SerAddress->value()是server address sendWriteRequest是向服务器写数据
|
|||
if (!reply->isFinished()) { //reply Returns true when the reply has finished or was aborted.
|
|||
//接收响应信息
|
|||
connect(reply, &QModbusReply::finished, this, [this, reply]() { |
|||
if (reply->error() == QModbusDevice::ProtocolError) { //接收到的响应信息是协议错误
|
|||
qDebug() << "写入数据错误:" << reply->errorString(); |
|||
} else if (reply->error() != QModbusDevice::NoError) { //接收到的响应消息是其它错误
|
|||
qDebug() << "写入数据错误: " << reply->errorString(); |
|||
}else { //接收到的消息没有错误 一般没有必要解析响应消息
|
|||
const QModbusDataUnit data = reply->result(); |
|||
// qDebug() << "消息数据个数:" << data.valueCount() << " :" << data.values();
|
|||
} |
|||
reply->deleteLater(); |
|||
}); |
|||
} else { // broadcast replies return immediately
|
|||
reply->deleteLater(); |
|||
} |
|||
} else { |
|||
qDebug() << "sendWriteRequest Error: " << reply->errorString(); |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief MyModbusTcp::writeMultipleHR 写多个保持性寄存器HR |
|||
* @param address 起始地址 |
|||
* @param num 数量 |
|||
* @param dataSend 写入的数组 |
|||
* @param serverID id |
|||
*/ |
|||
void MyModbusTcp::writeMultipleHR(int address, int num, float *dataSend, int serverID = 1) |
|||
{ |
|||
if(modbusDevice->state() != QModbusDevice::ConnectedState){ |
|||
// QMessageBox::critical(this, "错误", "MosBusTcp未连接");
|
|||
return; |
|||
} |
|||
//发送数据
|
|||
qDebug() << "开始发送"; |
|||
QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, address, num); |
|||
unsigned int word[2]; //转换后存放的数组
|
|||
for(int i=0;i<6;i++){ |
|||
float2Word(dataSend[i], word); |
|||
qDebug() << dataSend[i]; |
|||
// qDebug() <<*word;
|
|||
// qDebug() <<*(word+1);
|
|||
writeUnit.setValue(2*i,word[0]); |
|||
writeUnit.setValue(2*i+1,word[1]); |
|||
} |
|||
|
|||
if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, serverID)) {// ui->spinBox_SerAddress->value()是server address sendWriteRequest是向服务器写数据
|
|||
if (!reply->isFinished()) { //reply Returns true when the reply has finished or was aborted.
|
|||
//接收响应信息
|
|||
connect(reply, &QModbusReply::finished, this, [this, reply]() { |
|||
if (reply->error() == QModbusDevice::ProtocolError) { //接收到的响应信息是协议错误
|
|||
qDebug() << "写入数据错误:" << reply->errorString(); |
|||
} else if (reply->error() != QModbusDevice::NoError) { //接收到的响应消息是其它错误
|
|||
qDebug() << "写入数据错误: " << reply->errorString(); |
|||
}else { //接收到的消息没有错误 一般没有必要解析响应消息
|
|||
const QModbusDataUnit data = reply->result(); |
|||
// qDebug() << "消息数据个数:" << data.valueCount() << " :" << data.values();
|
|||
} |
|||
reply->deleteLater(); |
|||
}); |
|||
} else { // broadcast replies return immediately
|
|||
reply->deleteLater(); |
|||
} |
|||
} else { |
|||
qDebug() << "sendWriteRequest Error: " ; |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief MyModbusTcp::readMultipleHR 读取数据并放到wordRCV数组中 |
|||
* @param startAddress 起始地址 |
|||
* @param num 数量 |
|||
* @param serverID id |
|||
*/ |
|||
void MyModbusTcp::readMultipleHR(int startAddress, int num, int serverID = 1){ |
|||
if(modbusDevice->state() != QModbusDevice::ConnectedState){ |
|||
// QMessageBox::critical(this, "错误", "MosBusTcp未连接");
|
|||
return; |
|||
} |
|||
QModbusDataUnit data(QModbusDataUnit::HoldingRegisters, startAddress, num); //地址
|
|||
if(auto *reply = modbusDevice->sendReadRequest(data, serverID)){ //发送请求
|
|||
if(!reply->isFinished()){ |
|||
connect(reply,&QModbusReply::finished, this, &MyModbusTcp::onReadReadyHR_Slot); |
|||
} |
|||
else{ |
|||
delete reply; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief MyModbusTcp::onReadReadyHR_Slot 读取保持性寄存器数据并放到dataRCV数组中 |
|||
*/ |
|||
void MyModbusTcp:: onReadReadyHR_Slot(){ |
|||
if(modbusDevice->state() != QModbusDevice::ConnectedState){ |
|||
// QMessageBox::critical(this, "错误", "MosBusTcp未连接");
|
|||
return; |
|||
} |
|||
QModbusReply *reply = qobject_cast<QModbusReply *>(sender()); |
|||
if(!reply) return; |
|||
if(reply->error() == QModbusDevice::NoError){ |
|||
const QModbusDataUnit responseData = reply->result(); //接收的数据
|
|||
for(uint i = 0;i<responseData.valueCount();i++){ |
|||
wordRCV[i]= responseData.value(i); |
|||
} |
|||
for(uint i = 0;i<responseData.valueCount();i=i+2){ |
|||
float float_data=0; |
|||
unsigned long longdata = 0; |
|||
longdata = (wordRCV[i]<< 16) + (wordRCV[i+1] << 0); |
|||
float_data = *(float*)&longdata; |
|||
dataRCV[i/2] = float_data; |
|||
} |
|||
} |
|||
else if (reply->error() == QModbusDevice::ProtocolError) { |
|||
qDebug()<<"协议错误"; |
|||
qDebug()<<"protocol error:"<<reply->errorString(); |
|||
} |
|||
else{ |
|||
qDebug()<<"回复错误"; |
|||
qDebug()<<"error:"<<reply->errorString(); |
|||
} |
|||
reply->deleteLater(); |
|||
} |
|||
|
|||
//=======================定时获取数据==============================
|
|||
/**
|
|||
* @brief MyModbusTcp::onTimeReadHR 定时读HR,并保存到dataRCV数组中 |
|||
*/ |
|||
//void MyModbusTcp::onTimeReadHR()
|
|||
//{
|
|||
// qDebug()<<"开始持续获取plc数据";
|
|||
// timer = new QTimer(this); //启动定时器,100ms
|
|||
// connect(timer, SIGNAL(timeout()), this, SLOT(readMultipleHR()));
|
|||
// timer->start(1000); // 每隔1000ms
|
|||
//}
|
|||
|
|||
///**
|
|||
// * @brief MyModbusTcp::stopOnTimeReadHR 停止获取数据
|
|||
// */
|
|||
//void MyModbusTcp::stopOnTimeReadHR()
|
|||
//{
|
|||
// qDebug()<<"停止获取plc数据";
|
|||
// timer->stop();
|
|||
// timer->deleteLater();
|
|||
//}
|
|||
|
|||
//================================等待时间=========================
|
|||
///**
|
|||
// * @brief MyModbusTcp::waitTime 等待tms
|
|||
// * @param time
|
|||
// * @param t
|
|||
// */
|
|||
//void MyModbusTcp::waitTime(QTime time, int t){
|
|||
// time.start(); //设定time为当前时间
|
|||
// while(time.elapsed() < t){ //等待时间流逝500ms
|
|||
// QCoreApplication::processEvents(); //处理事件
|
|||
// }
|
|||
//}
|
@ -0,0 +1,111 @@ |
|||
#ifndef MYMODBUSTCP_H |
|||
#define MYMODBUSTCP_H |
|||
|
|||
#include <QModbusTcpClient> |
|||
#include <QModbusReply> |
|||
#include <QDebug> |
|||
#include <QTimer> |
|||
#include <QDateTime> |
|||
#include <QApplication> |
|||
|
|||
|
|||
class MyModbusTcp : public QObject |
|||
{ |
|||
public: |
|||
MyModbusTcp(); |
|||
//声明modbusDevice
|
|||
QModbusClient *modbusDevice; |
|||
//modbustcp接收的原始数据,以word为单位
|
|||
unsigned int wordRCV[40]; |
|||
//用于存放读取的数据的数组,float类型
|
|||
float dataRCV[30]; |
|||
// QTimer *timer = nullptr;
|
|||
|
|||
/**
|
|||
* @brief timeGoBy 等待t毫秒 |
|||
* @param time |
|||
* @param t |
|||
*/ |
|||
void timeGoBy(QTime time, int t); |
|||
/**
|
|||
* @brief connectModbusTcp 连接modbustcp |
|||
*/ |
|||
void connectModbusTcp(); |
|||
|
|||
/**
|
|||
* @brief disconnectModbusTcp 断开连接 |
|||
*/ |
|||
void disconnectModbusTcp(); |
|||
|
|||
/**
|
|||
* @brief writeSingleHR 将单个float写入保持性寄存器 |
|||
* @param address 写入的保持性寄存器地址 |
|||
* @param dataSend 写入的数据 |
|||
* @param serverID id |
|||
*/ |
|||
void writeSingleFloat(int address, float dataSend, int serverID); |
|||
/**
|
|||
* @brief writeSingleWord 写入单个word(int) |
|||
* @param i 地址 |
|||
* @param w 写入的数据 |
|||
*/ |
|||
void writeSingleWord(int i, int w); |
|||
/**
|
|||
* @brief writeMultipleHR 写多个保持性寄存器HR |
|||
* @param address 起始地址 |
|||
* @param num 数量 |
|||
* @param dataSend 写入的数组 |
|||
* @param serverID id |
|||
*/ |
|||
void writeMultipleHR(int address, int num, float *dataSend, int serverID); |
|||
|
|||
/**
|
|||
* @brief readMultipleHR 读多个保持性寄存器,并保存到dataRCV数组中 |
|||
* @param startAddress 起始地址 |
|||
* @param num 数量 |
|||
* @param serverID id |
|||
*/ |
|||
void readMultipleHR(int startAddress, int num, int serverID); |
|||
|
|||
// /**
|
|||
// * @brief onTimeReadHR 定时读HR
|
|||
// */
|
|||
// void onTimeReadHR();
|
|||
|
|||
// /**
|
|||
// * @brief stopOnTimeReadHR 停止定时获取数据
|
|||
// */
|
|||
// void stopOnTimeReadHR();
|
|||
|
|||
private: |
|||
|
|||
/**
|
|||
* @brief float2Word 将浮点数f转化为2个8位数据存放在word数组中 |
|||
* @param f 待转换的浮点数 |
|||
* @param word 转换后的word数组 |
|||
*/ |
|||
void float2Word(float f, unsigned int *word); |
|||
/**
|
|||
* @brief word2Float 将2个word数据转化为浮点数 |
|||
* @param p 指向word数组的指针 |
|||
* @param dataTransformed 转化后的浮点数 |
|||
*/ |
|||
void word2Float(unsigned int *p, float dataTransformed); |
|||
|
|||
/**
|
|||
* @brief errorOccurred_Slot 错误发生 |
|||
*/ |
|||
void errorOccurred_Slot(); |
|||
|
|||
/**
|
|||
* @brief stateChanged_SLot 状态改变 |
|||
*/ |
|||
void stateChanged_SLot(); |
|||
|
|||
/**
|
|||
* @brief onReadReadyHR_Slot HR读取准备就绪 |
|||
*/ |
|||
void onReadReadyHR_Slot(); |
|||
}; |
|||
|
|||
#endif // MYMODBUSTCP_H
|
Loading…
Reference in new issue