美文网首页
项目实战:Qt西门子PLC通讯调试和模拟工具(包含PLC上位机通

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

作者: 红模仿_红胖子 | 来源:发表于2020-12-03 20:51 被阅读0次

本文章博客地址:https://blog.csdn.net/qq21497936/article/details/110071837

各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

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

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

前言

西门西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上位机通

      本文链接:https://www.haomeiwen.com/subject/dhevwktx.html