【问题标题】:Snap7 writing to a S7-1200 PLCSnap7 写入 S7-1200 PLC
【发布时间】:2016-02-28 10:14:25
【问题描述】:

我正在尝试使用 C++/CLI 应用程序向 Siemens PLC 写一些东西。

读取是可以的(除了第一次读取它给出奇数值)。

但是写作是在做一些与我想要的完全不同的事情。

您可以在下面找到代码:

    private: void WriteSiemensDB()
    {
        byte* buffer;

        if (ConnectToSiemensPLC()) //Check if you are connected to PLC
        {
        String^ msg;
        int DBNumber = 2;
        bool NDR;
                                                       
        //Getting the values 1 time so buffer has a value
        buffer = sPLC->ReadDB(DBNumber);
        
        //give variables a value to write it to the PLC
        NDR = true;
        
        sPLC->SetBitAt(buffer, 0, 0, NDR); //Convert a bool to a bit
    
        msg = sPLC->WriteDB(DBNumber, buffer); //write to the Datablock in Siemens

        MessageBox::Show(msg); //Show if it worked or not
    }
}

sPLC->SetBitAt 方法:

void SiemensPLC::SetBitAt(byte buffer[], int Pos, int Bit, bool Value)
{
    byte Mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
    if (Bit < 0) Bit = 0;
    if (Bit > 7) Bit = 7;

    if (Value)
    {
        buffer[Pos] = (byte)(buffer[Pos] | Mask[Bit]);
    }
    else
    {
        buffer[Pos] = (byte)(buffer[Pos] & ~Mask[Bit]);
    }
}

WriteDB 方法:

System::String^ SiemensPLC::WriteDB(int DBnumber, byte buffer[])
{
    int Result;
    String^ msg;
    Result = MyClient->DBWrite(DBnumber, 0, 80, buffer);

    if (Result == 0)
    {
        msg = "Gelukt!"; //success
    }
    else
    {
        msg = "Mislukt, error:" + Result; //failed
    }
    return msg;
}

我实际上收到消息“Gelukt”,但它仍然写入 rwong 值。所以填写我的buffer 时出了点问题。我在缓冲区中做错了吗?

在 C# 中,除了缓冲区是 byte buffer[]; 之外,我有相同类型的应用程序

我的问题是:

  • C++ 中的 byte* buffer; 和 C# 中的 byte buffer[]; 有什么区别?
  • 当我在调试时将鼠标悬停在缓冲区上时,它显示buffer* = 0 ''。这是否意味着它是空的?如果是这样,为什么它仍然向我的 PLC 发送随机数?

【问题讨论】:

    标签: c++-cli plc s7-1200 siemens


    【解决方案1】:

    C++ 中的 byte* buffer; 和 C# 中的 byte buffer[]; 有什么区别?

    假设你有typedef unsigned char byte;:

    在 C++/CLI 中,byte* buffer; 声明了一个 buffer 变量,它是一个指向 byte 的指针。在 C# 中,您将其编写为:byte* buffer;unsafe 上下文中。语法是一样的。

    在 C# 中,byte[] buffer; 声明了一个 buffer 变量,它是一个由 byte 值组成的托管数组。对此的 C++/CLI 语法是 array&lt;byte&gt; buffer;

    请注意,byte buffer[N]; 是原生数组的 C++ 语法,不是相同的东西。那个可以衰减到byte* 指针。

    看起来您的代码使用了本机内存缓冲区,但如果没有ReadDB 的来源,就无法确定这一点。

    当我在调试时将鼠标悬停在缓冲区上时,它会显示buffer* = 0 ''。这是否意味着它是空的?如果是这样,为什么它仍然向我的 PLC 发送随机数?

    这意味着缓冲区中的第一个字节是0。如果您的缓冲区应该包含 C 字符串数据,则意味着它包含空字符串。

    我在缓冲区中做错了吗?

    很有可能。但是我不能确切地说出什么问题,因为你没有发布ReadDB的来源。

    不过有几个危险信号:

    • 缓冲区大小是多少?您的代码不知道 ReadDB 返回什么,那么您应该如何确保不会溢出呢?
    • 谁是缓冲区的所有者,意思是:谁应该释放它?它大概存在于堆上,因此您的代码正在泄漏内存。如果它存在于ReadDB 的堆栈中,则说明存在内存损坏问题。无论哪种方式,这段代码都是错误的。

    【讨论】:

    • 是的,我注意到我必须将缓冲区更改为数组,我已经这样做了,现在已经解决了。谢谢(你的)信息! :)
    猜你喜欢
    • 2017-03-13
    • 1970-01-01
    • 2015-10-07
    • 2016-06-13
    • 2018-06-07
    • 2014-10-06
    • 1970-01-01
    • 2017-04-04
    • 2018-07-28
    相关资源
    最近更新 更多