Part 12 - TwinCAT functions (using TF6250 - TC3 Modbus TCP)

Video: https://youtu.be/FOC0rUeECDs

#PLC #TwinCAT3 #Beckhoff #IEC_61131-3 #Modbus #Redes_Industriales #Networks #Industrial_Automation

🔙 Previous Part | Next Part 🔜

↩️ Go Back

Table of Contents:


A) Objectives

Welcome back! Until now I would say  that we have covered all the basics of TwinCAT.

We've learned:

Everything I've shown so far is included in the base installation of TwinCAT 3, so in other words the TwinCAT 3 XAE that we installed.

With the functionality that's  included in the base XAE, you can do the vast bulk of the stuff you need for an industrial automation  project.

However, sometimes you need to do things that require you to extend the functionality of  TwinCAT. This is achieved through what Beckhoff calls TwinCAT functions.

Beckhoff have a complete  ecosystem of functions that you can use to solve various problems. Some of the functions are very  basic, while some of them are so big that they would require their own 18 part tutorial to cover  the functionality.

In this part of the tutorial we   will look at the concept of the functions, and then  we are going to the fun part of this tutorial and install a TwinCAT function and use it to solve a  problem. Let's get started!

B) Introduction to TwinCAT functions

The TwinCAT functions are divided into a couple of different categories. Each category has several TwinCAT functions.

The first category is the TF1-series, the TC3 system.

Here we have some extensions to the  normal PLC runtimes, such as extensions to run models created in Matlab/Simulink, or editors for creating PLC software in UML


The next category is regarding  the human machine interface. So for the operator panel of your TwinCAT software.

With this category you can create a frontend using modern technologies  such as HTML5, CSS and JavaScript.


The third category is the measurement one, which for example includes tools for analytics, power measurement and the superb tool called  scope.

These tools are very useful and come in handy both when you need to do a short  and long term analysis of your process.

ScopeView is very important, you can learn more here:
Video: 🦾 Industrial Automation Courses/PLC Programming Courses/BECKHOFF/Motion Control and IO with TwinCAT by SquishyBrained/EP13 - Scope View


Next we have the controller category which  includes all the basic controllers that you might need, such as a PID controller and  various filters.

In this category you also have the TwinCAT speech which you for example can  use to send commands to your PLC using your voice


Next we have a ginormous category  which is the one for motion control.

Whenever you want to do anything in TwinCAT that's  related to motion you find it here.

Working with TwinCAT I sometimes get the feeling that half  of TwinCAT's functionality is in this category.


The sixth category is connectivity, which includes  functions for whenever you want your PLC to connect to other systems and the outside world.

I'll get into more details with this one soon.


Next we have one of the newer functions in  TwinCAT, vision.

With this you can integrate a camera into TwinCAT when you for example  want to use it for quality inspection


The last category is the industry specific.

Here you will find functions that are specific for certain industries, such as building  automation and a framework for wind turbines.


B.1) TF6xxx - Connectivity

For the rest of this tutorial, we will focus on  the connectivity category,

where we will look deeper into what functions that are actually  available here.

Each category has several functions. Some of them are already integrated  into the default installation of the TwinCAT XAE, whilst others require a separate download.

The first example of a function in the connectivity category is TF6020, JSON data  interface.

JSON, which stands for javascript object notation, is an open standard file format  and data interchange format.

This function is used when you want to exchange data between  TwinCAT, and an external application in JSON.


Next we have TF6100, OPC-UA. OPC-UA is a  cross-platform open source IEC standard for data exchange between systems, developed by  the OPC foundation.

It's an industry standard which most PLC brands understand. This function  will give your PLC both an OPC-UA server and client.


Next we have TF6250, modbus TCP.

Modbus is a data  communications protocol, originally from the 70s Lots of various devices use modbus. If you work  with PLCs you are 100% guaranteed to come across devices that only talk modbus. This is the  slightly more modern IP-based version of it.


