Store PLCnext CommunityPLCnext on LinkedInPLCnext on Instagram  PLCnext on YouTube Github PLCnext CommunityStore PLCnext Community

  1. habip_yesilyurt
  2. PLCnext Technology & PLCnext Controls
  3. Monday, 21 June 2021
Hi,
I want to use https://github.com/PLCnext/BusConductor" target="_blank">BusConductor component from a C++ runtime application. I deployed BusConductor as instructed in "without PLCNext Engineer part". When I tried to read port, I get this log

GetBufferPtrByFullPortName: Could not find portName 'http://Arp.Io.AxlC/BcComponent1/BusConductor' in fbIoPortsFramesMap

In BusConductor tutorial it is said "you can use a gds.config file to connect the BusConductor port to a GDS port in your own C++ project". but it is not clear how to do that.

Is there a sample C++ runtime code to start configuring bus and getting information about detected modules using BusConductor component? If there is no such sample code, can anyone describe how to use BusConductor via GDS?
Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo
Sorry for the delay.

If the intention is to develop a Runtime application (like the Sample Runtime example) with dynamic Axioline configuration (like the BusConductor example does), then it would be unusual to use an ACF (or PLM) component to achieve this, although this is possible. It would make more sense to implement the dynamic bus configuration feature (like in the BusConductor example) by calling the Axioline RSC service directly from the Runtime application, during application startup.

The quote that you cite from the BusConductor example is intended to refer to C++ projects which define their own GDS ports, which can then be used as end-points for the GDS port connections in a .gds.config file. C++ projects like the Sample Runtime example cannot define their own GDS ports, so that quote does not apply to those types of projects.

Instead, if you really want to use the BusConductor ACF (or PLM) component to do dynamic Axioline configuration for a Runtime project, then you will need to use the DataAccess RSC service to read and write to the GDS port variables on the BusConductor component. There is an example showing how to use RSC services in Part 5 of the Sample Runtime example, and and example of how to use the Data Access RSC service in the CppExamples project.

Please let us know which way you decide to go, and if you have any further questions on this topic.
Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support
habip_yesilyurt Accepted Answer Pending Moderation
0
Votes
Undo
Hi Martin,
Thank you for reply.
I will try both methods. Since my customer asked me to implement this feature only for evaluation, my time is limited. I liked the Plcnext environment especially because it is way more faster than other candidates. On the other hand learning curve is steep ( at least for me :) ). It is an upset that there is no such a C++ runtime sample as I try to adapt a legacy C++ project to Plcnext platform.

I'll let you know about my progress.

Regards,
Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo
OK, if it is only for demonstration then perhaps using the BusConductor component will be quicker, but your app will probably need to be re-designed for a production application.

I try to adapt a legacy C++ project to Plcnext platform
That's exactly what Codesys (and some others) have done with their own legacy applications, so you are not the first to try this. What is unusual in your case is that you need dynamic I/O hardware configuration at run-time, which Codesys (or any other runtime) does not have, as far as I am aware. Most applications are happy for the user to specify the I/O configuration at design-time, and then stay with that fixed hardware configuration at runtime. If your application can get away with that "limitation" (like Codesys does), then your application will be simpler to port to the PLCnext Control platform.
Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support
habip_yesilyurt Accepted Answer Pending Moderation
0
Votes
Undo
Our customer asked for "dynamic I/O hardware configuration detection" feature since existing application adapts itself according to the I/O modules detected on the bus.

I have already verified that we can adapt the existing application to PLCNext platform. I verified it using some digital and analog I/O modules and an IF CAN module. But I did it using a fixed I/O configuration created by PLCNext Engineer.

My progress:
I decided to use BusConductor component as you suggested.

I used IDataAccessService as in Data Access RSC sample from CppExamples project. With IDataAccessService I tried to access BusConductor ports from SampleRuntime Part 5 code. I used "BcComponent1/BusConductor" as port name for both reading and writing.

I got "NotExist" error as write operation result and "void" return type for read operation.

My conclusion... port name "BcComponent1/BusConductor" can not be used from Runtime code directly. As if I still need some GDS port mapping.

Do you agree with my conclusion?
I am still not sure if i'm on the right track or not :)

I can send the code if you'd like to have a look...
Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo
Yes, you are on the right track, but I don't think you can make that conclusion yet.
The variable you are trying to access using the DataAccess service is a struct variable, and from the API documentation:

To address a variable, the full variable name uri is necessary. Some valid examples are given below:
:
ComponentName-1/ProgramName-1.Struct_Variable_Name.Element1.Leaf
:
So, please try reading/writing the CONFIG_REQ field (boolean) in that structure, for example:

BcComponent1/BusConductor.CONFIG_REQ

And, (just to check), BcComponent1 must be instantiated on the PLC when you try to access the port(s) on that component instance.

