Home / C# / How to write a Siemens S7 plc driver with C# and Sharp7

How to write a Siemens S7 plc driver with C# and Sharp7

Sharp7 is a new C# driver to communicate to Siemens S7 Plc. The driver has been written by Davide Nardella, the author of Snap7 library, and it’s retro-compatible with the C# wrapper of Snap7. So if you were using Snap7 and the C# wrapper, you can easily replace both with Sharp7 library.

One of the biggest advantages of having the full library in C# is during debugging. You can place a breakpoint in Visual Studio and debug the messages sent and received from the TCP socket without having to leave Visual Studio and without having to use network sniffers or other external software.

Also with Sharp7 it’s easier to read/write multiple variables in a single request than with Snap7. Now ReadMultiVars and WriteMultiVars don’t require pointers and memory management.

Watch on Youtube

Download

The official website of Sharp7 is http://snap7.sourceforge.net/

Sharp7 can be downloaded from Sourceforge download page: https://sourceforge.net/projects/snap7/files/Sharp7/

sharp7-folder

The downloaded archive contains 3 folders:

  • Src: contains the sources of the library. In case of Sharp7 this is the library itself, as there are no binaries to be included
  • Doc: contains the user manual in pdf
  • Examples: contains 4 examples, one for Windows Forms, two for Console application and one for UWP

Documentation

The library comes itself with a complete user manual and examples for Windows Forms, Universal Windows Platform and a simple Console application. Usually, any user manual would be required to have instructions in at least 2-3 other languages to create ease for international customers. For this purpose, the expertise of a traduction technique (French: technical translation) service company would be necessary to ensure the accuracy of the directions conveyed to the end-users.

As for this particular manual, there are some sections that are really important:

  • Compatibility (page 9): this section shows the compatibility of the library functions with the plc that you are using. S7300-S7400 supports every function, while newer plcs can only read and write data.
  • Connection (page 10-11-12): this section shows how to setup and configure the CPU and DB to grant the access to external software.
  • Connection parameters (page 22-26): this one explains how to setup IP, rack and slot of the plc, in order to be able to communicate.
  • Read/Write function description (27-34): contains the definition of the functions that you will use the most, to read and write memory area.
  • Helpers and example (57- 61): contains the definition of conversion function from .Net to S7 variables and some examples.

Configuration for S7-1200

To test the library we will write a simple console program. It will show how to connect/disconnect, read and write block of DB and multiple variables.

In this example we will connect to a S7-1200 plc. This unit has to be configured properly (see page 12 of the user manual).

So let’s uncheck optimized block access for every DB (under program blocks) and configure the CPU protection.

s7-1200-config-1

Creation of the sample project

When importing Sharp7, the best approach is to create a C# Class library project and place Sharp7 sources inside that project.

sharp7-create-new-proj

sharp7-new-project

sharp7-example-solution

Then we will reference the Sharp7 project in all the project that we need.

screenshot-2016-10-20-01-03-16

add-reference

Connection to the plc

Driver creation, connection and disconnection are really easy to do.

// Create and connect the client
var client = new S7Client();
int result = client.ConnectTo("127.0.0.1", 0, 1);
if(result == 0)
{
    Console.WriteLine("Connected to 127.0.0.1");
}
else
{
    Console.WriteLine(client.ErrorText(result));
}

// Disconnect the client
client.Disconnect();

Read from DB

Reading from a single db is also simple, but you must be comfortable with using buffers, converters and the snap7 functions.

To read for example 18 bytes, we need to create an array of 18 bytes. Then pass it to the Read function to populate it with the data from the cpu, then convert all the data from S7 format to C# format.

db1-read

For example this is the code to read this DB:

Console.WriteLine("\n---- Read DB 1");

byte[] db1Buffer = new byte[18];
result = client.DBRead(1, 0, 18, db1Buffer);
if(result != 0)
{
    Console.WriteLine("Error: " + client.ErrorText(result));
}
int db1dbw2= S7.GetIntAt(db1Buffer, 2);
Console.WriteLine("DB1.DBW2: " + db1dbw2);

double db1ddd4 = S7.GetRealAt(db1Buffer, 4);
Console.WriteLine("DB1.DBD4: " + db1ddd4);

double db1dbd8 = S7.GetDIntAt(db1Buffer, 8);
Console.WriteLine("DB1.DBD8: " + db1dbd8);

double db1dbd12 = S7.GetDWordAt(db1Buffer, 12);
Console.WriteLine("DB1.DBD12: " + db1dbd12);

double db1dbw16 = S7.GetWordAt(db1Buffer, 16);
Console.WriteLine("DB1.DBD16: " + db1dbw16); 

Write to DB

The Write function works in a way which is really similar to the Read function. We have to create a buffer, populate it with the data (converted in S7 format) that we need to write, and then call the Write function.
In this case we want to write these values:

db1-write

So we need to create a buffer of 12 bytes, populate the first 4 with a real number, the 4th-7th with a Dint number, the 8th -12th with a DWord number. Also, since our buffer starts from 4.0, we must set the start index to 4.
One has to be really careful with indexing, so what I usually do when creating the buffer is to use the real offset of the variable and to subtract the start index.
So here is the code to write DB1.DBD4, DB1.DBD8 and DB1.DBD12:

db1Buffer = new byte[12];
const int START_INDEX = 4;
S7.SetRealAt(db1Buffer, 4 - START_INDEX, (float)54.36);
S7.SetDIntAt(db1Buffer, 8 - START_INDEX, 555666);
S7.SetDWordAt(db1Buffer, 12 - START_INDEX, 123456);
result = client.DBWrite(1, START_INDEX, db1Buffer.Length, db1Buffer);
if (result != 0)
{
    Console.WriteLine("Error: " + client.ErrorText(result));
}

ReadMultiVar

Reading multiple variables in a single request is one of the most used features of S7 drivers, especially if one needs to read variables that are scattered around multiple DBs.
Example: let’s suppose, we want to read with a single request the values from DB1 and DB3.

readmultivar

So we have to create 2 buffers, in this case both of the same length, and we create an S7MultiVar variable. The S7MultiVar variables have a method “Read”, which populates all the buffers with the data from the plc.
This is the code to make the read:

// Read multi vars

var s7MultiVar = new S7MultiVar(client);
byte[] db1 = new byte[18];
s7MultiVar.Add(S7Consts.S7AreaDB, S7Consts.S7WLByte, 1, 0, 18, ref db1);
byte[] db3 = new byte[18];
s7MultiVar.Add(S7Consts.S7AreaDB, S7Consts.S7WLByte, 3, 0, 18, ref db3);
result = s7MultiVar.Read();
if (result != 0)
{
    Console.WriteLine("Error on s7MultiVar.Read()");
}

Once we called the read method, we can convert the data with the converters

db1dbw2 = S7.GetIntAt(db1, 2);
Console.WriteLine("DB1.DBW2.0 = {0}", db1dbw2);

db1ddd4 = S7.GetRealAt(db1, 4);
Console.WriteLine("DB1.DBW4.0 = {0}", db1ddd4);

db1dbd8 = S7.GetDIntAt(db1, 8);
Console.WriteLine("DB1.DBW8.0 = {0}", db1dbd8);

db3dbw2 = S7.GetIntAt(db3, 2);
Console.WriteLine("DB3.DBW2.0 = {0}", db3dbw2);

db3dbd4 = S7.GetRealAt(db3, 4);
Console.WriteLine("DB3.DBW4.0 = {0}", db3dbd4);

db3dbd8 = S7.GetDIntAt(db3, 8);
Console.WriteLine("DB3.DBW8.0 = {0}", db3dbd8);

WriteMultiVars

This function is usually used less often than the ReadMultiVars, but just in case you need it, here is how it works.
We have to create a buffer for every variable we want to write, then we populate the buffer with the converted values that we want to write, and then we call the Write method.
In this case we will write the DB1 and DB3 values from offset 2 to offset 8.

writemultivar

Again, here is the code. Pay special attention to start index and offsets.

// Write multi vars
s7MultiVar = new S7MultiVar(client);
const int DB1_START_INDEX = 2;
db1 = new byte[10];
S7.SetIntAt(db1, 2 - DB1_START_INDEX, 50);
S7.SetRealAt(db1, 4 - DB1_START_INDEX, (float)36.5);
S7.SetDIntAt(db1, 8 - DB1_START_INDEX, 123456);
s7MultiVar.Add(S7Consts.S7AreaDB, S7Consts.S7WLByte, 1, DB1_START_INDEX, db1.Length, ref db1);

const int DB3_START_INDEX = 2;
db3 = new byte[10];
S7.SetIntAt(db3, 2 - DB3_START_INDEX, -50);
S7.SetRealAt(db3, 4 - DB3_START_INDEX, (float)-25.36);
S7.SetDIntAt(db3, 8 - DB3_START_INDEX, -123456);
s7MultiVar.Add(S7Consts.S7AreaDB, S7Consts.S7WLByte, 3, DB3_START_INDEX, db3.Length, ref db3);
result = s7MultiVar.Write();
if (result != 0)
{
    Console.WriteLine("Error on s7MultiVar.Read()");
}

Sample code

You can find the sample code and the Plc program on Github: https://github.com/mesta1/Sharp7-example

