Browse Source

first

master
tianzhendong 3 years ago
commit
d63d454cc5
  1. 73
      .gitignore
  2. 33
      MyModbusTcp.pro
  3. 11
      main.cpp
  4. 65
      mainwindow.cpp
  5. 50
      mainwindow.h
  6. 192
      mainwindow.ui
  7. 325
      mymodbustcp.cpp
  8. 111
      mymodbustcp.h

73
.gitignore

@ -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

33
MyModbusTcp.pro

@ -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

11
main.cpp

@ -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();
}

65
mainwindow.cpp

@ -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);
}

50
mainwindow.h

@ -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

192
mainwindow.ui

@ -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>

325
mymodbustcp.cpp

@ -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 2word数据转化为浮点数
* @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 wordint
* @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(); //处理事件
// }
//}

111
mymodbustcp.h

@ -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 wordint
* @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 2word数据转化为浮点数
* @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…
Cancel
Save