TF6270 is a function to enable your PLC to talk  PROFINET, which is a fieldbus developed by Siemens and used as a standard fieldbus on all Siemens  PLC.

Because Siemens has such a big market share there are many devices only talking PROFINET  out there.


TF6300 is a function which gives your PLC software the capability to connect  to an FTP server to upload and download files.


B.1.1) TF6250, modbus TCP

There are half a gazillion  other functions in this category.

Probably enough to keep you occupied for weeks if you wanted to try all of them out.
This category alone could probably keep me  occupied making video tutorials for months.

For the programming part of this tutorial  we will focus on the TF6250 function,

in where we will run a simulated modbus server  and talk to it using our TwinCAT software.


Comment:
When I say that there are a lot of functions to  extend your TwinCAT 3 program with, then I really mean it. It's not just the connectivity functions, but every category that I just showed you has so much functionality that I could literally  talk for hours and hours about each one.

I wish that I had an infinite amount of time, where I could create courses and tutorials for you and include these functions also in  this tutorial.

But fact is that each and one of these categories of TwinCAT functions are a  multi-part tutorial by themself.

If you for example look at the TF2000 category,

which covers all the  different functions to make a modern web-based front-end or operator panel to your system. This  could easily be a complete tutorial by itself, just this single category.

Who knows, maybe I'll make a  tutorial about this as well? Anyway let's get back


B.1.2) How does the TF6250, modbus TCP work?

Before diving into the practical part, I thought I wanted to show you a few more details about how the TF6250 works.

So  first we have our PLC which runs the XAR,

|300

in other words the TwinCAT runtime.

As I told you  in one of the introductory parts of this tutorial, the PLC can be splitted up into two parts.

The operating system and the TwinCAT kernel,

|700

To start using the modbus function, you first  need to go to the Beckhoff website and download the TF6250 function.

This is a standard  executable that you install on your PLC.
Note: We'll do this step and all the other steps  together when we get to the programming part.

By installing this function in the PLC, there will  be a process available in the operating system for this function.

Next, to use this function, we  need our development environment, that is the XAE.

For some of the functions it's necessary to  install the downloaded function in the XAE machine as well, to get access to for  example libraries for the function,

However with TF6250, these are already  pre-installed with the default XAE installer.

Next, we need to add a reference to the  TF6250 modbus library in our TwinCAT 3 project, which we'll do the same way as we've done for  other libraries.

This library will give us access to the modbus function blocks in our PLC code.

B.1.2) // ---------------------------------------------------------------------------------------------------------------------

Once  we are done with the development of our PLC code we simply need to do an activate configuration,  which will deploy our executable on the PLC.

Once our program starts, it will try to initiate  a connection to whatever modbus servers that we have defined in the program.

Once a connection  is up and running, data exchange can occur The modbus data is initialized in the PLC program and  then sent to the process in the operating system As the operating system has access to  the network stack, the application now has a channel to send the modbus data to whatever  modbus devices that are connected to the network The modbus process will take care  of the transmission of the modbus data to the modbus servers, and also  tunnel the data in the other direction This architecture allows us to run the real-time  kernel applications asynchronous of whatever

happens in user-land. We'll get back to this  topic more deeply when we will talk about ADS Okay it's time for a little bit of programming. This part is gonna be a little bit special because we're actually gonna use two separate virtual  machines. So the configuration that I will do here is...so first of all I will demonstrate how to  use the modbus function.

So the modbus function for TwinCAT. And to do this I need something to  talk to. So normally what I would do is to just run everything from the local virtual machine Where we have the development environment, where we have the PLC runtime and where we would in this  case have a modbus simulator. I'm not going to do that now. I will have a separate virtual machine.

So the virtual machine here to the left is a separate virtual machine, where we will just run a  modbus simulator. And on the right, that's our usual development environment. That's where we will also  run our PLC code. So this is also what's simulating the PLC and where we will run the modbus function.

