前言

  西门西PLC、台达触摸屏、法兰克机床等等多年以前玩得比较多,改造机床、维修机床、给机床编程等等,没事还能车个零件啥的,对于多年以前的研发改造,有时间就重新整理下。
  先上点有历史年代感的照片:
  
  
  
  

  
  

  

  

 

需求

  基于Qt实现与PLC通讯功能。

 

Demo

  
  

 

体验下载地址

  CSDN:https://download.csdn.net/download/qq21497936/13239895
  QQ群:1047134658(点击“文件”搜索“plcCommunication”,群内与博文同步更新)

 

v1.2.0

  
  

 

v1.1.0

  
  

 

关键源码

  
  
  
PlcWidget.h

#ifndef PLCSERVERMANAGER_H
#define PLCSERVERMANAGER_H /************************************************************\
* 控件名称:PlcServerManager
* 功能描述:Plc通讯服务器(用于模拟PLC,包括仿真DB数据空间)
* 控件功能:
* 1.唯一实例类
* 2.注册DB
* 3.监听、停止监听
* 4.对所有事件进行反馈
* 作者:长沙红胖子(AAA红模仿)
* 博客专家地址:https://blog.csdn.net/qq21497936/article/details/102478062
* 联系方式:QQ(21497936) 微信(yangsir198808)
* 版本信息
* 日期 版本号 描述
* 2020年11月23日 v1.0.0 基础功能
* 2020年12月01日 v1.1.0 增加客户端写入提示信号
\************************************************************/ #include <QObject>
#include <QMutex>
#include <QHash>
#include "snap7.h" class PlcServerManager : public QObject
{
Q_OBJECT
private:
explicit PlcServerManager(QObject *parent = 0); public:
static PlcServerManager * getInstance(); QHash<int, QByteArray> getHashDB2ByteArray() const; signals:
void signal_listenStateChanged(bool listen);
void signal_dataChanged(); public slots:
void slot_start();
void slot_stop();
void slot_listen(QString ip);
void slot_stopListen();
void slot_regsiterDB(int dbNum, int size);
void slot_setDB(int dbNum, QByteArray data); private:
static PlcServerManager *_pInstance;
static QMutex _mutex;
static void callBack_event(void *usrPtr, PSrvEvent PEvent, int Size); private:
bool _running; // 线程是否启用
bool _listen; // 是否连接PLC
QString _ip; // ip地址
QStringList _listIp; // 连接上的客户端地址
TS7Server *_pTS7Server;
QHash<int, QByteArray> _hashDB2ByteArray;
}; #endif // PLCMANAGER_H

PlcWidget.cpp

