Have you ever been disappointed in the data logging options available on your Basic panel? Ever wished it were easier to set up logging directly to a database? Or perhaps you've wanted to set up some simple simulation or test sequences without modifying your PLC control code. If you have a little LabVIEW experience, you're in luck!
Recently, I ran across an R&D scenario where we wanted to log some data from an S7-1500 PLC for analysis - a lot of data. We were using a TP1500 Comfort Panel, so this seemed like a logical place to start. Unfortunately, we weren't blown away with the built-in logging capabilities. Ideally we wanted to log data to multiple logfiles at several user configurable speeds that were saved in a format easily opened in Excel. We discovered the built-in Historical Data tool has some great features and can be very useful - but this isn't its intended purpose. Moving on from there, we tried some scripting to create our own custom logger - this was functional and, for small amounts of data, perhaps even usable. But with the amount of data we wanted to log as well as the speeds we wanted, it wasn't ideal.
As a second option, we activated the webserver on the PLC and created a datalog on the PLC itself. This was more efficient - we could control logging speeds while in operation, have multiple logs, control the format (to some extent) and, depending on how much PLC code we wanted to write, make logging user configurable. However, this again didn't meet all of our goals : now it was necessary to log into the webserver anytime we wanted to pull the data down. We could write a simple .NET application to run on a PC and pull the file down automatically using http requests, but that only solved one issue. We didn't want to use too much of the PLC memory, so we were restricted in how much data we could keep in memory (it was a rolling datalog). We also had so many channels that we couldn't store a proper header. This meant that we had to always remember what column corresponded to what data. Even with those limitations, it served its purpose.
Later, I started thinking about a few other options. I would prefer to avoid OPC, but perhaps I could set up Modbus and write a simple LabVIEW or .NET app to log data. It's a simple matter to set up Modbus on the PLC, and there are Modbus libraries readily available for both LabVIEW and .NET, so this was definitely a potential option. Or, better yet, how about using TCP/IP communication to read block data directly from the PLC. Perhaps if I set up some TCP messaging from the PLC and created a TCP Listener to collect and log the data. If only it was possible to set up S7 Communication and do a block read from an external (non-S7) application... after a few quick Google searches, I found an answer. Not only is it possible to do it, someone has already figured out the S7 TCP/IP protocol through some detailed WireSharking, implemented the drivers in LabVIEW, and shared the API on the NI Developer Community site. Their S7 communication API seems to be pretty robust. It took minimal effort to get it working here in the lab, and I was logging data directly from the PLC without any S7 programming necessary.
While the code shared on NI Developer Community is pretty much ready to go out of the box, I played around with the wrapper and added some really simple logging. Obviously, this is just a starter and is not very elegant, but with the features available in LabVIEW, your options are limitless. From setting up multiple remote PC based HMIs, to creating testing systems, to data visualization and logging - once your data is in LabVIEW you can do anything you want.
The great part of this for me was that it required no programming on the S7 side. Well, that may not be entirely true. One thing you do need to keep in mind, especially if you're working in TIA Portal, is that DBs are created by default with Optimized Block Access - this means that the address (or offset from DB start) is determined when the block is compiled and could change. If you're going to explicitly read data out of block, you'd better know where that data is. So I would suggest disabling Optimized Block Access for any DB you are reading or writing to. Also, you should take care when creating/formatting your DB. While you can configure your read/write size, I found it easier to stick to reading out a fixed size - DWORD - and parsing the raw bits into the format I needed. So if you do the same, you'd be better served to order your DB such that DWORD sized tags are starting at integer multiples of DWORD offsets... 0.0, 4.0, 8.0, etc... Similarly, 16-bit tags should be starting at WORD integer order WORD multiples... 0.0, 2.0, 4.0, etc... And if you're DB isn't a perfect multiple of DWORDS, it is probably best to add some spare/filler tags to fill it out so you can do a single read rather.
Optimized Block Access: You will likely want to disable this to guarantee your data is where you expect it.
If you'd like to try it yourself, I strongly recommend reading the NI Developer Community page and looking at the original code - it includes examples for writing to the PLC as well as reading. The comments also have some great information for targeting different Siemens PLCs (pay close attention to the slot number). I've also attached some code, although it is nothing more than some slight modification to the original posted code - a slightly different DB format (including floating point tags), some simple logging to file, and the writing removed - but it is another potential resource for ideas.
The DB used in my example - note the offsets to identify tag locations in the data block
Good luck programmers!
Learn more about DMC's LabVIEW programming services.