So the modbus supplement that we're gonna download and install. There's one thing more I want to  mention. In the modbus terminology there's this...um...so in modbus there is the definition of client  and server...are a little confusing. Because y

ou have a master and a slave and you know...I'm  not gonna use the standard definition because it it really makes my head explode, and we don't  want that to happen. I'm just gonna see this as simply...we will have the modbus client, which  will be the PLC and the modbus server which is whatever we're gonna talk to. So the modbus server  in this case...it could be a real device but you know because I don't have lots of equipment  here in my home, I will simply simulate the modbus server.

The first thing we need to do is  to go to the website of Beckhoff and download the function, the modbus function. For  that we just look for Beckhoff modbus TCP. TF6250. Okay this is in German. My german  is quite bad. "Auf Englisch bitte" And we go to software and tools. Downloads. Exe. Start download. And then we just download the supplement This supplement would normally  then again be installed on the PLC to make this bridge from the PLC code  to the operating system, where we will   have this process that will do the  communication with the modbus servers

I will install it here because here we're using  the PLC, also as as our runtime So let's install it Installation complete Another thing I forgot to mention is that  we have two different network devices. So here we have the PLC which has a certain IP address, so this specific IP address, while the modbus virtual machine, the modbus server virtual machine  has this IP address.

So we will be talking from this machine to this machine. So let's start the  development environment and create a new project A new TwinCAT project and  just call it modbus learning New PLC project So the first thing we're going to do is  to add a reference to the modbus library For certain functions then the  library is added with the installation   Which means you also have to install it  on the PLC, on the development environment With some functions this is already installed... the library is already installed with the XAE

So just look for modbus And it's this guy. So this  is the RTU version which is serial communication, while this is the TCP variant We can see here that this provides several  function blocks for doing different functions   in modbus.

So modbus has these these different  functions depending on what you want to achieve There's some function codes to read basically bits. And then there's functions to read 16-bit values so integers or words. Then there's functions  to write bits. It's just basically different functions. Modbus is an extremely  primitive protocol. You don't have the luxury to like you would have in something more  modern like opc ua where you can do a method call   and get some values or read a variable with  a certain name.

I mean this is a protocol from the 1970s, so everything is basically just getting  bits and bytes or writing bits and bytes. It's extremely primitive, but yeah. What I thought is  that we will start with some of these functions We will write a function block to read some bits. To do that we first have to create a simulation I will use this software that I have downloaded. It's for free.

There are some restrictions so you can run it only for 10 minutes at the time. Then you have to close it down and restart it But with this we can simulate the modbus server. Or modbus slave as the official name is But okay I'm just gonna use server here. Then we  can use this simulator to talk from our client And to do that we will simply start with...just  register later here.

30 days evaluation Again this is fine for us now. I will by the way  provide a link in the description below for the software so you can try this out at home. And then we want to use modbus TCP/IP with this port. This port is important to remember  here, because we will have to use this port to talk from the client.

So it's just  a standard socket basically Here we can define the slave, so we can define what function we want to provide. We  will just start with the coil. A coil just basically provides a list of bits. Then we can try to read them So we will...to read this now...so we  can for example set this one to ON To read this now we will create a function  block that will read this from the server This value from the server.

And I will just call it "ReadCoilsExample" So we will have to use a function block from  the this library called...I actually have it here MBReadCoils, where you have to provide  some inputs and you will get some outputs And the way this guy works is... You define an instance of it And then...here's a shortcut. If you press F2... You can do text search.

ReadCoils, and then it  will provide just all inputs and outputs, which is quite convenient. So you don't have to enter  them manually, like you would maybe normally do The IP address is the IP address of  this virtual machine so it's 192.168.5.34 The port is 502. The unit id according to the  documentation, is identification number blah blah blah. If it's used by TCP/IP, which we will  do, the value should be this.

