User Event Task

Hello! I have a program that I want to run in an other task and I tried to make it as an user event task. In help description it says that I have to use a function block EVENT_TASK, I can’t find in amongst programming blocks. Do anyone know where to find it? Thanks in advance /Stefan

Hi Ssteffe, I’ve just checked this and you’re right the FB is described in the help but missing in the current installation in PLCnext Eng. It might be that there is a special lib, I’ll check this with my colleges. However, even when the FB would not be ready yet it is possible to call an event by the C++ API, could this be also an alternative for you? Keep you informed! Frank

Hi Ssteffe, I’ve unfortunately bad news for you. We’ve still the IEC 61131 User Event FBs for PLCnext in our Backlog, but due to other features we’ve had to shift them. Until the FB is not available, there is still the possibility to do it in C++… Cu Frank

Hi Frank! Thanks for reply, I will test it in C++ then. /Stefan

Hi Stefan, please find below a short code snippet which demonstrate how you can trigger( SET() method) the user event task in a RT C++ application.

#include "Arp/Plc/Commons/Esm/RtEventManagerProxy.hpp"

Arp::String eventName = "EventName";
Arp::Plc::Commons::Esm::RtEventManagerProxy& rtEventManagerProxy = Arp::Plc::Commons::Esm::RtEventManagerProxy::GetInstance();
this->rtEventPtr = rtEventManagerProxy.GetEvent(eventName);

if (this->rtEventPtr != nullptr)
{
    this->rtEventPtr->Set();
}

We will prepare also an example in our GitHub C++ Example collection. Take care!

Hi Frank! Thanks for the snippet. It works fine and will help me starting non time critical tasks. Best regards Stefan

Good afternoon! I am thankful for this thread, because I was struggling with this as well. Is there an update when this will be available? I see and acknowledge the workaround above, but I am not sure that here in the US this would be considered an acceptable workaround

Hi tthayer, I would not call it a workaround, because the C++ service (we call it remote service calls - RSC) are the foundation to access and control the PLCnext Runtime. Even when we don’t have currently a schedule for a dedicated 61131 lib, it is possible to call every RSC service inside a C# functionblock. So you can crate your own library at any time. Basicaly this is also the way we’ve created the TCP, Axio and Interbus functionblocks. If needed we can provide a design pattern… cu Frank

Hello all, I am working on getting the encoder signal with AXC F 2152 and I/O module AXL F DI8/1 DO8/1 XC 1H and I need a hardware interrupt so I can capture all the signals I get from the encoder. I am planning on using the PLCnext Engineer 2019.6 software for my project. My signals have a pulse width of 2.5ms and I have read on the community board that the I/O module I have should be enough to capture all the signals using User Event Task in PLCnext Engineer. I saw in the documentation that for activating events I can use EVENT_TASK function block to activate the event, but since it is missing from the PLCnext Engineer 2019.6 I looked for other options. On this topic I found the possible solution, but since I am not very proficient with C++ I wanted to ask if there is another way of activating User Event Task (or getting the encoder signals some other way) or this is the only approach (for now)? Regards Petar

