zoukankan      html  css  js  c++  java
  • 项目实战:Qt西门子PLC通讯调试和模拟工具(包含PLC上位机通讯,PLC服务器)

     

    前言

      西门西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

  • 相关阅读:
    JNI 对象处理 (转)
    快速配置vs2012+opencv
    Jni中C++和Java的参数传递(转)
    版本控制之四:SVN客户端重新设置帐号和密码(转)
    版本控制之三:SVN合并及解决冲突(转)
    版本控制之二:SVN的初步使用(转)
    版本控制之一:SVN服务器搭建与安装(转)
    xml读取一行数据
    方法论:怎样练习一万小时
    一位软件工程师的6年总结(转)
  • 原文地址:https://www.cnblogs.com/qq21497936/p/14082800.html
Copyright © 2011-2022 走看看