So then we do that Quantity is...number of digital inputs data bits  to be read. So for this example we just set one And...this value is start address  of the digital inputs to be read. So the address here is zero. If you just want to read this...the first value cbLength is...contains the max byte size of  the destination buffer.

So yeah we need to provide a buffer where we're going to write  the data that we have read. We will do that We can just call it nReadValue and it can be a byte Let's just store it in a byte. So this will  be the size of that, right? So the SIZEOF will   r

eturn the number of bytes which is, in this  case...the number of bytes of one byte is one And the destination address is the  address of where we want to store   the data once we read it. That will  be this nReadValue, so address of nReadValue. And then we have to do some  triggering of execute, to trigger this function block to actually kind of send the command to this  process that's running in windows to do the actual execution.

Actually for fun we  can see whether this installation that we did actually started some process in windows, which  it should do. So if you go to task manager We should have something with modbus  here now. Yepp! There we go. So we have...now we have a process here that's running in  the operating system. This is the guy that that our PLC runtime will talk to. I assume  through ADS.

And then this is the process that will go out on the network and talk with the  actual modbus server, so this virtual machine A little confusing, I know. But once you've worked  a little bit with TwinCAT you're going to get the hang of this...how everything works. I mean I  could go really geeky here and just start to use a wireshark and show you exactly what's  happening.

But I would probably bore the hell out of you doing that. Anyway, so now we can't just  call this, because we need a state machine, right? So we need some state machine that defines how  we're gonna...you know...start reading by triggering execute. Then wait for the response by lowering  execute, and then we just wait for an answer So I would just create a state machine using  local variables.

I don't recommend you to do stuff like this...like coding...this is  the typical typical way to do it. Which most   of the Beckhoff documentation does. A nicer way  is to define these local enumerations and I would just call it...we kind of need three states, right? We  need one state for while we're waiting, nothing is   happening. One state where we're triggering  the execute flag.

And one state where we're just waiting for the response. The response or an  error. So I would just call it a WAIT, TRIGGER, READ Maybe that's a good name. So in  the WAIT state...coding Then we have a trigger state here we will do the triggering and then read Here we will wait for the response, right? A very simple state machine What I will do now, is that I will  copy paste this guy, the trigger Oops And when you trigger it we want  to trigger it with execute true

But we first want to get to the trigger, right? So when we start this we're in a WAIT state and for that we need a trigger  function block. So we'll just call it trigger We will execute the trigger. So the trigger  here will be the way to know that okay... "Now we want to go from WAIT to executing  this logic". and here we simply check...

coding...then we want to go to TRIGGER, but  only if we are in WAIT. This means that we shouldn't allow the user to TRIGGER here unless  we're actually already in WAIT. So if it triggers and we're not in WAIT so if you're for  example reading the value, we shouldn't do anything. Then we should just let it finish. We simply check eReadState is equal to...

coding...so if the current read state that is WAIT then we go to TRIGGER I think i got this right...yepp These outputs...we're gonna check in the next state. So we trigger this read coils function block here And then we go to the next state...coding And now we're just going to call this function block in the read state with the execute flag set to  false.

So it's just executed until we will get the response. Because you know you kind of have to think  it about it this way... that here we are in kernel space, so we are in real time. We're running it with  our cycle time, whatever the cycle time is set to And we have the real time constraints, and then  on parallel to this execution that we have for the real time, we have the operating system, so we have Windows.

And Windows (applications) as you know runs in user space, so there's no deterministic  properties of this. Windows can decide to do whatever. But we have the the modbus communication  going here, because that happens in Windows We simply have to wait until Windows responds  to us. That's why we have this asynchronous communication between the two.

That's kind of  the thing I had a hard time to wrap my head around when I went from doing kind of traditional  software development to going into real-time PLC control. Then I always had to think about this  you know...I have an operating system and I have the TwinCAT kernel. And they are living in their  two isolated worlds but we need to communicate between them, and we need to have a way to handle  that.