158 comments

  1. I don’t thing the Siemens project (the one loaded in the portal) is in the download – at least I cant seem to locate it.

  2. is it work in simatic manager?

    • Yes of course.

      • So.whats different between wincc and C#? Wincc is easy.I can edit dB in wincc (read or write)!why use c#?

        And
        How find component C# for Hmi?

        • WinCC, like all other HMI packages (FactoryTalk, Wonderware, iFix, …), is absolutely fine for the most of the tasks. You can do almost everything that you can do with C#.

          However, I find that more and more OEM that write their own software without those HMI packages.

          There are some advantages of using C# instead of WinCC or other HMI, for example you can use a version control software like Git, you can do countinous integration, unit testing, automation tests, etc. Also software written in C# scales well if you have a lot of programmers working on it.

          Also if you need to integrate external software, dlls, strange stuff from different vendors, custom protocols, custom hardware, I think that these HMIs may have some limits.

          One thing has to be clear, C# is more expensive because the learning curve is more steep.

          For the components there is something online, but the most components for industrial automation are not free. However it’s not that difficult to write such components. And if you need charts, gauges and other controls, there is plenty of them. This is just an example http://wpftoolkit.codeplex.com/

        • Why not to use WinCC?
          Because you have to pay for each and every runtime. I’ve installed more then 20-30 C# runtimes in my factory. Just think how much I saved.

          C# is costly??
          You only care for learning curve if you are working in Western Countries. In Asia learning curve doesn’t matter. 1 WinCC license is equal to 5 months of fresh automation engineer salary.

          Finding Components?
          Everything is available on google till you don’t use HMI word. Don’t try it to look like conventional HMI. graphs bars etc are available easily. and if you really want hmi symbols. Use free trial of symbolfactory.

        • c# is open to EVERYTHING, and gives you full freedom. wincc is closed, so you can do only what siemens lets you

  3. hi! io lkearning how o use this for a Project, now I have followed every step in your tutorial, but at the momento of running my program the buffer on the readresult variable always is 262144, I download it the plc program to my plc I´m using a CPU 1212C with tia portal v14, I configured the DB and the protection of the plc and my program connects with the adress but does not read anything, since I used your program the buffer suze that I used is 38

    • 262144 is Bad Datasize passed to send/recv. It means that you are probably reading more than you can read. I suspect that your DB has less than 38 bytes.

    • Hi, did you find a solution. Same here but the DB size is right…

      • Did you check “Allow PUT/GET under security tab of plc settings”?

        • Yes. I left the application running for a while and noticed that sometimes it succeds and sometimes not (with error 262144). I need to read a DB constantly and the system is multi thread. May it be an issue?

        • Yes, multithread is an issue. Its better to you as many connections as many threads you have. I tested this several times. But watch your number of connections.

        • I was using the same client (S7Client) for read AND write. Now I have a new instance for each thread (one client to read, another to write) and it is working fine.
          Thank you!

        • You can use a lock or a semaphore instead of different sockets. I think there are examples in the latest articles.

  4. Hello! Thanks for the tutorial. First time I used the S7.Net library, but I was only able to get it working with PLCSIM, not with real PLC. So I found this Sharp7 library and your tutorial. But the problem is that I am a newbie and can’t really figure out how to manage simple tasks like writing/reading the PLC outputs (like set Q0.0 to 1) or memory bits (e.g. read what value is in M2.1). My attempt so far was something like this: client.WriteArea(0x82, 0, 0, 1, 0x01, new byte[] {1}), which was meant to set the state of first output to 1, but it didn’t work. Could you please guide me on the right way?

    • Sharp7 has some helpers that should be used instead of ReadArea: MBRead, MBWrite, EBRead, EBWrite, ABRead, ABWrite. M is the memory area, E probably are inputs, and A are outputs. German abbreviations.
      If you need to write a single bit, without modifying the other bits, I wrote an helper in a recent article, maybe you can take a look at it and get some inspiration.

      /// <summary>
      /// Writes a bit at the specified address. Es.: DB1.DBX10.2 writes the bit in db 1, word 10, 3rd bit
      /// </summary>
      /// <param name="address">Es.: DB1.DBX10.2 writes the bit in db 1, word 10, 3rd bit</param>
      /// <param name="value">true or false</param>
      /// <returns></returns>
      private int WriteBit(string address, bool value)
      {
          var strings = address.Split('.');
          int db = Convert.ToInt32(strings[0].Replace("DB", ""));
          int pos = Convert.ToInt32(strings[1].Replace("DBX", ""));
          int bit = Convert.ToInt32(strings[2]);
          return WriteBit(db, pos, bit, value);
      }
      
      private int WriteBit(int db, int pos, int bit, bool value)
      {
          lock (_locker)
          {
              var buffer = new byte[1];
              S7.SetBitAt(ref buffer, 0, bit, value);
              return _client.WriteArea(S7Consts.S7AreaDB, db, pos + bit, buffer.Length, S7Consts.S7WLBit, buffer);
          }
      }
      
      • Thanks, I tried it and was able to get it working with PLCSIM. With this code I was able to set the Q0.0 to 1: client.ABWrite(0, 1, new byte[] { 1 }); However when I download the same TIA project to my real S71200 plc and try to set the Q0.0 with the same C# code, it connects OK, but the ABWrite method returns error code – ISO : Invalid PDU received (the same error happens when using other methods like EBRead, MBWrite, MBRead, DBWrite,…). I have double checked that in the PLC properties the PUT/GET check box is checked and Full Access is granted. Have you tried the Sharp7 library with a real PLC not only PLCSIM? The same thing happens with S7.Net driver. I have thought that my PLC could be faulty, because when I want to Flash LEDs through TIA Portal an error dialog pops up saying: “The target online device does not support LEDs Flashing or is not reachable.” However everything else works okay, I can Go Online, monitor values, force values throught Force table, PLC program runs ok. Do you have experience with such behaviour or am I missing something when I transfer from PLCSIM to real device? Thanks for your time.

        • No I don’t have a real plc to try and personally I just use DB and map everything to DB.
          You better contact the authors at this address to ask for clarifications: https://sourceforge.net/p/snap7/discussion/

        • im working with two s71200~1215, and it works fine,Although I use snap7 instead of this sharp version,i guess its the same thing.DId you configure the CPU protection?

        • Hi! Yep, I configured everything according to the tutorial. I suspect there is problem with the firmware version of my PLC.

        • hello , i’m working on the same thing, i want to read and wite I/O from real PLC and mermory adress could you tell me please how it wordked for you , could you please help me how to code it with c#

        • Hello! I wasn’t able to get it working with real PLC, only with PLCSIM. I used the code @mesta posted few comments above, but slightly modified.

          1. Example – Writing to Memory bits byteIndex-th byte:
          plcClient.WriteArea(S7Consts.S7AreaMK, 0, byteIndex, 8, S7Consts.S7WLByte, new byte[]{0,0,1,1,0,0,1,1});

          2. Example – Reading PLC outputs
          plcClient.WriteArea(S7Consts.S7AreaPA, 0, byteIndex, buffer.Length, S7Consts.S7WLByte, buffer);

        • hi again, thanks for your reply, can you plz give me the result of the examples, and for the 2nd one, isn’t a Reading PLCOutput? so we have to put Client.ReadArea(..), isn’t it?

        • Yes, you are right, I’ve made a mistake there 🙂 The result of first operation should be that the PLC memory bits will be set according to the values of the byte array => It means that memory bits from M0.0 to M0.7 will become 0, 0, 1, 1, 0, 0, 1, 1. The second example reads the state of PLC outputs and saves them to the passed buffer (again byte array).

        • ok, i got it,
          I was able read the Input//output//and the memory adress but only with plcsim for S71500 and i havn’t the plcsim for S71200 witch i should work with!! i have a real PLC 1215 C but when i execute the same code of reading data with c# , an error is shown every time! (Invalid buffer passed to send/receive) Have you found this error before?

      • The manual shows that ” When WordLen=S7WLBit the Offset (Start) must be expressed in bits.” . So I suppose the offset should be “pos*8+bit”?

        • Yes,you are right .After two days of attempts, I got control for S7WLBit with node.js.There is very little info about this.Try this way:if the address is 2000.1,writeArea(s7Client.S7AreaDB,DBNumber,2000*8+1,buffer.length,s7Client.S7WLBit,buffer,callback).Make sure that s7Client has been initialized and buffer is something like this: new Buffer(“1”); WeChat 15216719714

      • Hello, i try read data of 1 PLC from 2 diferent devices, but when two programs run i have a troubble of communication tcp i’m but devices.
        You has have this problema?

  5. Hi,
    Thanks for your tutorial, i begin in C# and open-source HMI.
    How to read any DATA from multiple PLC ??
    Create loop for change connection ??

    Thanks for you’re answer.

  6. How do you write just one bit to PLC?

    • This is the code that I used in a recent video. It is part of a bigger application, you can find the sources here: https://github.com/mesta1/HMI-with-WPF-part-2-Navigation-with-PRISM/blob/master/SimpleHmi.PlcService/S7PlcService.cs

      /// <summary>
      /// Writes a bit at the specified address. Es.: DB1.DBX10.2 writes the bit in db 1, word 10, 3rd bit
      /// </summary>
      /// <param name="address">Es.: DB1.DBX10.2 writes the bit in db 1, word 10, 3rd bit</param>
      /// <param name="value">true or false</param>
      /// <returns></returns>
      private int WriteBit(string address, bool value)
      {
          var strings = address.Split('.');
          int db = Convert.ToInt32(strings[0].Replace("DB", ""));
          int pos = Convert.ToInt32(strings[1].Replace("DBX", ""));
          int bit = Convert.ToInt32(strings[2]);
          return WriteBit(db, pos, bit, value);
      }
      
      private int WriteBit(int db, int pos, int bit, bool value)
      {
          lock (_locker)
          {
              var buffer = new byte[1];
              S7.SetBitAt(ref buffer, 0, bit, value);
              return _client.WriteArea(S7Consts.S7AreaDB, db, pos + bit, buffer.Length, S7Consts.S7WLBit, buffer);
          }
      }
      
  7. Here is something I’ve accomplished with help of this article: https://github.com/stefan-schindler/plc-programmable-3d-simulation. It’s a 3D interactive simulation of a packing machine which communicates with PLCSIM via Sharp7, basically it writes the inputs and reads the outputs. So thank you once more for great article 🙂

    • Hey this is a great project ! I will try it out in the next days, thanks for posting it!

    • I want too 🙂

    • again hello 🙂
      unity mono using and debugging 3.5 net framework and i added dll sharp 3.5 net version but i dont work dll why ?

    • Hi Stefan, nice project. I’m working on something similar, and I have an issue with “Method not found: ‘System.Net.Sockets.Socket.Dispose’.” when using client.disconnect. It seems to be from the .NET version that Unity uses, so I’m wondering if you found a fix for this, or if you just ignore the error. Thanks!!

      • Hello, thanks 🙂 Have you configured the project to use full .NET framework not just the subset?

        • I’m not sure where that set up is? From what I find, Unity only uses up to .Net 3.5. I’m using Visual Studio for my C# editor, but I think that is irrelevant to what happens within Unity. Could you point me in a direction for full .NET Framework please. Thanks.

        • Thanks for pointing me in the right direction! Unity was set to use “Stable 3.5” instead of “experimental 4.6”. Once I changed that, it fixed an issue with using System.Threading.Tasks, which led to excellent communication between Unity and PLC. For anyone else: In Unity, Edit/Project Settings/Player, then change the Scripting Runtime Version. Thanks Stefan, Mesta, and Sharp7!

        • ndoell or Stefan, can you confirm if you are using real PLC, and not just PLCsim? I am building a auxiliar engine project for a company and want to deploy the real simulation on unity. Thanks

        • For me, it only worked with PLCsim, I could’t get it to work with real PLC (talking about S7 PLC driver).

  8. plz I need PLCsim V13 for S71200 v, could somebody give it to me or tell me how can I get it !! :/

  9. I am amazed by the fact that you did reply every question. Gj man.

  10. Hello! I wasn’t able to get it working with PLCSIM, All examples : Sharp7Example, CSClient, VBClient the result the same “TCP Error receiving data” during make connection.

  11. Not working any more. Error ISO – invalid buffer passed to send/receive – 262144

  12. Is it possible to monitor PLC valiables continuously, if so, which is the best way to do this?
    Thanks in advance!

  13. hi wich hardware please !!can you help me ..

    • It works with Siemens S7 plc.

      • yes it’s siemens S7 plc , i tried at first to work with a real plc 1214C DC/DC/DC and it worked, but i have to make the communication with the plc cpu1215C dc/dc/dc , could you help me please what could it be the problem ?

        • Firmware update or CPU protection settings (scroll down and check Permit PUT/GET) or DB not marked for access.

  14. Hi Michele, first of all: Great job! You have explaned everything clearly and it was working with the first try.

    Now my question: ok, PLC data I have now in my C# program, but how to talk via RESTapi to another server? I have sample code in PYTHON which is working, but I would like to have the software in one “piece”.

    What is missing is the knowledge how to make the structure from the beginning.

    • If you want to create a REST api that exposes Sharp7, just create a WebApi project from Visual Studio.

      • Would you help me to getting started? It’s commercial so I don’t have a problem to talk about an official order.

        • I will put togheter a small project during the weekend and publish it, then we see.

        • That sounds incredible! If you want I could send you by email the API documentation and the corresponding PYTHON samples, but it is from a third party and therefore confidential.

          PS: Obviously you are a night owl too. 8)

        • Ok you can send the documentation at michele.cattafesta [at] mesta-automation [dot] com, so I will have a better idea on your requirements.

          And yes, I am a night owl too 🙂

        • Good morning, email is sent. Cheers

  15. hello
    i have problem.
    i want only change db1.dbw16 (just)
    ==========
    var writebuffer = new byte[18];
    S7.SetIntAt(writebuffer, 16, Convert.ToInt16(textBox1.Text));
    ============
    when i want set it. all byte Except this will be zero
    i want just change value db1.dbw16.but when i change it. all data except this will be zero.
    please help me
    thanks

  16. Hello Mesta.
    Your articles are greate!
    After them, i connect and read / write some variables in DB.
    But i still can’t read any String variable from DB.
    Could You please explain how can i get this?
    Thank You,
    Eda

  17. Hello
    can you give me example how read from timer? for example T1?
    thanks

  18. How speed read and write DB?

  19. I use 8 thread. Each a thread, I create a connection to PLC, to write value to DB.
    Thread 1: client 1, write value to DB1
    Thread 2: client 2, write value to DB2
    …..
    Thread 8: client 8, write value to DB8.

    Can they run parallel.

    • Of course they can run in parallel. You can check if the plc is accepting the requests by checking the result returned from the DBWrite method.

  20. Hi Mesta,
    Thank you vary much!

    I have retrieved data successfully from a PLC on a machine I work with. I don’t write anything to it, only read from DBs. Now there are problems with the machine and the company I purchased it from said that it maybe because of what I am doing.

    The only changes that where done, where to uncheck optimized block access for DBs and configure the CPU protection as you explained and it does not make sense to me that this would cause a problem.

    So my question is, do the Snap7 / Sharp7 libraries make changes to the PLC DBs or code to be able to retrieve data?

    Thanks again!

    • After some experimenting it looks like the changes of uncheck optimized block and configure the CPU protection where the cause.
      If you know of anything else that could be please write back.

      Thanks

      • Unchecking optimized block changes the memory structure, because Siemens seems to do some optimizations on the memory occupation. When unchecked, the old S7-300 memory structure is used, with absolute addressing.
        It seems strange to me that checking and unchecking the optimization changes the behavior of the program.
        Can you get some info from Siemens about this ? It seems quite a dangerous “feature”…

  21. Hallo

    thanks for the great tutorial , but at the risk of appearing like a total nut ,

    i seem no to be able to get started . i am very much new to the subject , being through the Reference Manual
    but i can’t get connected to neither my physical plc nor PLCSIM

    i am using TIA Portal V14 , PLCSIM V14 , on windows 10 . and every time i tried to connect to the PLC as shown in this
    tutorial , it fails , with the error type :” errTCPDataRecv : 0x0003 : TCP error receiving the data.” being returned .

    I certain that i have missed some necessary set up ( connection configurations ) that i hope you could help me with .

    Ps: List of additionnal firmware needed will also be helpful thx

  22. Hello,

    I am using Simatic Step 7 Professional V13 (without SP1) and PLCSIM V13 (without SP1). Everything is running on the virtual machine.

    Simulation mode works fine without Sharp7 application. When I run the Sharp7 application (exactly as described in the tutorial), I get this error “TCP : Error receiving Data”. I checked again and again and I am sure that I have done everything correctly.

    I have no idea what am I missing? I need help.

  23. Hi,

    I am trying to read a Real data with GetRealAt() function. The Real value in DB is “39.505”. But when I read the data the value I get is “39.5050010681152”. Any idea why do I get this value?

  24. Sorry, but where to download? All Sourceforge-Links are down! 🙁

  25. Hello. I have LOGO 8 Running, reading works. Writing EBWrite, ABWrite, MBWrite does not work (error res = 7). Help Pls

    public static bool metZapisBit(ref S7Client client, int bit)
    {

    // bit 1-10;

    bool zpet = false;

    byte[] Buff_M = new byte[64];

    S7.SetBitAt(ref Buff_M, 0, bit – 1, true);

    int res = client.MBWrite(0, 1, Buff_M);

    if (res == 0)
    {
    zpet = true;
    }
    else
    {

    zpet = false;
    }

    return zpet;
    }

    Thank you Richard

  26. Hello Mesta
    i have been able previously to connect to the PLC and read from the DB
    but when i do try to do so now , i receive an invalid Block Size error ( errCliInvalidBlockSize = 0x01900000 ) error , even though the connection has been successfully established with the PLC .

    Can’t really identify the problem , tried to same program to worked before , but still nothing . I also re downloaded the library , but still no success .!

    thanks for your help , once more !

  27. Hello Mesta.

    Can you explain me how I can configure the connection between Sharp7 and a CPU319 with PLCSIM?
    Because when I testing connection with “ping”, I can’t see the cpu.

  28. This sharp7 is working for tia portal ? Can we use sharp7 by step5 s7300 project?

  29. Can we use sharp7 by step5 S7 300 project?

  30. Thanks a lot for the article. All works perfectly !
    I have a question.
    There is a way to check the plc connection ?
    Connected property (or connect() method ) not update it’s state if, at runtime, disconnect LAN cable of the PLC .
    Thanks a lot.

    • In S7.net we use this:

      public bool IsConnected
              {
                  get
                  {
                      try
                      {
                          if (_mSocket == null)
                              return false;
                          return !((_mSocket.Poll(1000, SelectMode.SelectRead) && (_mSocket.Available == 0)) || !_mSocket.Connected);
                      }
                      catch { return false; }
                  }
              }
      
      • Thanks for the answer. I already use s7.net and i check this solution but poll( ) method is not available for type of ‘msgSocket’ of sharp7. I am thinking about ping continuously Plc.

        • Sure ping works, but in some places you may find it blocked by network administrators. You can also create a socket and keep polling that socket.

  31. Hi Mesta, thanks for Your excellent work. Im Trying to read an array of char from the plc, and using DBread has you show all works.
    I declared my buffer of byte,read the db from start and stop byte by array in the DB(the char array) and i put in mystring= s7.getcharsat(buffer,start,size) and in mystring i have what i want. But only for the first time. If i disconnect and reconnect the pc to plc and repeat the command, mybuffer contains some crazy character and mystring change. How i can fix this ? Thanks a lot !

  32. i think that i’ve found the error. I ping continuously to check the connection whit the plc, and if i break cable Lan of connection, my thread looping until the ping go to success. Then it reconnects. But, if i do not write client.disconnect() BEFORE the connectTo(), some readDB goes wrong. If that possible ? Thanks a lot.

    • If it disconnects on plc side, you are responsible to clean up your sockets and restart the communication. I thought the readDB would fail. Are you checking the error codes ?

      • Yes, readDB give me errorcode 5 and 7.
        So, is the right way make client.disconnect() before client.connectTo () ?
        Thanks a lot.

  33. Hi, I have the problem with the IP address at the beginning of the video ( ConnectTo( ” IP address “, 0, 1 ), though I did exactly the step in the video but int result = client.ConnectTo(“127.0.0.1”, 0, 1) is not 0 instead it is 3 or 5, then I change both my PC’s IP address and PLC’s IP address and the result still 3 or 5. I don’t know what is happening here, I struggled for 2 days but it is still.

    I would love to accomplish the project in your video ! Please help me . Thank you so much !

    • by the way, in the TIA portal ( v14 ) I use plc S7 1214 Ac/Dc/Rly. Does it affect ?

      • You see rack and slot on TIA Portal Hardware -> Click on CPU -> general.

        • Thank you for your nice support,
          I’m building a GUI using Window Form Application, and i’m using CheckBoxes to toggle the state of the Bool variable in the DB, but when i use the DBWrite function it keeping annouce me that : “Non-negative number required. Parameter name : length”, but when i change the parameter buffer.Length into -buffer.Length it work but cannot modify the value in TIA Portal. I really need your help. Thank you very much in advance !
          And all other stuffs i’ve already finish (i.e., TIA Portal, protection, uncheck Optimize…., check Permit…. )
          Here is my code :

          using System;
          using System.Collections.Generic;
          using System.ComponentModel;
          using System.Data;
          using System.Drawing;
          using System.Linq;
          using System.Text;
          using System.Threading.Tasks;
          using System.Windows.Forms;
          using Sharp7;

          namespace Myself2
          {
          public partial class Form1 : Form
          {

          public Form1()
          {
          InitializeComponent();
          }

          private void btnConnect_Click(object sender, EventArgs e)
          {
          var client = new S7Client();
          try
          {
          int connectionResult = client.ConnectTo(“127.0.0.1”, 0, 1);
          if (connectionResult != 0)
          throw new Exception( connectionResult.ToString() );

          txtIP.Text = “127.0.0.1”;

          }
          catch ( Exception ex )
          {
          MessageBox.Show(this, ex.Message, “Information”, MessageBoxButtons.OK, MessageBoxIcon.Information);
          }
          }

          private void btnDisconnect_Click(object sender, EventArgs e)
          {
          var client = new S7Client();
          try
          {
          client.Disconnect();
          txtIP.Text = “Disconnected”;
          }
          catch ( Exception ex)
          {
          MessageBox.Show(this, ex.Message, “Information”, MessageBoxButtons.OK, MessageBoxIcon.Information);
          }
          }

          private void chkbx0_CheckedChanged(object sender, EventArgs e)
          {

          var client = new S7Client();
          var db1buffer = new byte[12];

          if (chkbx0.Checked)
          {
          S7.SetBitAt(ref db1buffer, 0, 0, true);
          }
          else
          S7.SetBitAt(ref db1buffer, 0, 0, false);

          int ans = client.DBWrite(1, 0, 12, db1buffer); ———>///////////// Something Wrong HERE

          if (ans == 0)
          txt0.Text = “OK”;
          else
          txt0.Text = “Error”;

          And my DB is 1 , bit i want to modify 0.0 and 0.1 and 0.2.

          Thank you again !

  34. Hello mesta, I need your help. m1 is running when I click on start_m1 button. but when I press the start_m2 button, m1 stops and m2 is running. and also same problem for stop buttom. im working with real plc

    private void start_m1_pb_MouseDown(object sender, MouseEventArgs e)

    {

    Byte[] db1buffer = new byte[1];
    const int start_index = 54;
    S7.SetBitAt(ref db1buffer, 54 – start_index, 0, true);

    Result = client.DBWrite(1, start_index, db1buffer.Length, db1buffer);
    if (Result != 0)
    {

    toolStripStatusLabel1.Text = client.ErrorText(Result);
    }

    }
    private void stop_m1_pb_Click(object sender, EventArgs e)
    {

    byte[] db1buffer = new byte[1];
    const int start_index = 54;

    S7.SetBitAt(ref db1buffer, 54 – start_index, 6, true);
    Result = client.DBWrite(1, start_index, db1buffer.Length, db1buffer);
    if (Result != 0)
    {
    toolStripStatusLabel1.Text = client.ErrorText(Result);
    }
    }
    private void start_m2_pb_MouseDown(object sender, MouseEventArgs e)
    {

    byte[] db1buffer = new byte[1];
    const int start_index = 54;
    S7.SetBitAt(ref db1buffer, 54 – start_index, 1, true);
    Result = client.DBWrite(1, start_index, db1buffer.Length, db1buffer);
    if (Result != 0)
    {
    toolStripStatusLabel1.Text = client.ErrorText(Result);
    }

    }

    private void stop_m2_pb_Click(object sender, EventArgs e)
    {

    byte[] db1buffer = new byte[1];
    const int start_index = 54;
    S7.SetBitAt(ref db1buffer, 54 – start_index, 7, true);
    Result = client.DBWrite(1, start_index, db1buffer.Length, db1buffer);
    if (Result != 0)
    {
    toolStripStatusLabel1.Text = client.ErrorText(Result);
    }
    }

  35. I made my graduation thesis with some of these informations that you gave. It made so much easier than I thought. Thanks to you.

    • Hello Mesta I need Your Help,
      I need Function to communicate to plc Siemens Logo V8 Using C#.net

      Thank you For Any Information

  36. Hello!mesta,
    I have a problem,i want to connect mutil plc(about 30) with snap7 in c#, so i think it is need mutil-thread,but how to using thread to start snap7,do you have any information to help me .
    thankyou.

  37. Hi Mesta,

    I create a c# project and set the setting in TIA Portal , connection done successfully and get CPU Info,SZL, and in Misc get unit status but didn’t get DB values.

    Ref : Using CSClient (C# Simple Demo) Project.

    Error Like
    ISO : invalid buffer passed to send/receive
    ISO : Invalid PDU received
    CPU: adress out of range

    Please Guide me

    Thanks & Regards
    Mihir

  38. Hi Mesta,

    Can you help me to find a way to get the data every 1000ms from the PLC? Do i need always a new connection or can i keep the connection open? is it then necassary and how to check the availability of the connection and then poll the data from the PLC? Hope you can help me with a short code around your great Sharp7Example Code.

    Thanks, Armin

  39. Hi i have a problem. I make aplication like you but i cant read DB1. I used method GetBitAt and i move value to Textbox. I use one button to connect PLC and second button to disconnect.

    private void button2_Click(object sender, EventArgs e)
    {
    int result = client.ConnectTo(“192.168.0.1”, 0, 1);
    if (result == 0)
    {
    MessageBox.Show(“Connected”);

    }
    else
    {
    MessageBox.Show(“Error”);
    }
    button2.Enabled = false;
    button1.Enabled = true;
    }

    private void button1_Click(object sender, EventArgs e)
    {
    client.Disconnect();
    button1.Enabled = false;
    button2.Enabled = true;
    }

    private void button5_Click(object sender, EventArgs e)
    {
    byte[] Buffer = new byte[8];
    HobbyTlacidlo = S7.GetBitAt(Buffer, 0, 0);
    textBox2.Text = Convert.ToString(HobbyTlacidlo);
    }

    Please help i done everithing what is on video. I have PLC Siemens S7 6ES7 214-1AG40-0XB0 frmware V4.2 Tia portal V14 Sp1. Pc ip adress 192.168.0.10 PLC 192.168.0.1

  40. Is it possible to use this to scan for Siemens PLC on the network?

  41. I am using C# , the sharp7 example to connect to and read DB . I am using the example , there i am using DBRead to read the values of Global DB. The example is able to connect but cannot read Why ?

    How can i find the size of the buffer to read the DB starts with offset 0 and ends at 12 with real type.

    I am using S7 1214

  42. Hi, I need express help. How to correctly read input from address I1.7 using client.readarea method? I cannot figure it out.

  43. Andres M. Rosales.

    Hi, Do you know how to include the “Sharp7” library in a windows form application? Because until now, I haven´t been capable to do it.
    Thanks in advance.

    • Just include Sharp7 class into a project and than call it like any other class in your project.

    • You can either add it to the project and use like a normal class, or if you are more used to the old .net ways to do it, just open it in a new project and build the dll so you can add the namespace in new projects just by adding it to the namespaces headers.
      I prefer the dll way because it makes more realiability and reusability for multiple projects. and correct me if I am wrong but i think the sharp7 already land as a compiled dll.

  44. HI,
    it’s possibile to have, in one form, multiple thread with a single connection?
    To be clearer:
    I have a class for the connection with the cpu (Siemens).
    If I try to use this connection i different thread but it fails the second time it was called.
    If I use a single connection, single thread all work fine, even if I simultanuosly open an othe form with another connection.
    What it seems to me is that the cpu accept multiple connection, but I do something wrong when using multiple thread in a single form.
    A very important thing to say. This behaviour start when I ran the project against a real cpu, in TIA emulator all works fine. It’s a cpu configuration?
    Can you help me?
    Andrea

    • Try to open a new plc client for each thread, and close it when you kill the thread ( if the thread is not looping). Remember to close the connection always. I really dont see how you may need to do multithreading in the read/write process to the PLC, you probably end up overflowing the buffer limit for the read maximun number of words, I dont remember now the exact number of this limit but was high enough.
      If you are looking for some read/write under the hood, without losing computing power in the main thread, you should use coorutines, like windows does. I highly recommend you to try sharp7 or s7.net with Unity. I did a project controling a diesel engine generator with a 1200 and Unity, wired and wireless app built on for Wind, mac, ios, android, and working as smoothly.
      High end interface tools avaliable with a huge computational power due to coorutines built-in in an so easy way. Try it, you wont regret.

  45. gravino@skynet.be

    hi
    i would like to use in VBA is possible to create a sharp7

  46. Hello. Help me please.
    In Sharp7 libraries, S7.SetStringAt accepts only 2 characters.
    I need to accept 10 characters with DB1 – data type string [10].
    How to accept 10 characters using S7.SetStringAt?

  47. fajar rukmo anggoro

    to confusing for me. SNAP implementation on python much simpler for me.

    I prefer use snap on python and communicate via socket to my C# GUI

  48. I to every one. I have problem to read a DB in a S7 1200. I saw the same problem before in the post but I can not to get read the DB. Always is the same message “Invalid Buffer passed to Send/Recive”
    I check the DB protect and CPU protrect. To the long buffer.
    Please anybody can help me?

  49. Hello,
    anyone tried it with a s7 1500?

  50. Hi,
    what is the conversion to s7 Char from C#. I mean, if i have an ‘a’ in my string, how could i write that to see ‘a’ in S7.
    Thx in advance.

  51. Excellent Tutorial!!!
    Can You help me, how I can read Continuously without any button press in C# Winform.
    Thanks in Advance..

  52. Piermichele Conte

    Hello, a question on Sharp7.
    With this library I also have access to the datalogs folder of the external memory, (memory card), of an S7-1200, or only to the internal memory (db, merkers, ..)?
    Thanks

  53. Hi, I am facing error 5 and sometimes error 3 when trying to connect a PLC, my windows service is running a taskfactory with 10 tasks each of one targets a different PLC. what does those errors mean? thx in advance

  54. I am being able to read data from DB blocks using DBGet:
    byte[] buffer = new byte[bInfo.MC7Size];
    int result;
    int longg = 1;
    result = cliente.DBGet(db, buffer, ref longg );

    But when i try to read data from OB, or another type of DB it desn’t works.
    Could someone please provide an example of reading data fron no DB Blocks?
    Thx in advance

  55. Hi, is there a way to connect to the plc using an user and password?

    • You can always code it in Csharp man, thats what this library is all about.

      • Yes, but i don’t mean that, i mean that a PLC could be protected by password and if there is a way to access it using a password, not in the C# code, i mean, passing that password to the method that connects with the PLC, or maybe this is not necessary while the PUTTY/GET check is ok.

  56. Hello. a question a on Sharp7.
    Are all the CPUs listed below compatible??
    – S7 200
    – S7 200 smart
    – S7 300
    – S7 400
    – S7 1200
    – S7 1500

  57. Alexandre nasri

    Hi,

    I used DBRead and DBWrite in my code to change the variables in a DB.
    I want to use ABRead instead in order to read all the variables, but the problem is that I don’t know how and where to find these variables in Tia Portal, and how to use the function ABRead in a code.

Leave a Reply to Anonymous Cancel reply

Your email address will not be published.