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

若该文为原创文章,转载请注明原文出处
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/110071837
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)

Qt开发专栏:项目实战(点击传送门)


前言

  西门西PLC、台达触摸屏、法兰克机床等等多年以前玩得比较多,改造机床、维修机床、给机床编程等等,没事还能车个零件啥的,对于多年以前的研发改造,有时间就重新整理下。
  先上点有历史年代感的照片:
  项目实战:Qt西门子PLC通讯调试和模拟工具(包含PLC上位机通讯,PLC服务器)_第1张图片

  
  项目实战:Qt西门子PLC通讯调试和模拟工具(包含PLC上位机通讯,PLC服务器)_第2张图片

  项目实战:Qt西门子PLC通讯调试和模拟工具(包含PLC上位机通讯,PLC服务器)_第3张图片

  项目实战:Qt西门子PLC通讯调试和模拟工具(包含PLC上位机通讯,PLC服务器)_第4张图片


需求

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


Demo

  


体验下载地址

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


v1.2.0

  项目实战:Qt西门子PLC通讯调试和模拟工具(包含PLC上位机通讯,PLC服务器)_第5张图片


v1.1.0

  项目实战:Qt西门子PLC通讯调试和模拟工具(包含PLC上位机通讯,PLC服务器)_第6张图片
  


关键源码

  项目实战:Qt西门子PLC通讯调试和模拟工具(包含PLC上位机通讯,PLC服务器)_第7张图片
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 
#include 
#include 
#include "snap7.h"

class PlcServerManager : public QObject
{
    Q_OBJECT
private:
    explicit PlcServerManager(QObject *parent = 0);

public:
    static PlcServerManager * getInstance();

    QHash 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 _hashDB2ByteArray;
};

#endif // PLCMANAGER_H

PlcWidget.cpp

#include "PlcServerManager.h"
#include 
#include 
#include 
#include 

#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 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)