NI Home
Cart Cart | Help
Company Events Academic NI Developer Zone Support Solutions Products & Services Contact NI MyNI

Currently Being Moderated

S7 PLC TCP/IP Protocol Reference Example

VERSION 8

Created on: Jun 30, 2009 11:01 AM by MarcoPolo5 - Last Modified:  Nov 13, 2009 10:58 AM by MarcoPolo5

Introduction

This example provides a library of LabVIEW VI's that can be used to communicate with a Siemens S7-300 PLC via an Ethernet port over TCP/IP.

 

 

Details

This example communicates with a S7-300 series PLC through Ethernet TCP/IP - no adapter is needed. The example provides an API to read from / write to registers on the PLC. This example was not created from a protocol specificaion, but through reverse engineering sample data sent between a PC and S7 PLC. Use at your own risk.

 

S7_TCP_API_2.PNG

Download Versions

Siemens S7 TCP v3_3 LV 8_5.zip

     This code is setup to be fault tolerant; i.e. - if a cable is disconnected or connection is lost the "S7_Error_Reconnect.vi" can be called to cleanup the bad connection and re-open a good connection. There are some optimizations for reading multiple registers from a single DB block.This code is derived from the Serial MPI S7 Protocol Exaple

 

S7Com_2009_11_06.zip

     This code was provided by a fellow developer (thanks!) and uses a slightly different architecture.

 

Note - the attached files are experimental VIs provided for educational purposes only.  No warrantee is expressed or implied.  You should test your code and completely understand the implications of writing to or reading from an operating PLC.

 

Downloads:
Average User Rating
(3 ratings)




qzxin qzxin  says:

It's useful,but missing one vi named S7 Read Write Cluster Array.vi.

MarcoPolo5 MarcoPolo5  says in response to qzxin:

sorry - missed that VI. Uploaded a new zip file with it included.

sørenhallbergjensen sørenhallbergjensen  says in response to MarcoPolo5:

Very nice code. Thanks for sharing.

 

Any chance that this will work with the 200 series attached with an Siemens ethernet module ? (S7 224XP PLC with the EM243-1 Ethernet module)

 

/søren

MarcoPolo5 MarcoPolo5  says in response to sørenhallbergjensen:

I am not aware of the differences with the CP 243 ethernet module vs the 343 (which this code was used with) - I could not say if it would work or not. If it does not work, you might be able to find some information through http://libnodave.sourceforge.net/ (an open source S7 PLC data exchange code) helpinig find where the LabVIEW code needs to be changed for 200 series communication.

TS9 TS9  says:

This is a very cool code.  Thanks.   One problem I have is the Read works fine but the Write returns error 66.  Is there a port I need to open up or something else to grant access to? 

Have you compared this performance wise to DSC with an OPC connection?   With just a limitied number of reads it seems pretty fast but I'm wondering if it will slow down with a larger number of register reads or writes.

MarcoPolo5 MarcoPolo5  says in response to TS9:

The program uses the port 102 for communication. If you are getting error 66 " The network connection was closed by the peer." - then you might want to double check that you are not trying to write to read-only registers. But I have used this program almost exclusively for reading registers - there could be a bug with some writes. The register read speed should scale linearly with the number of registers desired to read - should be same with OPC - but I have not benchmarked it. My guess is that it would be faster than OPC having the direct call to registers. There are ways to optimize reading large chunks of DB blocks - if you need this, let me know.

TS9 TS9  says:

Hi, thanks for the reply.  No luck with the writes yet.  I tried testing to some memory bits as well as a few different DBs.  They should not be read only registers.

I'd be interested in optimizing reading large chunks of DB blocks.  One of the problems with our current PLC program is that the HMI reads read all over the place.  We are in the process of consolidating all the HMI ins and outs to a couple data blocks.  -Thanks.

MarcoPolo5 MarcoPolo5  says in response to TS9:

I added a newer version of the VI's that I have used. I do not have a S7 to test the code with anymore, so if there are bugs and you find a fix, please post them back on this site. The new version (3.1) does have a "optimization" routine that will group reads from the same DB block in a single TCP read. If most of your data is from a single DB, it will be significanly faster. The optimization will not work if you are reading to locations other than DB blocks.

bobi bobi  says in response to MarcoPolo5:

Reading working OK. But when try to write, there is error "66". Where is the problem?

sørenhallbergjensen sørenhallbergjensen  says in response to MarcoPolo5:

MarcoPolo5

 

Thanks again for sharing your code, certainly do apriciate it.

 

I had a chance to test the S7 communication (EM243-1) yesterday. The TCP/IP vi's connect on port 102 without any problems, but the hex chars :

"TPKT" and "Connect to Adapter" send from the VI "S7_Init_Adapter_TCP.vi" fail to awaken the module since I get a TCP read timeout when trying to read the expected 22 char return answer.

 

Siemens wants aprox $4000 for the MPI protocol, so I realy wanted to see if I could get away with not investing this amount.

 

To test that the S7-system was functional, I configured the NI OPC Server with the S7 driver (2 hours trial mode duration). This worked fine and I was able to configure tags for certain addresses from the S7 and directly port them to Shared Variables.

 

I am trying to implement a GUI for the S7 on a WinCE 5.0 touch panel from IVCDisplays.com running LabVIEW PDA. On this platform I can't operate the NI OPC Server, however, raw TCP/IP calls work just fine so this would be a good entry point to making nice-looking GUI's for S7 installations.

 

The NI-OPC server was configured with a TSAP 1001, I dont have any idea of what than means, but a S7 guy told me that was needed.

 

Does anyone out there have a bit more information on the MPI protocol from Siemens ?

 

Greetings from Copenhagen Denmark.

/søren

MarcoPolo5 MarcoPolo5  says in response to sørenhallbergjensen:

You can use Wireshark (

http://www.wireshark.org/) to scope the packets on the TCP/IP connection to the CP-243. Compare what you see with the OPC Server and the LabVIEW code. The connection hex values are slightly different depending on what type of adapter you are connecting to (I have used both a serial and CP-343). The read/write transfers should be the same. Hope that Helps. If you find out what the difference is - let me know.
Lucianogob Lucianogob  says:

Hi,

 

I'm from National Instruments Brazil, and a customer just downloaded this code, but he is looking for a code that can communicate with multiple PLCs. Does anyone have a code that can do this?

Thanks.

Regards

TS9 TS9  says:

Hi,

   Finally had some time to look at this again and try to determine why I can't get the Write mode to work.  I downloaded Wireshark to compare the difference between what this code sends and what my OPC server sends when it asks for the same info.   Unfornuately I'm very much a newbie with TCP protocol in general so I'm essentially deciphering it based on your comments in the code and some, so far not so good, web searches. 

 

Here's what I got so far...  hopefully you can follow it ok - I'm disecting the data packet and noting any differences between the OPC server and this code.  Sorry if I mess up on the nomenclature a bit.

 

    When sending a read request, the packet data is nearly identical.  The only difference is what your code has labeled sequence # is 3301 in LV and 0066 in the OPC server.   However both work so I'm assuming that seq # is not that critical.

 

 

     When sending a write request, the packet data has some more differences.

PDU Header is the same

Seq # is 4401 in the code and 09C0 in the OPC server

Packet length (I think that's what it is) is the same at 0E

Write data length?  the code had 0005, OPC server has 0008, but the comments in the code say 8 - I switched it but made no difference

 

Everything built in the S7_Msg_Parameters vi was the same  (from write mode at 05 to the bit address - in my case MD70 was 0230)

   EXCEPT for transport type - the OPC server had 06 and LV code is 02  (06 is not an option in the LV code)

     I assume transport type tells the PLC something about the data type so might be a problem.

 

After for the write data section it changed more...

   The OPC server sent the entire new value (5 in my case) in one send   (00 04 00 20 00 00 00 05)  - the first part of that is write header info which is also different 00 40 00 20 as opposed to 00 04 00 08  - does the 20 and 08 indicated the length of the write value?  20 hex would be 32 bits which is what it sends down all at once.

   The LV code has the (00 00 00 05) value but it loops on this so only sends one byte down at a time (00 04 00 08 00. to 00 04 00 08 05)

So why does it loop through this byte by byte instead of sending it all at once?  I suppose it could do this if it only writes 1 byte at a time but then wouldn't it have to change the starting address if its writing a long word to tell it where to write?

 

Also, where did you find info about how this all breaks down? PDU header, transport type, lengths etc?  (I've tried searching Siemens website but it is very hard to search there.  I found some stuff on RFC1006 but not to this detail and not sure that's the message protocol being used here)

 

Thanks,

Regards

bamat bamat  says in response to TS9:

There is an excellent S7 packet dissector for wireshark at:http://sps-forum.de/showthread.php?t=28292

Registration is required for access to the files.  I do not speak German, but I was able to register by reading the German text via a google translate window.

Go to the end of the posting (now on page two) and get the latest version of s7comm_dll_090712.zip.  The source is also available.  A look at the source can reveal the possible values of many of the fields.

Problems writing with the example code may be related to the read length field.  When writing, the read length field must contain a write length parameter based on the number of data units (bytes, words, dwords), not bytes.

I am working on this using a S7 318-2DP + CP 343-1 and a bridge device.  When this device opens its connection there are two frame exchanges that the example does not have.  The first is labeled as a TPKT Connection request.  The PLC answers this with a connection confirm.  The second exchange is a ISO/S7 Comm exchange that wireshark identifies as S7 PDU negotiation.

bobi bobi  says:

What is the maximum reading and writting lenght (for one item)? I try and it works till 10 bytes (reading). If I try with more then 10 i get empty response.

MarcoPolo5 MarcoPolo5  says in response to TS9:

TS9 - "S7Com_2009_11_06.zip" was forwarded by a fellow developer. See the file in the download section above. The code is a little different from the original code, but read and write should both work.

MarcoPolo5 MarcoPolo5  says in response to bobi:

bobi - "S7Com_2009_11_06.zip" was forwarded by a fellow developer. See the file in the download section above. The code is a little different from the original code, but read and write should both work.

kunalb kunalb  says in response to bamat:

I could find the solution on not writing in DB of PLC. There is a very small mistake in the code; the packet size for both write and read request remains same, where as it is different for both.

 

You need to alter a vi "S7_Read_Write_Data_TCP.vi" to solve this issue.

 

Fourth byte (index 3) of the packet "S7 Ethernet Data" should be replaced by the size of the total packet. This packet is generated by "S7_Build_Message.VI" connected to "TCP Write" vi.

MarcoPolo5 MarcoPolo5  says in response to kunalb:

Kunalb - thank-you for your catch of the write bug. I made some edits based on your feedback and what is also in the S7Com code - the new code is uploaded as Siemens S7 TCP v3_2 LV 8_5.zip. I do not have hardware to test these changes. Can you or anyone else give me feedback if the write bug is fixed?

kunalb kunalb  says in response to MarcoPolo5:

I tried with the new zip, unfortunately it didn't work.

 

I have uploaded the API lib zip.

Please check the vi "S7_Read_Write_Data_TCP.vi" I have modified.

 

Using this API lib, I could read/write 100 bytes of single DB.

I have not tested rest of the VIs (read_write_cluster_array, etc.). Might require to alter accordingly.

 

I have tested this code on PC as well as cRIO.

MarcoPolo5 MarcoPolo5  says in response to kunalb:

kunalb - thank-you for the fix. I incorporated your VI's into the 3.3 version of the code now posted

More Like This

  • Retrieving data ...