一、核心程序
1.头文件
#pragma once
#include <QObject>
#include <QMutex>
#include <QThread>
#include "ToolSnapGlobal.h"
#include "snap7.h"
struct sSnapData;
class TOOL_SNAP_EXPORT cSnapConObject : public QThread
{
Q_OBJECT
public:
cSnapConObject(QObject *parent = 0);
~cSnapConObject();
public:
static cSnapConObject *getInstance();
public:
bool connect(QString strIp, int nPort = 102,int nRack = 0, int nSlot = 1);
bool readInt16(uint16_t uAddr, int16_t &nValue,int nDb = 1);
bool readMultInt16(uint16_t uStartAddr, int nCount,int16_t *buffer, int nDb = 1);
bool readInt32(uint16_t uAddr, int32_t &nValue, int nDb = 1);
bool readMultiInt32(uint16_t uStartAddr, int nCount, int32_t *buffer, int nDb = 1);
bool readFloat(uint16_t uAddr, float &fValue, int nDb = 1);
bool readMultiFloat(uint16_t uStartAddr, int nCount, float *buffer, int nDb = 1);
bool readM(uint16_t uStartByte, uint16_t uBitOffset, bool &bState, int nDb = 1);
bool readInput_X(uint16_t uStartByte, uint16_t uBitOffset, bool &bState, int nDb = 1);
bool readOutput_Y(uint16_t uStartByte, uint16_t uBitOffset, bool &bState, int nDb = 1);
bool writeInt16(uint16_t uAddr, int16_t nValue, int nDb = 1);
bool writeMultiInt16(uint16_t uStartAddr, int nCount, int16_t *buffer, int nDb = 1);
bool writeInt32(uint16_t uAddr, int32_t nValue, int nDb = 1);
bool writeMultiInt32(uint16_t uStartAddr, int nCount, int32_t *buffer, int nDb = 1);
bool writeFloat(uint16_t uAddr, float fValue, int nDb = 1);
bool writeMultiFloat(uint16_t uStartAddr, int nCount, float *buffer, int nDb = 1);
bool writeM(uint16_t uStartByte, uint16_t uBitOffset, bool bState, int nDb = 1);
bool writeOutput_Y(uint16_t uStartByte, uint16_t uBitOffset, bool bState, int nDb = 1);
bool isConnected();
void release();
private:
void convertInt16ToBigEndian(int16_t value, byte* buffer);
void convertInt32ToBigEndian(int32_t value, byte* buffer);
int32_t bigEndianToLittleEndian(int32_t bigEndianValue);
int16_t bigEndianToLittleEndian(int16_t bigEndianValue);
protected:
void run() override;
private:
sSnapData *m_ptr;
QString m_strIp = "192.168.200.1";
int m_nPort = 1000;
int m_nConnectionType = 2;
int m_nDbNumber = 1;
int m_nRackNumber = 0;
int m_nSlotNumber = 1;
};
2.源文件
#include "Snap7ConObject.h"
#include "snap7.h"
#include <QDebug>
#include <QTime>
#include <QDataStream>
struct sSnapData
{
int nErrorCount = 0;
bool bExit = false;
bool bConneted = false;
TS7Client *pClient = nullptr;
QMutex funMutex;
};
struct sSnap7Timer
{
QTime time;
uint32_t interval;
void start(uint32_t t)
{
interval = t;
time.restart();
};
bool isTimeOut()
{
return time.elapsed() > interval;
};
};
cSnapConObject::cSnapConObject(QObject *parent)
: QThread(parent)
, m_ptr(new sSnapData())
{
m_ptr->pClient = new TS7Client();
this->start();
}
cSnapConObject::~cSnapConObject()
{
}
cSnapConObject *cSnapConObject::getInstance()
{
static cSnapConObject instance;
return &instance;
}
void cSnapConObject::run()
{
static int nStep = 0;
static sSnap7Timer timeout;
while (true)
{
QThread::msleep(100);
if (m_ptr->bExit)
return;
switch (nStep)
{
case 0:
{
if (m_ptr->nErrorCount > 50)
{
nStep = 1;
}
}break;
case 1:
{
if (!m_ptr->pClient->Connected())
{
int nRet = m_ptr->pClient->ConnectTo(m_strIp.toStdString().c_str(), m_nRackNumber, m_nSlotNumber);
if (nRet == 0)
{
m_ptr->nErrorCount = 0;
m_ptr->bConneted = true;
}
else
m_ptr->bConneted = false;
}
else
{
m_ptr->nErrorCount = 0;
}
timeout.start(5 * 1000);
nStep = 2;
}break;
case 2:
{
if (timeout.isTimeOut())
{
nStep = 0;
}
}break;
default:
break;
}
}
}
bool cSnapConObject::connect(QString strIp, int nPort, int nRack, int nSlot)
{
m_strIp = strIp;
m_nPort = nPort;
m_nRackNumber = nRack;
m_nSlotNumber = nSlot;
int nRet = m_ptr->pClient->ConnectTo(strIp.toStdString().c_str(), nRack, nSlot);
if (nRet == 0)
m_ptr->bConneted = true;
else
m_ptr->bConneted = false;
return m_ptr->bConneted;
}
bool cSnapConObject::readInt16(uint16_t uAddr, int16_t &nValue,int nDb)
{
if (!m_ptr->bConneted)
return false;
int16_t buffer[1] = { 0 };
bool bRet = readMultInt16(uAddr, 1, buffer, nDb);
nValue = buffer[0];
return bRet;
}
bool cSnapConObject::readMultInt16(uint16_t uStartAddr, int nCount, int16_t *buffer, int nDb)
{
if (!m_ptr->bConneted)
return false;
QByteArray data(nCount * sizeof(int16_t), 0);
int nRet = m_ptr->pClient->ReadArea(S7AreaDB, nDb, uStartAddr, nCount * sizeof(int16_t), S7WLByte, data.data());
if (nRet == 0)
{
QDataStream dataStream(data);
dataStream.setByteOrder(QDataStream::BigEndian);
for (int i = 0; i < nCount; ++i)
{
int16_t value;
dataStream >> value;
buffer[i] = (value);
}
return true;
}
else
m_ptr->nErrorCount++;
return false;
}
bool cSnapConObject::readInt32(uint16_t uAddr, int32_t &nValue, int nDb)
{
if (!m_ptr->bConneted)
return false;
int32_t buffer[1] = { 0 };
bool bRet = readMultiInt32(uAddr, 1, buffer, nDb);
nValue = buffer[0];
return bRet;
}
bool cSnapConObject::readMultiInt32(uint16_t uStartAddr, int nCount, int32_t *buffer, int nDb)
{
if (!m_ptr->bConneted)
return false;
QByteArray data(nCount * sizeof(int32_t), 0);
int nRet = m_ptr->pClient->ReadArea(S7AreaDB, nDb, uStartAddr, nCount * sizeof(int32_t), S7WLByte, data.data());
if (nRet == 0)
{
QDataStream dataStream(data);
dataStream.setByteOrder(QDataStream::BigEndian);
for (int i = 0; i < nCount; ++i)
{
int32_t value;
dataStream >> value;
buffer[i] = (value);
}
return true;
}
return false;
}
bool cSnapConObject::readFloat(uint16_t uAddr, float &fValue, int nDb)
{
float fArray[1] = {0.0};
bool bRet = readMultiFloat(uAddr,1,fArray);
fValue = fArray[0];
return bRet;
}
bool cSnapConObject::readMultiFloat(uint16_t uStartAddr, int nCount, float *buffer, int nDb)
{
if (!m_ptr->bConneted)
return false;
int nSize = sizeof(float);
QByteArray data(nCount * sizeof(float), 0);
int nRet = m_ptr->pClient->ReadArea(S7AreaDB, nDb, uStartAddr, nCount * sizeof(float), S7WLByte, data.data());
if (nRet == 0)
{
QDataStream dataStream(data);
dataStream.setFloatingPointPrecision(QDataStream::SinglePrecision);
for (int i = 0; i < nCount; ++i)
{
float value;
dataStream >> value;
buffer[i] = (value);
}
return true;
}
return false;
}
bool cSnapConObject::readM(uint16_t uStartByte, uint16_t uBitOffset, bool &bState, int nDb)
{
if (!m_ptr->bConneted)
return false;
uint8_t boolValue = 0;
int nRet = m_ptr->pClient->ReadArea(S7AreaMK, nDb, uStartByte, 1, S7WLBit, &boolValue);
if (nRet == 0)
{
bState = (boolValue & (1 << uBitOffset)) != 0;
return true;
}
else
m_ptr->nErrorCount++;
return false;
}
bool cSnapConObject::readInput_X(uint16_t uStartByte, uint16_t uBitOffset, bool &bState, int nDb)
{
if (!m_ptr->bConneted)
return false;
uint8_t boolValue = 0;
int nRet = m_ptr->pClient->ReadArea(S7AreaPE, nDb, uStartByte, 1, S7WLBit, &boolValue);
if (nRet == 0)
{
bState = (boolValue & (1 << uBitOffset)) != 0;
return true;
}
else
m_ptr->nErrorCount++;
return false;
}
bool cSnapConObject::readOutput_Y(uint16_t uStartByte, uint16_t uBitOffset, bool &bState, int nDb)
{
if (!m_ptr->bConneted)
return false;
uint8_t boolValue = 0;
int nRet = m_ptr->pClient->ReadArea(S7AreaPA, nDb, uStartByte, 1, S7WLBit, &boolValue);
if (nRet == 0)
{
bState = (boolValue & (1 << uBitOffset)) != 0;
return true;
}
else
m_ptr->nErrorCount++;
return false;
}
bool cSnapConObject::writeInt16(uint16_t uAddr, int16_t nValue, int nDb)
{
int16_t buffer[1] = { nValue };
return writeMultiInt16(uAddr, 1, buffer, nDb);
}
bool cSnapConObject::writeMultiInt16(uint16_t uStartAddr, int nCount, int16_t *buffer, int nDb)
{
if (!m_ptr->bConneted)
return false;
std::vector<byte> bufferTemp(nCount * sizeof(int16_t));
for (size_t i = 0; i < nCount; ++i)
{
convertInt16ToBigEndian(buffer[i], &bufferTemp[i * sizeof(int16_t)]);
}
int nRet = m_ptr->pClient->WriteArea(S7AreaDB, nDb, uStartAddr,nCount*sizeof(int16_t), S7WLByte, bufferTemp.data());
if (nRet == 0)
return true;
else
m_ptr->nErrorCount++;
return false;
}
bool cSnapConObject::writeInt32(uint16_t uAddr, int32_t nValue, int nDb)
{
if (!m_ptr->bConneted)
return false;
int32_t buffer[1] = { nValue };
return writeMultiInt32(uAddr,1,buffer,nDb);
}
bool cSnapConObject::writeMultiInt32(uint16_t uStartAddr, int nCount, int32_t *buffer, int nDb)
{
if (!m_ptr->bConneted)
return false;
std::vector<byte> bufferTemp(nCount * sizeof(int32_t));
for (size_t i = 0; i < nCount; ++i)
{
convertInt32ToBigEndian(buffer[i], &bufferTemp[i * sizeof(int32_t)]);
}
int nRet = m_ptr->pClient->WriteArea(S7AreaDB, nDb, uStartAddr,nCount*sizeof(int32_t), S7WLByte, bufferTemp.data());
if (nRet == 0)
return true;
else
m_ptr->nErrorCount++;
return false;
}
bool cSnapConObject::writeFloat(uint16_t uAddr, float fValue, int nDb)
{
float buffer[1] = { fValue };
return writeMultiFloat(uAddr,1,buffer,nDb);
}
bool cSnapConObject::writeMultiFloat(uint16_t uStartAddr, int nCount, float *buffer, int nDb)
{
if (!m_ptr->bConneted)
return false;
QByteArray byteArray;
for (size_t i = 0; i < nCount; ++i)
{
float value = buffer[i];
QByteArray tempData(reinterpret_cast<const char*>(&value), sizeof(float));
for (int j = sizeof(float) - 1; j >= 0; --j)
{
byteArray.append(tempData[j]);
}
}
int nRet = m_ptr->pClient->WriteArea(S7AreaDB, nDb, uStartAddr, byteArray.size(), S7WLByte, byteArray.data());
if (nRet == 0)
return true;
else
m_ptr->nErrorCount++;
return false;
}
bool cSnapConObject::writeM(uint16_t uStartByte, uint16_t uBitOffset, bool bState, int nDb)
{
if (!m_ptr->bConneted)
return false;
uint8_t dataToWrite = 0;
if (bState)
dataToWrite = (1 << uBitOffset);
uint8_t currentData = 0;
int nRet = m_ptr->pClient->ReadArea(S7AreaMK, nDb, uStartByte, 1, S7WLBit, ¤tData);
if (nRet != 0)
{
m_ptr->nErrorCount++;
return false;
}
if (bState)
currentData |= dataToWrite;
else
currentData &= ~dataToWrite;
int nRet1 = m_ptr->pClient->ReadArea(S7AreaMK, nDb, uStartByte, 1, S7WLBit, ¤tData);
if (nRet1 == 0)
return true;
else
m_ptr->nErrorCount++;
return false;
}
bool cSnapConObject::writeOutput_Y(uint16_t uStartByte, uint16_t uBitOffset, bool bState, int nDb)
{
if (!m_ptr->bConneted)
return false;
uint8_t dataToWrite = 0;
if (bState)
dataToWrite = (1 << uBitOffset);
uint8_t currentData = 0;
int nRet = m_ptr->pClient->ReadArea(S7AreaPA, nDb, uStartByte, 1, S7WLBit, ¤tData);
if (nRet != 0)
return false;
if (bState)
currentData |= dataToWrite;
else
currentData &= ~dataToWrite;
int nRet1 = m_ptr->pClient->ReadArea(S7AreaPA, nDb, uStartByte, 1, S7WLBit, ¤tData);
if (nRet1 == 0)
return true;
else
m_ptr->nErrorCount++;
return false;
}
void cSnapConObject::convertInt16ToBigEndian(int16_t value, byte* buffer)
{
buffer[0] = (value >> 8) & 0xFF;
buffer[1] = value & 0xFF;
}
void cSnapConObject::convertInt32ToBigEndian(int32_t value, byte* buffer)
{
buffer[0] = (value >> 24) & 0xFF;
buffer[1] = (value >> 16) & 0xFF;
buffer[2] = (value >> 8) & 0xFF;
buffer[3] = value & 0xFF;
}
int32_t cSnapConObject::bigEndianToLittleEndian(int32_t bigEndianValue)
{
return ((bigEndianValue << 24) & 0xFF000000) |
((bigEndianValue << 8) & 0x00FF0000) |
((bigEndianValue >> 8) & 0x0000FF00) |
((bigEndianValue >> 24) & 0x000000FF);
}
int16_t cSnapConObject::bigEndianToLittleEndian(int16_t bigEndianValue)
{
return (bigEndianValue << 8) | ((bigEndianValue >> 8) & 0xFF);
}
bool cSnapConObject::isConnected()
{
return m_ptr->bConneted;
}
void cSnapConObject::release()
{
m_ptr->bExit = true;
if (m_ptr->pClient->Connected())
{
m_ptr->pClient->Disconnect();
}
}
二、下载连接
https://download.csdn.net/download/u013083044/89939160