一. 需求
集成snap7库,对西门子plc进行访问。
二. 步骤
- 下载snap7 库,之后取build/bin/win64 下的 dll 和lib 直接使用。
https://sourceforge.net/projects/snap7/files/1.4.2/
2. 把examples/cpp 下的 snap7.h 和cpp 加到工程里。
3. 封装一个单例 来使用 这个库。
#ifndef PLCMANAGER_H
#define PLCMANAGER_H
#include <QObject>
#include <snap7.h>
class PLCManager : public QObject
{
Q_OBJECT
public:
static PLCManager& getInstance() {
static PLCManager instance;
return instance;
}
PLCManager(const PLCManager&) = delete;
PLCManager& operator=(const PLCManager&) = delete;
//连接plc
int connect(QString ip);
//设置转台角度
int setTurntableAngle(float value);
private:
explicit PLCManager(QObject *parent = nullptr);
~PLCManager();
signals:
private:
std::shared_ptr<TS7Client> client;
bool bConnected{false};
};
#endif // PLCMANAGER_H
#include "plcmanager.h"
PLCManager::PLCManager(QObject *parent)
: QObject{parent}
{
client = std::make_shared<TS7Client>();
}
PLCManager::~PLCManager()
{
}
int PLCManager::connect(QString ip)
{
int ret = client->ConnectTo(ip.toStdString().data(),0,1);
if(ret==0){
bConnected=true;
}else{
bConnected=false;
}
return ret;
}
int PLCManager::setTurntableAngle(float value)
{
if(!bConnected)
return -1;
//测试
byte bufferWrite[1]={1};
client->MBWrite(100,1,&bufferWrite);
}
4. 使用的时候 直接调用业务函数。
PLCManager::getInstance().connect("127.0.0.1");
PLCManager::getInstance().setTurntableAngle(0);
5. 用Hsl工具测试下,这里再M100 位置 写入了一个byte ,值为1。
6,常用读写
void PLCManager::writeInt(int DBNumber, int StartByte, short value)
{
if(!bConnected)
return;
uint8_t bytes[2] = {0};
std::memcpy(bytes, &value, sizeof(value));
std::reverse(bytes, bytes + sizeof(bytes));
client->WriteArea(Area,DBNumber,StartByte,2,S7WLByte,bytes);
}
short PLCManager::readInt(int DBNumber, int StartByte)
{
if(!bConnected)
return -1;
uint8_t buffRead[2];
int ret = client->ReadArea(Area,DBNumber,StartByte,2,S7WLByte,&buffRead);
if(ret==0){
short intValue = static_cast<int>((buffRead[1] & 0xFF) |
((buffRead[0] & 0xFF) << 8));
return intValue;
}else{
return -1;
}
}
void PLCManager::writeFloat(int DBNumber, int StartByte, float value)
{
if(!bConnected)
return;
uint8_t bytes[4] = {0};
std::memcpy(bytes, &value, sizeof(value));
std::reverse(bytes, bytes + sizeof(bytes));
client->WriteArea(Area,DBNumber,StartByte,4,S7WLByte,bytes);
}
float PLCManager::readFloat(int DBNumber, int StartByte)
{
if(!bConnected)
return -1;
uint8_t buffRead[4];
int ret = client->ReadArea(Area,DBNumber,StartByte, 4,S7WLByte,buffRead);
if(ret==0){
uint32_t value = (static_cast<uint32_t>(buffRead[0]) << 24) |
(static_cast<uint32_t>(buffRead[1]) << 16) |
(static_cast<uint32_t>(buffRead[2]) << 8) |
static_cast<uint32_t>(buffRead[3]);
float floatValue;
std::memcpy(&floatValue, &value, sizeof(float));
return floatValue;
}else{
return -1;
}
}
void PLCManager::writeBool(int DBNumber, int StartByte, int StartBit, bool value)
{
if(!bConnected)
return;
byte res[1]{0};
int ret = client->ReadArea(Area,DBNumber,StartByte,1,S7WLByte,&res);
if(ret==0){
byte result[1]{0};
if(!value){
unsigned char mask = ~(1 << StartBit);
result[0] = res[0] & mask;
}else{
unsigned char mask = 1 << StartBit;
result[0] = res[0] | mask;
}
client->WriteArea(Area, DBNumber, StartByte, 1, S7WLByte, &result);
}
}
bool PLCManager::readBool(int DBNumber, int StartByte, int StartBit)
{
if(!bConnected)
return -1;
byte res[1]{0};
//读一个字节 8位
int ret = client->ReadArea(Area,DBNumber,StartByte,1,S7WLByte,&res);
if(ret==0){
//判断第StartBit位
unsigned char mask = 1 << StartBit;
unsigned char result = res[0] & mask;
if(result!=0){
return true;
}else{
return false;
}
}else{
return false;
}
}