fbarresi / sharp7 Goto Github PK
View Code? Open in Web Editor NEWNuget package for Sharp7
License: MIT License
Nuget package for Sharp7
License: MIT License
Hi,
I'm new to Siemens and I would like to know if I can connect to a CP3431-1 LEAN with this library ? And if there is something to configure to be able to communicate successfully?
My program is ready to run but I can't communicate with the Siemens CP343-1 LEAN.
Regards,
Pat
Ciao,
Sto avendo alcuni problemi con la funzione DBWrite:
In un protocollo di scambio dati tra PC e PLC che prevede l'accesso ad un DB in Lettura/Scrittura da entrambe le parti, a volte questa funzione restituisce 0 (esito positivo) anche se fisicamente sul PLC i dati non sono scritti.
Il protocollo di scambio è il seguente:
LOOP(condition)
PC=>PLC (DB1): Stringa XXXXXX (Risposta su DB1)
PLC=>PC (DB2): Stringa XXXXXXXXX (Risposta su DB2)
PC=>PLC(DB1): Stringa ------ (Reinizializza stringa con carattere predefinito)
PC=>PLC(DB2): Stringa ------ (Reinizializza stringa con carattere predefinito)
END LOOP
Ho momentaneamente tamponato questo problema con un meccanismo di Scrittura=>Rilettura=>Retry.
Avendo poca esperienza con questo protocollo fatico a comprendere se il problema sia dato dalla funzione che esce prematuramente o dal PLC che fa qualche scherzetto.
Hi !
There is no physical connection.
The DBRead method predictably returns error number 9. CLI : Client not connected.
The DB Write method returns an exception System.ArgumentOutOfRangeException.
And it should, as it seemed to me, also return error number 9.
Why is this not the case?
namespace TestSharp7ConsoleApplication
{
class Program
{
static void Main()
{
int result;
byte[] db = new byte[20];
S7Client client = new S7Client();
client.ConnectTo("192.168.0.2", 0, 1);
try
{
result = client.DBRead(10, 0, db.Length, db);
Console.WriteLine($"{result} : {client.ErrorText(result)}");
result = client.DBWrite(10, 0, db.Length, db);
Console.WriteLine($"{result} : {client.ErrorText(result)}");
}
catch (System.ArgumentOutOfRangeException e)
{
result = -1;
Console.WriteLine($"{result} : {e.Message}");
}
Console.WriteLine();
Console.WriteLine("Press <Enter> for exit");
Console.ReadLine();
}
}
}
Instead of using this
, SetBitAt
uses ref
, however byte[]
is a pointer to the array, so there's no need to ref it.
public static void SetBitAt(ref byte[] buffer, int pos, int bit, bool value)
There also is a cast to short
in GetIntAt, however the return type is still int
And GetTODAt
/SetTODAt
/GetLTODAt
/SetLTODAt
, work with DateTime
, while there's no Date part in the data, shouldn't it use TimeSpan
instead?
(As suggested by the code already present: TimeSpan Time = value.TimeOfDay;
)
.NET 5.0 is a current release. That means that it will be supported for three months after .NET 6.0 is released. As a result, we expect to support .NET 5.0 through the middle of February 2022. .NET 6.0 will be an LTS release and will be supported for three years, just like .NET Core 3.1.
https://devblogs.microsoft.com/dotnet/announcing-net-5-0/
https://devblogs.microsoft.com/dotnet/announcing-net-6-preview-1/
Tested with S7-300. After successful connection to PLC, if you disconnect it or turn it off the S7Client.Connected property stays always true.
It returns int instead of short and miscalculates value because of that.
This has been fixed on original sharp7.cs with 1.0.4 update by Jérémy HAURAY at 2018/06/12.
Problem could be fixed as below;
public static short GetIntAt(this byte[] buffer, int pos)
{
return (short)((buffer[pos] << 8) | buffer[pos + 1]);
}
Sorry for my English.
In my work, I decided to use your code, but during the development of the project, a question arose. What is the reason for choosing to use constants instead of enum?
Example from wiki:
public int ReadArea(int Area, int DBNumber, int Start, int Amount, int WordLen, byte[] Buffer)
where:
public const byte S7AreaPE = 0x81;
public const byte S7AreaPA = 0x82;
public const byte S7AreaMK = 0x83;
public const byte S7AreaDB = 0x84;
public const byte S7AreaCT = 0x1C;
public const byte S7AreaTM = 0x1D;
and
public const int S7WLBit = 0x01;
public const int S7WLByte = 0x02;
public const int S7WLChar = 0x03;
public const int S7WLWord = 0x04;
public const int S7WLInt = 0x05;
public const int S7WLDWord = 0x06;
public const int S7WLDInt = 0x07;
public const int S7WLReal = 0x08;
public const int S7WLCounter = 0x1C;
public const int S7WLTimer = 0x1D;
The variables that we pass to the ReadArea method, such as Area and WordLen, are not obvious, and they are very easy to make mistakes in. You can convert the code as follows.
public enum S7Area { PE = 0x81, PA = 0x82, MK = 0x83, DB = 0x84, CT = 0x1C, TM = 0x1D } public enum S7WordLength { Bit = 0x01, Byte = 0x02, Char = 0x03, Word = 0x04, Int = 0x05, DWord = 0x06, DInt = 0x07, Real = 0x08, Counter = 0x1C, Timer = 0x1D }
public int ReadArea(S7Area area, int DBNumber, int Start, int Amount, S7WordLength length, byte[] Buffer)
This way, you restrict the variables that you can pass while keeping their values. This is just a small example. there are a lot of constants in the code, starting from the block language and ending with
"Error codes". What is the reason for this?
Is multivar limited to 20 datapoints?
inspection does not count up after 20 datapoints
Shouldn't the current length of the string be checked against the specified maximum length when writing to prevent overwriting the following memory ?
public static void SetStringAt(this byte[] buffer, int pos, int MaxLen, string value)
{
int length = value.Length;
// checking current length against MaxLen
if (length > MaxLen) length = MaxLen;
buffer[pos] = (byte) MaxLen;
buffer[pos + 1] = (byte) length;
Encoding.UTF8.GetBytes(value, 0, length, buffer, pos + 2);
}
Hi, I wish if you could share some trend performance graphs about read/write tags. We are using this library for big amount of PLC data, and we read them on cycle time. At the moment everything is not completely implemented, we are not sure about library stability so we read some datas only when the OnRead event on our service is triggered
Thanks
Hello!
We are using an implementation for C# and I would like to draw your attention to the following code:
int Elapsed = Environment.TickCount;
...
Expired = Environment.TickCount - Elapsed > Timeout;
This is because Environment.TickCount returns values from Int32.MinValue to Int32.MaxValue. Therefore, if the system has been running for 24.9 days, the counter will turn negative and the expression Expired = Environment.TickCount-Elapsed > Timeout will return false for the next 24.9 days.
Instead of Environment.TickCount, I would suggest using a static instance of Stopwatch (which is run once) to get uptime milliseconds.
Reading and writing custom types (struct or class) required like below;
s7Client.Read<T>(...)
Hi,
i have a windows service which checks the PLC for data every second.
While i do so, i write an integer (can be 0 or 1) in the PLC and sometimes get the following error (max 10 times in 24hours)
E1-1: System.ArgumentOutOfRangeException: Non-negative number required. (Parameter 'length')
at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
at Sharp7.S7Client.WriteArea(Int32 Area, Int32 DBNumber, Int32 Start, Int32 Amount, Int32 WordLen, Byte[] Buffer, Int32& BytesWritten)
at Np300.Service.Utilities.PlcReader.ReadPlcDbBuffer() in C:\Np300.Service\Utilities\PlcReader.cs:line 56
at Np300.Service.Utilities.PlcReader.ReadPlcDbBuffer() in C:\Np300.Service\Utilities\PlcReader.cs:line 62
at Np300.Service.Utilities.PlcReader.ReadFromPlc() in C:\Np300.Service\Utilities\PlcReader.cs:line 32
at Np300.Service.Services.PlcBufferService.WriteEventsFromPlcToBuffer() in C:\Np300.Service\Services\PlcBufferService.cs:line 99
private async Task<byte[]> ReadPlcDbBuffer()
{
//Irrelevant
var client = new S7Client();
client.ConnectTo(_spsOptions.Np300Saw.IpAddress, _spsOptions.Np300Saw.Rack, _spsOptions.Np300Saw.Slot);
var oldRequestId = readBuffer.GetIntAt(_spsOptions.Np300Saw.RequestId.Position);
//Relevant
short requestId = (short)(oldRequestId == 1 ? 0 : 1);
byte[] writeBuffer = new byte[2];
writeBuffer.SetIntAt(0, requestId);
//Error is thrown on the following line
state = client.DBWrite(_spsOptions.Np300Saw.DbId, _spsOptions.Np300Saw.RequestId.Position, 2, writeBuffer);
// Read more from PLC and do stuff...
client.Disconnect();
}
Has someone an idea why this happens?
Do i forget to dispose something?
Should i reuse the client, instead of disconnecting every time?
Thanks
Kilian
If you go to the IO functions page for example, you will see that the return values are copied from the Connection page.
They are obviously wrong.
SendPacket(byte[] Buffer, int Len) doesnt check the connected state as SendPacket(byte[] Buffer) does, thus calls to ReadArea and some other Read/Write methods may throw an NullReferenceException.
Could you please update your NuGet package to support .Net Core? The sharp7 library should work flawlessly on this plattform, but the warning in Visual Studio (because of the wrong target framework) is a little bit annyoing.
Hi,
I'm testing a connection with a S71500 PLC via VPN.
I'm reading different DB Areas from different DB.
Everything run fine.
Sometime, with the Internet traffic, one of the read fails with Tcp Read Data error and usually some data are still to be read (maybe data arrive later).
The Flushing included in method WaitForData is performed before the next read, but if TCPSocket.Available is less than the next read data size, the flush will not perform. Is it right ? In this case I will receive, within the next read, wrong data.
Thank you
In file S7Client.cs line 1726 currently is:
PDU[24] = (byte)Seq_in;
Should be:
S7_SZL_NEXT[24] = (byte)Seq_in;
Hello.
I would like to ask if this is possible. Perhaps I am wrong, but the examples that i have read in the documentation is that from the PC application that uses Sharp7, it can read data and write data, but it is this PC application which has to do it explicitly.
In my case, I would like the contrary, I would like that the PC application is listening the PLC and when the PLC decides to send data to the PC, then the PC could do something.
For example, if the an alarm happens, the PLC could notify to the PC and then, the PC receives the alarm and can do things like send an email to notify, save the alarm in a database and so on.
If this option it is not possible, then the PC has to read data from PLC periodically, that I guess it is a worse solution.
So, is it possible to send data from PLC to PC?
Thanks.
Hi, I just wonder whether smart 200 plc is supported by this lib.
At the moment, it's not possible to emulate an S7 server without the native dll, as shown in the unit tests.
It would be nice to replace the native version of the S7 server with a completely managed one, and integrate it in the Sharp7 library, as a way to replace the native dll completely, even in an S7 Server emulation scenario.
Hi,
I don't understand why GetRealAt sometimes gives me Numbers like: 182.2499999985 instead of the actual 182.25 inside the PLC.
Anyone also experiences this issue?
I tried to use S7multivsr to write a single bit into a PLC, but it aways outputs an error code:0x01400000.
Hi~
I have found access to Process inputs,Process outpus,Merkers,Datablocks,Counters and Timers in this project,but I didn't find any way to access V memory of Plc(s7-200), did I miss something or the project does not support it now?
S7.SetBitAt give ambiguous definition error code.
Error BC31429 'SetBitAt' è ambiguo perché esistono diversi tipi di membri con lo stesso nome in class 'S7'.
Both definition have same parameters, the only difference is in the Byref.
<Obsolete("Use SetBitAt as extension method")>
Public Shared Sub SetBitAt(ByRef buffer() As Byte, pos As Integer, bit As Integer, value As Boolean)
<Extension>
Public Shared Sub SetBitAt(buffer() As Byte, pos As Integer, bit As Integer, value As Boolean)
Please keep a changelog or make releases on github (explaining what's in the release). Otherwise, people have absolutely no idea what they are getting when upgrading the version on Nuget.
Also, you should consider using SemVer https://semver.org/ for your version numbers.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.