I'm trying to write something to my Siemens PLC with a C++/CLI application.
Reading is ok (except the first time it reads it gives odd values).
But writing is doing something completely different then what I want.
below you can find the code:
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
}
}
The sPLC->SetBitAt method:
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 method:
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;
}
I actually get the message "Gelukt", but it still writes the rwong values. So something goes wrong with filling my buffer
. Am I doing something wrong in with the buffer?
In C# I have the same kind of application except the buffer is a byte buffer[];
My questions are:
- Whats the difference between a
byte* buffer;
in C++ and abyte buffer[];
in C#? - 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?
Assuming you have
typedef unsigned char byte;
:In C++/CLI,
byte* buffer;
declares abuffer
variable which is a pointer to abyte
. In C# you write it as:byte* buffer;
in anunsafe
context. The syntax is the same.In C#,
byte[] buffer;
declares abuffer
variable which is a managed array ofbyte
values. The C++/CLI syntax for this isarray<byte> buffer;
.Note that
byte buffer[N];
is C++ syntax for a native array, which is not the same thing. That one can decay to abyte*
pointer.Looks like your code uses a native memory buffer, but there's no way to tell that for sure without the source of
ReadDB
.It means the first byte in your buffer is
0
. If your buffer is supposed to contain C string data, it means it contains the empty string.Most probably. But I can't say exactly what's wrong, because you didn't post the source of
ReadDB
.There are a couple of red flags though:
ReadDB
returns, so how are you supposed to ensure you're not overflowing it?ReadDB
's stack you have a memory corruption issue. Either way, this code is wrong.