一. 需求
集成snap7库,对西门子plc进行访问。
二. 步骤

  1. 下载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;
    }
}