That's exactly what we're doing here So we need to simply call this  function block until we get a response And just provide execute false. Here we're  going to be in read until we get something from the modbus application in Windows. The only thing we need to check now is... coding Here you see that the 10-minute  trial period, so I will close this down A limitation with the software I will start it when we actually need it *

coding*...or we have an error then  we don't want to be here anymore Then we want to go back to waiting And I mean, this is just an example but if  I would do this more professionally, I would probably create a generic modbus client  function block. That we can instantiate w

ith values like the IP address and port, so we  don't have to provide that. And also getting...so getting data in and out, so getting the error data  and the actual value from the modbus server. Here   I'm just doing a demonstration of how to actually  use this function block. Obviously this can be cleaned up. And I mean, this is called read coils EXAMPLE after all. Yeah, I think that kind of is everything we need.

And of course we need  to instantiate this function block in our MAIN And we need to execute it. And we need to make  sure that our real-time properties are correct Okay, I will have to set the isolated core  on this one, so I will do a quick reboot Okay, let's run it on the isolated  core. Let's activate configuration Okay, so now let's try to talk with the server.

But of course first we have to create the server So again let's create the connection Port 502. Let's just put a value here   But first let's set the right slave definition. So we're going to use this coil status, which again is what we're using here. We're  using the read coils function block Let's set the first address to 1 or TRUE And let's run this now.

So we have our trigger If we trigger it, it will...because  we're in wait, it will go to TRIGGER There it will execute all of this, and then  we will wait for the answer. Let's write it Okay, I didn't...nothing happened, what have I missed? Okay, I didn't miss anything, we got an error. Error 1828.

Let's look what this could mean What's 1828 in hexadecimal? That's...okay, let's find the manual for  this guy. For some reason I prefer the PDFs ADS error codes 724, license not found.  Ah! That's very VERY stupid of me Of course. What we need to do...this is a function, so this is not included in the standard development environment from the XAE.

So  you actually have to go to real time Go to...no sorry, to license. Manage licenses and  you have to add the TF... what was the name? TF6250 as a license. We have to generate a test license  for this. Normally if you would use this in a production environment you would actually order  a license for the modbus TCP from Beckhoff to run it.

So yeah, that was a little clumsy of me, but  this is just stuff that happens when you run live Let's activate configuration. Now it should want  to...yeah, some required runtime license is missing Now we need to add the additional  license, or generate a test license for it Here we have all the other licenses that  you might want to use, and as you can see there's a gazillion million billion quadrillion  licenses that you could buy from Beckhoff So there's many functions. Let's run it again.

Hopefully that was the last surprise I don't have a big problem with surprises, but too  many surprises are not fun either. Okay. Let's trigger this guy again. Because we have to start it Yeah, and then we got the value of one. Which is this one. If we set it to false... Let's retrigger it. As you can  see we went back to WAIT.

We're in the WAIT, so if we trigger  this...if we trigger, so we have to go low... Then we have to go high, then  it's gonna run this again And then we got a read value of zero. We can also confirm that this is... that it actually succeeded to read  it by going to the function block So...this is the function block in the library. We can see cbLength is one, so cbLength is...

This is not correct in the documentation. "cbRead, contains the number of bytes currently read". We can also see that the number  of bytes is one. But we can also see that error is false, which means we had a successful read Okay? The next one we're gonna do is to  do some communication in the other direction   So in the other direction we're gonna write  data to the server.

For that we have the function block MBWriteSingleRegister, where we can write 16 bit values to the modbus server. So we're going to create an instance of this function block and write data to the server instead, so we're not going to read but  write data. To do that let's just copy this function block, and instead of calling it read  coils example we will call it write register   example.

We will create an instance  of this function block instead And instead of read the value we'll write  a 16 bit value, so an integer for example And instead of a read state it will be a write  state. We will still wait, we will still trigger the function block but instead of reading we will  do writing so we just call it WRITE. Everything else is more or less the same.