#include "PlcServerManager.h"
#include <QMessageBox>
#include <QFile>
#include <QHostAddress>
#include <QDebug> #define LOG qDebug()<<__FILE__<<__LINE__ PlcServerManager *PlcServerManager::_pInstance = 0;
QMutex PlcServerManager::_mutex; void PlcServerManager::callBack_event(void *usrPtr, PSrvEvent PEvent, int Size)
{
switch (PEvent->EvtCode)
{
case evcDataRead: // 读取数据 break;
case evcDataWrite: // 写入数据
emit _pInstance->signal_dataChanged();
break;
default:
break;
} } QHash<int, QByteArray> PlcServerManager::getHashDB2ByteArray() const
{
return _hashDB2ByteArray;
} PlcServerManager::PlcServerManager(QObject *parent)
: QObject(parent),
_running(false),
_pTS7Server(0),
_listen(false)
{
} PlcServerManager *PlcServerManager::getInstance()
{
if(!_pInstance)
{
QMutexLocker lock(&_mutex);
if(!_pInstance)
{
_pInstance = new PlcServerManager();
}
}
return _pInstance;
} void PlcServerManager::slot_start()
{
if(_running)
{
LOG << "It's already running!!!";
return;
}
_running = true;
_pTS7Server = new TS7Server();
} void PlcServerManager::slot_stop()
{
if(!_running)
{
LOG << "It's not running!!!";
return;
}
if(_pTS7Server)
{
_running = false;
_pTS7Server->Stop();
delete _pTS7Server;
_pTS7Server = 0;
}
} void PlcServerManager::slot_listen(QString ip)
{
if(!_running)
{
LOG << "It's not running!!!";
return;
}
if(_listen)
{
LOG << "It's already listen!!!";
return;
}
_ip = ip;
_pTS7Server->SetEventsCallback(PlcServerManager::callBack_event, 0);
_pTS7Server->StartTo(_ip.toUtf8().data());
_listen = true;
emit signal_listenStateChanged(_listen);
} void PlcServerManager::slot_stopListen()
{
if(!_running)
{
LOG << "It's not running!!!";
return;
}
LOG << _pTS7Server->Stop();
_listen = false;
emit signal_listenStateChanged(_listen);
} void PlcServerManager::slot_regsiterDB(int dbNum, int size)
{
if(!_running)
{
LOG << "It's not running!!!";
return;
}
QByteArray byteArray(size, 0x00);
_hashDB2ByteArray.insert(dbNum, byteArray);
_pTS7Server->RegisterArea(srvAreaDB, dbNum, _hashDB2ByteArray[dbNum].data(), byteArray.size());
} void PlcServerManager::slot_setDB(int dbNum, QByteArray data)
{
if(!_running)
{
LOG << "It's not running!!!";
return;
}
if(_hashDB2ByteArray.contains(dbNum))
{
for(int index = 0; index < data.size(); index++)
{
_hashDB2ByteArray[dbNum][index] = data.at(index);
}
LOG << _hashDB2ByteArray.value(dbNum).toHex(' ');
}
}
 

若该文为原创文章,转载请注明原文出处
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/110071837

