前言
西門西PLC、臺達觸摸屏、法蘭克機牀等等多年以前玩得比較多,改造機牀、維修機牀、給機牀編程等等,沒事還能車個零件啥的,對於多年以前的研發改造,有時間就重新整理下。
先上點有歷史年代感的照片:
基於Qt實現與PLC通訊功能。
CSDN:https://download.csdn.net/download/qq21497936/13239895
QQ羣:1047134658(點擊“文件”搜索“plcCommunication”,羣內與博文同步更新)
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