Hi djuric, I’m not sure if even when the event task FBs would be available this would be suitable here. If the encoder is transmitting continuously new positions a fixed and bus synchronous scan time would be maybe better. And this would be also the solution here:

                                               * Create a fast task (AXC F 2152 min. 1ms) which is double as fast than the signal itself.
                                               * Synchronize the task with the Axioline bus cycle (Axioline F node --> Settings --> Trigger IO Update
                                               * Instantiate on this task a litte program which just counts the signals

Keep in mind to just count in the fast task the values, move the evaluation and the rest into slower task, otherwise you will create an unnecessary load. In case you do not reach the needed performance, keep also in mind that we’ve also dedicated Counter modules (like e.g. AXL F CNT2 INC2 1F - 2688093) I hope this helps. Take care Frank

Hi Frank, Thank you for your answer. This solution you provided was indeed my first choice because it seemed logical that I can capture everything with just a cyclic task of 1ms. But with that method I was still getting maybe one third of the pulses from the encoders, so then I came up with this idea of getting them by hardware interrupts. But your answer made me go through this first approach one more time and I figured out that AXL F DI8/1 DO8/1 XC 1H filter time for my application was set at 3ms, so I changed that to <0.1 ms and it worked, I can get all my signals now. Thank you once again for helping me solve my problem! Regards, Petar

Hi Stefan, please find below a short code snippet which demonstrate how you can trigger( SET() method) the user event task in a RT C++ application.

#include "Arp/Plc/Commons/Esm/RtEventManagerProxy.hpp"

Arp::String eventName = "EventName";
Arp::Plc::Commons::Esm::RtEventManagerProxy& rtEventManagerProxy = Arp::Plc::Commons::Esm::RtEventManagerProxy::GetInstance();
this->rtEventPtr = rtEventManagerProxy.GetEvent(eventName);

if (this->rtEventPtr != nullptr)
{
    this->rtEventPtr->Set();
}

We will prepare also an example in our GitHub C++ Example collection. Take care!

Hello all,

Thanks for the code snippet. I have some questions regarding the User Events.

                                               1. How does one access/declare the rtEventPtr? I have tried to simply "use" the pointer in the code assuming that it is magically declared somewhere in the code already for me, but the compiler is unable to find a one.
                                               2. Is it possible to receive events in the C++ code beside only triggering them?
                                               3. When are you planning to implement the EVENT_TASK function block for the PLCNext?
                                               4. Edit: Have you already created the example code for the GitHub repo? If so, where can I find it?

Looking forward to hearing from you!

Kind regards,
Michael Czorniej

Hi Michael, I think I can help you with 1 question. You have to include #include “Arp/Plc/Commons/Esm/RtEventManagerProxy.hpp” and then you can create the rtEventPtr Arp::String eventName = “Event1”; //The name of the event from PLCnEng

Arp::Plc::Commons::Esm::RtEventManagerProxy& rtEventManagerProxy = Arp::Plc::Commons::Esm::RtEventManagerProxy::GetInstance();
RtEvent::Ptr rtEventPtr; I hope this will help. /Stefan

Hi Stefan, Thanks for the help. It does work indeed! :slight_smile:

Hello Everyone. Can You Please Guide where i can write C++ Code in PLC Next Engineering Software? I want to use User Event Call Immidiatly for one of my application

There is a series on C++ programming for PLCnext Engineer, here: https://www.youtube.com/playlist?list=PLXpIBdAgtoRLfPY_s9z3gpy1Whldo7VCz If you are not familiar with this process yet, or with C++ programming in general, then this might not be the solution for an application that needs to be completed immediately.

Hi all, please find below another, more complete example. #include “Arp/Plc/Commons/Esm/RtEventManagerProxy.hpp” namespace TestAppli { Arp::string eventName = “MyUserEvent”; //Name of the User Event Task in PLCnext Engineer Arp::Plc::Commons::Esm::RtEventManagerProxy& rtEventManagerProxy = Arp::Plc::Commons::Esm::RtEventManagerProxy::GetInstance(); RtEvent::Ptr rtEventPtr = rtEventManagerProxy.GetEvent(eventName); void EventTestProj::Execute() { \trtEventPtr = rtEventManagerProxy.GetEvent(eventName); \tif (rtEventPtr != nullptr && xTriggerEvent == true) \t{ \t\tLog::Info(“Fire Event”); \t\trtEventPtr->Set(); \t} } } // end of namespace TestAppli @Martin, thanks for your help :slight_smile:

No problem. :slight_smile: To be clear, the source code above is part of a C++ real time program (.cpp) file. The key seems to be that the pointer to event, which is retrieved using the event name, is not valid if retrieved during the creation of the program instance, but is only valid later in the PLC start-up sequence. In the example above the event pointer is retrieved every time the program instance is executed, which is probably belts-and-braces but it does ensure that the pointer is valid when the Set() method is called on that event.

Hi tthayer,\nI would not call it a workaround, because the C++ service (we call it remote service calls - RSC) are the foundation to access and control the PLCnext Runtime.\nEven when we don’t have currently a schedule for a dedicated 61131 lib, it is possible to call every RSC service inside a C# functionblock. So you can crate your own library at any time.\nBasicaly this is also the way we’ve created the TCP, Axio and Interbus functionblocks.\nIf needed we can provide a design pattern…\ncu\nFrank\n

Did you have any example on how to call rsc service from c#

I know that Frank said this back in 2019:

_Even when we don 't have currently a schedule for a dedicated 61131 lib, it is possible to call every RSC service inside a C# functionblock. So you can crate your own library at any time …__Basicaly this is also the way we 've created the TCP, Axio and Interbus functionblocks._The last statement is true - this is the way that some internal PLCnext Engineer function blocks are written. However the pattern for doing this turns out to be so complex that it is not really useable outside our internal library development team. Even if the design pattern was publicly available (which it isn’t), there are so many traps that we can’t really recommend this pattern for general use at the moment (sorry).
Do you mind me asking which RSC service(s) you would like to access from a C# Function Block?