Cpp sharing variables between Component and Program

Hi all, I’m working on a cpp project where the PLCnext is a TCP server and it makes contact and recieves and sends data to a Siemens PLC (this is the client).

I’m having some difficulties to get the 512 bytes I recieve and send to the PLCnext. I’m using IN- and OUTports for the Cpp program. These variables I’m trying to send to the PLCnext to use internally for other programming stuff and checking the time between some intervals.

                                             * 512 bytes recieved from the Siemens PLC as an OUTport
                                             * 512 bytes recieved from the PLCnext as an INport
                                             * int64 starttime unix0ticks
                                             * int64 activetime unix0ticks
                                             * int64 endtime unix0ticks

I tried using a typedeff arrayWriter of 512 bytes but I can’t acces it on the Component base. this is the link to a github page where the code is placed: https://github.com/ArneBert/Cpp-PLCnext-TCP/tree/master/CppRSCService_v2, Greetings,
Arne

Hello Arne, In your Program.hpp file you can find this line. ```CPP

CppRSCService::CppRSCServiceComponent& cppRSCServiceComponent; ``` This is a refference to you Component.
You can access your Component through that refference. If you want to forward data from your Component to the Program into GDS in a cyclic manner I recommend, like mentioned here , that you implemment a FiFo Buffer for data in your Component (List of Byte[512] or something) and a method that provides threadsafe means to get the data from there. Basically this could look like this:

ComponentThread{ RecieveList.AddValue(Socket.GetLastData()); }

-—
Program::Execute{
OutportByteArray = cppRSCServiceComponent.RecieveList.GetValue();
} I highly recommend that you lookup threadsafe dataexchange if you intend to implement this procedure yourself.
This can be tricky to implement if you want to avoid data races or have szenarios where multiple threads access the same datastore. As an alternative:
You can use the Component Port to controll your thread and implement a synchronous Dataexchange with a complementary functionblock PLCnext Engineer project. //#attributes(Hidden)
struct Ports
{
// Some Input Variables like TargetIP, Target Port, Start Connection, ect ect... //#name(In)
//#attributes(Input)
Arp::byte InField[512];
//#name(ReadNext)
//#attributes(Output)
Arp::boolean CanReadNext = false; // Some other component will recieve this and send Values when true to InField. //#name(Out)
//#attributes(Output)
Arp::byte OutField[512]; //#name(WriteNext)
//#attributes(Input)
Arp::boolean CanWriteNext = false; // Some other component will set this and recieve Values from true to OutField. };

//#port
Ports ports; // Create one (and only one) instance of this struct.
// Apart from this single struct instance, there must be no other Component variables declared with the #port comment.
// The only attribute that is allowed on the struct instance is "Hidden", and this is optional.
// The struct can contain as many members as necessary.
// The #name comment can be applied to each member of the struct, and is optional.
// The #name comment defines the GDS name of an individual port element. If omitted, the member variable name is used as the GDS name.
// The members of the struct can be declared with any of the attributes allowed for a Program port. kind regards,
Oliver


|

Hi Oliver, Thx for the help. I implemeted your alternative method because I’m not so familiar with C++.

I pasted the struct Ports you made in Eclipse and build the code. I was able to build the code but when I dragged the program in the PLCnext Engineer. But I couldn’t find the struct where I can acces the data.
I have updated the github page with the latest version. https://github.com/ArneBert/Cpp-PLCnext-TCP/tree/master/CppRSCService_v2 Do I have to also paste this struct in the Program under Port? What I also noticed was when I only had the struct with those variables I use. eclipse wasn’t able to find for example Starttime.
The error was something about out of scope. It’s like whatever I place in that struct the component.cpp wouldn’t have acces to it. Maybe a bit off topic, but I would want to learn more about C++ and the Framework for C++ the PLCnext uses.
Could you help me with the Framework the PLCnext uses? Greetings,
Arne

Hello Arne,

you defined the Struct (Ports) but did not instantiate a Variable of that type. (ports)

//#port


Ports ports;

And then in your .cpp
you need to access the Variables like (struct members)
ports.endtime

The component port does not have anything to do with the Program.

kind regards,
Oliver

Hi Oliver, So I was able to modify my code and get it to build without any big problems in Eclipse. But when I want to run the program in the PLCnext, sometime the PLCnext engineer suddenly fails or I can’t stop or modify the code. Most of the time 1 core is at 100% utulity (see picture).

I have to cutt of the power and a previous version of the code will be run.
I modified the code on the github page: https://github.com/ArneBert/Cpp-PLCnext-TCP/tree/master/CppRSCService_v2
I don’t get the results of the ticks, and array I need. I do not know what I’m doing wrong here. Kind regards,
Arne


Hi, I got the PLCnext back to work without crashing. The program still won’t run, it will start the program for a fraction of a second but then fails.

I updated the github page and I placed my PLCnext engineer project, the OUTPUT.log and the gds file in the main CppRSCService_v2. In the OUTPUT.log there is a fatal error name SIGEGV about a socket.shutdown(). I was using it but when removed in the Cpp Component code the fault remains.
I found a post about this SIGEGV but I’m not findind the problem in my code or the GDS. This is the link about this SIGEGV: https://www.plcnext-community.net/en/discussions/fatal-error-sigsegv-from-output-log.html Kind regards,
Arne Berteloot

Hi Arne, a SIGEGV is always a bit tricky to find. I would suggest to add some log messages (log into Output.log) into your code to pinpoint the causing section of the fault. `#include “Arp/System/Commons/Logging.h”

``Log::Info(Debug Message);` Also it might be helpful to follow also our Cpp Examples in our GitHub channel. Take care Frank

Hello, I found the problem and the code is running as it should.

The problem I had was that the PLCnext Engineer indicated the pcworx library was not updated.
The strange part was that I got the message hat the CppRSCService was updated externally and updated.
But when I deleted and reopened my C++ library the project was updated.
It seems there is a bug in Eclipse or the PLCnext engineer.
I’m using an older version of the PLCnext Engineer 2020.0 LTS.
I’m using eclipse with PLCnCLI version 2020.0 LTS (20.0.0.24752) and the PLCnext Controller AXC-F-2152 is also version 2020.0 LTS (20.0.0.24752).
The problem was about the shutdown function for a socket and possibly also something about multiple IN- and OUTPorts. Kind Regards,
Arne Berteloot