The only difference  is that you will have to provide a pointer to the value that you want to write to the modbus server  instead of providing a value where you want the data to be stored. We can change this value online to something that we want to write to the modbus server. So  let's just simply replace all of these guys This write state is going to  go to WRITE here instead.

This is going to be a write state and  we're going to do our write single register instead. We can replace everything. So all the logic is the same. We still have... ...we still have to wait  when we want to do something. Then we have to trigger the function block, and then we have  to wait for the response.

Whether it's a modbus read or whether it's a modbus write, doesn't  matter. For the control logic of our PLC it's exactly the same. But now the inputs however will  be different. So if you look at the inputs of this We can do like this. Then we will do our nice  F2 trick.

I don't know if it's a trick actually It's just a convenience. We use this function  block. As you can see...now the inputs are slightly different, not much. It's still an IP address, naturaly. We still need a device to talk to It's a TCP port. A unit id, is the same. And MBAddr is zero, so let's just write zero to this location. nValue will be the value  that we will write, so we will just provide...

the write value for the address. Let me think... Okay so it wants the write value, or the nValue is a word so we need to convert this to a word. We can do it with this thing that we also  learned in a previous part of this tutorial, type   conversion. And execute is true. Then timeout.

If  we don't change the timeout it will be the default ADS timeout, whatever that is. One second, five  seconds or something. So we don't have to change it And then the outputs we won't use in  the trigger but we will use them in the actual write state. And I think that's  pretty much it, yeah. So we don't have any pointers or anything because we don't need to provide  a pointer to where the function block should store data, because again the communication is  going in the other direction, so we just need to provide the data that we want to write to the  modbus server. But that's pretty much it, so let's...

First of all, of course we need to provide an...we  need to create an instance of this function block And we need to execute it. And it's okay to  do reading and writing at the same time. This library and this supplement...this TwinCAT function  can handle writing and reading at the same time You can even do reading and writing to different  addresses and and registers at the same time Hopefully I haven't forgotten  anything.

Only time will tell Let's run it. And now, first of all, we need to provide a value to write So we have to provide the...so let's provide  the value 1000. That's what we want to write Let's just write it down. Then  let's trigger this function block So yeah, I'm just going to open... Here so let's do it from here  instead.

We're going to trigger from here, and let's write it and see what happens Yeah. You see we got value 1000  here. So let's change it to minus 32 000. It's an integer so it should be  fine. And let's retrigger the function block So retriggering the function  block will make us go from WAIT Because again, the trigger will change the  wait states to TRIGGER and then we will go execute high and execute low and wait.

Yeah, I guess you kind of get this now at this point Yeah. And we got minus 32 000 here. So now we've  actually had two virtual machines talking to each other in both directions. We've been reading  data from the modbus server. The simulated modbus server, and we've been writing data to it using  two different function codes. The first one was function code...modbus function one, read coils.

The other one was function six which is write   single register. And if you want to, I would highly encourage you to read about modbus and exactly how it works. It's quite interesting but again  this is a very very old protocol. But you will still find it everywhere in the industry. There's  so many devices that are only talking modbus so I would highly recommend you to learn this for  only that reason.

I'm just basically 100% sure you will at some point in your  automation career get to use these functions Yeah, but that's it! Time runs fast when you  have fun. This was just a tiny tiny preview of the various TwinCAT functions that are  available to discover. If I ever do more videos after this tutorial is finished, this is sure  to be one of the topics that I will get back to This was the last video of the basic part  of this tutorial.

Congratulations! The next video will be the first one in the advanced  series of videos, where we will look at a very important topic, version control. Thank you for  being with me so far. See you in the next part!


G) 💬 Summary (copy code 🖥️)


🔙 Previous Part | Next Part 🔜

↩️ Go Back


Z) 🗃️ Glossary

File Definition
Uncreated files Origin Note