Snap7 写入 S7-1200 PLC
Snap7 writing to a S7-1200 PLC
我正在尝试使用 C++/CLI 应用程序向我的西门子 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 发送随机数?
Whats the difference between a byte* buffer;
in C++ and a byte buffer[];
in C#?
假设你有 typedef unsigned char byte;
:
在 C++/CLI 中,byte* buffer;
声明了一个 buffer
变量,它是指向 byte
的指针。在 C# 中,您将其编写为:byte* buffer;
在 unsafe
上下文中。语法相同。
在 C# 中,byte[] buffer;
声明了一个 buffer
变量,它是 byte
值的托管数组。 C++/CLI 语法为 array<byte> buffer;
.
请注意,byte buffer[N];
是原生数组的 C++ 语法,与 不同。那个可以衰减到 byte*
指针。
看起来您的代码使用了本机内存缓冲区,但如果没有 ReadDB
的来源,就无法确定这一点。
When I mouse over on my buffer when I'm debugging, it says buffer* = 0 ''
. Does that mean it's empty? if so, why does it still send random numbers to my PLC?
这意味着缓冲区中的第一个字节是 0
。如果您的缓冲区应该包含 C 字符串数据,则意味着它包含空字符串。
Am I doing something wrong in with the buffer?
很有可能。但是我不能说到底哪里出了问题,因为你没有 post ReadDB
.
的来源
虽然有几个危险信号:
- 缓冲区大小是多少?您的代码不知道什么
ReadDB
returns,那么您应该如何确保不会溢出它?
- 谁是缓冲区的所有者,意思是:谁应该释放它?它 大概 存在于堆中,因此您的代码正在泄漏内存。如果它存在于
ReadDB
的堆栈中,则说明存在内存损坏问题。不管怎样,这段代码都是错误的。
我正在尝试使用 C++/CLI 应用程序向我的西门子 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 发送随机数?
Whats the difference between a
byte* buffer;
in C++ and abyte buffer[];
in C#?
假设你有 typedef unsigned char byte;
:
在 C++/CLI 中,byte* buffer;
声明了一个 buffer
变量,它是指向 byte
的指针。在 C# 中,您将其编写为:byte* buffer;
在 unsafe
上下文中。语法相同。
在 C# 中,byte[] buffer;
声明了一个 buffer
变量,它是 byte
值的托管数组。 C++/CLI 语法为 array<byte> buffer;
.
请注意,byte buffer[N];
是原生数组的 C++ 语法,与 不同。那个可以衰减到 byte*
指针。
看起来您的代码使用了本机内存缓冲区,但如果没有 ReadDB
的来源,就无法确定这一点。
When I mouse over on my buffer when I'm debugging, it says
buffer* = 0 ''
. Does that mean it's empty? if so, why does it still send random numbers to my PLC?
这意味着缓冲区中的第一个字节是 0
。如果您的缓冲区应该包含 C 字符串数据,则意味着它包含空字符串。
Am I doing something wrong in with the buffer?
很有可能。但是我不能说到底哪里出了问题,因为你没有 post ReadDB
.
虽然有几个危险信号:
- 缓冲区大小是多少?您的代码不知道什么
ReadDB
returns,那么您应该如何确保不会溢出它? - 谁是缓冲区的所有者,意思是:谁应该释放它?它 大概 存在于堆中,因此您的代码正在泄漏内存。如果它存在于
ReadDB
的堆栈中,则说明存在内存损坏问题。不管怎样,这段代码都是错误的。