.
Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support
habip_yesilyurt Accepted Answer Pending Moderation
0
Votes
Undo
Unfortunately it did not work :(

Here is my code. For both write and read operations else statements execute with following log output

04.06.20 12:23:55.682 root INFO - Error writing single bool to GDS NotExists
04.06.20 12:23:55.683 root INFO - Error reading single bool from GDS NotExists



// 1. Read a single variable
// "ReadSingle" can only be used with primitive types
bool configReq= 0;
ReadItem readPortData = dataAccessServicePtr->ReadSingle(
"BcComponent1/BusConductor.CONFIG_REQ");
if (readPortData.Error == DataAccessError::None) {
readPortData.Value.CopyTo(configReq);
Log::Info("configReq '{0}' read from ReadSingle()", configReq);
} else
Log::Info("Error reading single bool from GDS {}", readPortData.Error);

// "WriteSingle" can only be used with primitive types
WriteItem writePortData;
DataAccessError writeResult;
writePortData.PortName = "BcComponent1/BusConductor.CONFIG_REQ";
writePortData.Value = true;
writeResult = dataAccessServicePtr->WriteSingle(writePortData);
if ( writeResult ==
DataAccessError::None) {
// Success
} else
Log::Info("Error writing single bool to GDS {}", writeResult);



I assume BcComponent1 is instantiated by plcnext service when I restart it.
Here is the folder/file structure of "~/projects" folder of PLC that I deployed according to the instructions in BusConductor tutorial.

current -> BusConductor
BusConductor/
├── BusConductor.acf.config
├── generic_axioline
│   ├── Io
│   │   ├── Arp.Io.AxlC
│   │   │   ├── 1.tic
│   │   │   ├── 27c150b2-895d-43a3-8500-3982e800065a.tic
│   │   │   ├── 34f3a4a2-374e-4e21-8ef8-929acd798f58.tic
│   │   │   ├── d2f7aa90-61af-4aa0-b04b-62a7bb2a6b13.tic
│   │   │   └── links.xml
│   │   └── Arp.Io.PnC
│   │   ├── axc-f-2152-1.tic
│   │   └── links.xml
│   ├── Plc
│   │   ├── Eclr
│   │   │   └── eCLR.img
│   │   ├── Esm
│   │   │   └── PCWE.esm.config
│   │   ├── Gds
│   │   │   └── PCWE.gds.config
│   │   └── Plm
│   │   └── pcwe.plm.config
│   └── Services
│   └── OpcUA
│   └── PCWE.opcua.config
└── libBusConductor.so
Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo
Ah ... in the process of trying to reproduce this problem, it occurred to me that perhaps this is the cause:
https://github.com/PLCnext/BusConductor/issues/3
The title says it all - "Does not work with firmware 2021.0.0". So, I guess that you are running firmware version 2021.0.x ?
I think that may be the problem you are seeing - the GDS ports on PLM components (like BusConductor) cannot be accessed.
That problem was fixed in FW 2021.0.5, so I will load that FW version and check if the DataAccess RSC service can now access these GDS ports.
Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support
habip_yesilyurt Accepted Answer Pending Moderation
0
Votes
Undo
Current FW version on our PLC is 21.0.2.35550. So It seems I need to upgrade it to 2021.0.5 version.
As it is my last working day before 3-week holiday, I do not want to do so today. I will try it after my holiday.
I may bother you when I am back from the holiday :)
Thanks for the valuable help...
Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo
No problem, I haven't had a chance to check this yet myself, but I should have an answer in three weeks (when I am also back from my holiday!)
Enjoy your break!
Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support
Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo
I have now had a look at this and I will need to re-write the instructions for installing the BusConductor component without PLCnext Engineer.

The problem may be related to this issue:
https://github.com/PLCnext/PLCnext_CLI/issues/6

In any case, the BusConductor instructions were written at a time when there seemed to be no problem creating a PLM Component instance using an .acf.config file. It turns out that this does not work 100% smoothly for components that have Ports defined, like the BusConductor component. One problem is described in the above Github issue.

In this case, there are at least two solutions:

1. Change the BusConductor instructions so that the component is created as a PLM Component, instead of an ACF Component. This will require more configuraton files, e.g. the .esm.config file will need to define a Task, and a BusConductor Program instance. This will basically follow the procedure described here:
https://github.com/PLCnext/CppExamples/blob/master/Examples/NoEngineer/README.MD

2. Create an alternative BusConductor component, alongside the existing one, that will work properly when created using an .acf.config file.

I'm not sure which of these would be best, but the first one is the easiest to do with the existing code.

I will put this task into a new Github issue in the BusConductor repository.
Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support
Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo
I have now updated Github with improved instructions on how to run the example without PLCnext Engineer, based on option 1 above.
This now works OK for me, so please let us know how you get on.
Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support
  • Page :
  • 1


There are no replies made for this post yet.
However, you are not allowed to reply to this post.