项目实战:Qt西门子PLC通讯调试和模拟工具(包含PLC上位机通讯,PLC服务器)的更多相关文章

  1. 倍福TwinCAT3上位机与PLC通信测试(ADS通信) 包含C#和C++代码

    倍福TwinCAT3上位机与PLC通信测试(ADS通信) 包含C#和C++代码 本次测试需要环境: VS2013,TwinCAT3(本人版本TC31-Full-Setup.3.1.4018.16) 代 ...

  2. 多个rs485设备怎样跟上位机通讯?

    http://bbs.hcbbs.com/thread-819457-1-1.html 多个rs485设备怎样跟上位机通讯? [复制链接] |关注本帖     fdemeng 签到天数: 1228 天 ...

  3. (原创)使用C#开发高性能PLC上位机监控系统服务器应用程序

    PLC服务器监控系统的特点: 1·使用微软C#面向对象开发语言开发应用程序.2·使用了健壮性与性能良好的SUPER SOCKET服务器通信框架,实现自定义应用层通信协议,支持多台PC客户端访问服务器, ...

  4. 案例分享:Qt西门子机床人机界面以及数据看板定制(西门子通讯,mysql数据库,生产信息,参数信息,信息化看板,权限控制,播放器,二维图表,参数调试界面)

    若该文为原创文章,转载请注明原文出处本文章博客地址:https://blog.csdn.net/qq21497936/article/details/118685521 长期持续带来更多项目与技术分享 ...

  5. c#上位机与三菱PLC(FX3U)串口通讯

    项目中会经常用到上位机与PLC之间的串口通信,本文介绍一下C#如何编写上位机代码 与三菱FX3U进行通讯 1. 第一种方法是自己写代码实现,主要代码如下: //对PLC的Y7进行置1 byte[] Y ...

  6. 嵌入式Linux学习笔记(六) 上位机QT界面实现和串口通讯实现

    目录 (1).参考资料 (2).QT界面布局实现 (3).数据和操作逻辑 在上一章我们实现了下位机的协议制定,并通过串口通讯工具完成了对设备内外设(LED)的状态修改,下面就要进行上位机软件的实现了( ...

  7. WinForm通用自动更新AutoUpdater项目实战

    目前我们做的上位机项目还是以Winform为主,在实际应用过程中,可能还会出现一些细节的修改.对于这种情况,如果上位机带有自动更新功能,我们只需要将更新后的应用程序打包放在指定的路径下,可以让用户自己 ...

  8. 开源纯C#工控网关+组态软件(四)上下位机通讯原理

    一.   网关的功能:承上启下 最近有点忙,更新慢了.感谢园友们给予的支持,现在github上已经有.目标是最好的开源组态,看来又近一步^^ 之前有提到网关是物联网的关键环节,它的作用就是承上启下. ...

  9. 【大话QT之十六】使用ctkPluginFramework插件系统构建项目实战

    "使用ctkPluginFramework插件系统构建项目实战",这篇文章是写博客以来最纠结的一篇文章. 倒不是由于技术都多么困难,而是想去描写叙述一个项目架构採用ctkPlugi ...

  10. QT5 QSS QML界面美化视频课程系列 QT原理 项目实战 C++1X STL

    QT5 QSS QML界面美化视频课程系列 QT原理 项目实战 C++1X STL 课程1   C语言程序设计高级实用速成课程 基础+进阶+自学 课程2   C语言程序设计Windows GDI图形绘 ...

随机推荐

  1. [转帖]ls命令

    ls(list) 命令可以说是Linux下最常用的命令之一 #ls -l;列出文件的详细信息 #ll 以上两个命令一样,ll是ls -l的简写 #ls -al;列出目录下的所有文件,包括以 . 开头的 ...

  2. Linux 内核参数

    /proc/sys/net/ipv4: ip_local_port_range:定义了TCP或UDP对目标发起连接所选择的本地端口范围(除ip_local_reserved_ports之外),其定义受 ...

  3. Flask四剑客

    目录 Flask四剑客 Flask四剑客 ''' 响应字符串 响应html页面 跳转页面 返回json字符串 ''' from flask import Flask, render_template, ...

  4. 使用 NuGet.Server 创建和部署 ASP.NET Web 应用程序搭建私有Nuget服务器

    使用 NuGet.Server 创建和部署 ASP.NET Web 应用程序搭建私有Nuget服务器 在Visual Studio中,选择"新建>文件>"Project ...

  5. Pytest 源码解读 [1] - [pluggy] 核心设计理念浅读

    背景: Pytest 是一个功能强大的 Python 测试框架,它使用了一个名为 "pluggy" 的插件系统来扩展其功能.在 Pytest 的源码中,pluggy 模块负责实现插 ...

  6. 【SpringBoot】AOP默认的动态代理

    分析: 当引入AOP相关依赖后 <dependency> <groupId>org.springframework</groupId> <artifactId ...

  7. 2023 ASP.NET Core 开发者路线图

    链接 ASP.NET Core Developer Roadmap

  8. 【Flink入门修炼】1-3 Flink WordCount 入门实现

    本篇文章将带大家运行 Flink 最简单的程序 WordCount.先实践后理论,对其基本输入输出.编程代码有初步了解,后续篇章再对 Flink 的各种概念和架构进行介绍. 下面将从创建项目开始,介绍 ...

  9. SVC服务的发现

    目录 服务的发现 发现的方式 1. ClusterIP 2. 通过变量 3. 通过DNS(推荐) 服务的发现 发现的方式 服务的发现说的就是svc的ip只有集群内的资源可以访问到,比如集群内的节点,p ...

  10. Power BI 11 DAY

    目录 电商平台流量分析 流量相关指标 流量数量指标 流量质量指标 度量值计算公式 流量转化率重要指标 指标观测维度 电商平台流量分析 电商平台黄金公式:销售额 = 流量 + 转化率 + 客单价 流量相 ...