then I was implementing a cylinder with two outputs and two inputs
FUNCTION_BLOCKCylinder2Out2InIMPLEMENTSICylinderVAR
  DO_Cylinder2WorkingPos: POINTERTOBOOL; (* digital output for move cylinder to working position *)
  DO_Cylinder2HomePos: POINTERTOBOOL; (* digital output for move cylinder to home position *)
  DI_CylinderInHomePos: POINTERTOBOOL; (* digital input for cylinder is in home position *)
  DI_CylinderInWorkingPos: POINTERTOBOOL; (* digital input for cylinder is in working position *)END_VARMETHODmove2Home: ICylinder
  DO_Cylinder2WorkingPos^ :=FALSE;
  DO_Cylinder2HomePos^ :=TRUE;
  move2Home :=this;METHODmove2WorkingPos: ICylinder
  DO_Cylinder2WorkingPos^ :=TRUE;
  DO_Cylinder2HomePos^ :=FALSE;
  move2Home :=this;METHODisInHomePos: BOOL
  isInHomePos :=((DI_CylinderInHomePos^)AND(NOT(DI_CylinderInWorkingPos^)));METHODisInWorkingPos: BOOL
  isInHomePos :=((DI_CylinderInWorkingPos^)AND(NOT(DI_CylinderInHomePos^)));METHODconstructor: Cylinder2Out2InVAR_INPUT
  doCylinder2WorkingPos: POINTERTOBOOL; (* digital output for move cylinder to working position *)
  doCylinder2HomePos: POINTERTOBOOL; (* digital output for move cylinder to home position *)
  diCylinderInHomePos: POINTERTOBOOL; (* digital input for cylinder is in home position *)
  diCylinderInWorkingPos: POINTERTOBOOL; (* digital input for cylinder is in working position *)END_VAR
  DO_Cylinder2WorkingPos :=doCylinder2WorkingPos;
  DO_Cylinder2HomePos :=doCylinder2HomePos;
  DI_CylinderInHomePos :=diCylinderInHomePos;
  DI_CylinderInWorkingPos :=diCylinderInWorkingPos;
  constructor :=this;Â
I know it's not a real cylinder cause there is no error handling, and the position getter are so fine, but it doesn't matter for my questions.
I point to booleans and a boolean is one byte long, so when my outputs are on QX1.0 and QX1.1 it does not work. Pointer to bit is not possible, cause of word alignment.
Of corse I can do some thing like pointer to byte address and an integer for the bit address:
OutByte^.DO_Cylinder2WorkingPos:=TRUE;
But from my point of view, it's stupid and the code looks crap, I mean this is a plc and the main cause of a plc is handle IOs.
The other thing which I don't understand, is why I've to use pointer. I couldn't initialize a reference with a setter.
I was happy to get a plc with interfaces and classes, but with out IO handling it's useless. I hope somebody knows how to deal with IOs and class.
I'm grateful for hints or solutions.
BR
elfrosch
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Why do you want to use pointers to the inputs and outputs?
Why not use VAR_INPUT and VAR_OUTPUT and connect your actual inputs and outputs to the function block instance?
Or map your inputs and outputs to variables of your function block instance (local variables).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think that di/o has not to be inouts of cillinder fb. For me, the io of the cillinder has to be an Ref_cillinder for give orders and ask him (similar to ref_axe)
The di are declared internally in cillinder fb. Inside di fb we do
Var
Byte_8: reference to byte
End var
Byte_8 ref= ix0
And, for example if the di is in the 7th byte 2on bit:
Mydi:= (byte_8[7] and 16#4)
Obviously 7th byte and 2ond bit has to be configurable inside fb di using varinput constant or via a file which fb di reads at starting.
TimvH hat geschrieben:
Why do you want to use pointers to the inputs and outputs?
Why not use VAR_INPUT and VAR_OUTPUT and connect your actual inputs and outputs to the function block instance?
Okay this is common way for plc, but then it's useless to use interfaces and classes. Think about I've now a cylinder with two outputs and two inputs, for example the mech. designer decides it's cheaper to use a cylinder with spring for return. If the code is interface driven I don't care, cause I write a new cylinder class with one output and one input and thats it. In your case I've to change all lines of code where I call the cylinder object. Normaly is encapsulation of data one thing what you try to get with oo.
@Josep
If I do this: >Zitat:
Byte_8 ref= ix0
cylinder, then I've a cylinder for one address byte. In a non chemistry automation you've normaly dozens of cylinders, and I'm honestly too lazy to handle more than one class, also I belive in don't repeat yourself while coding. However while playing with codesys v3, I couldn't inject a reference, so thats the reason why I use pointers.
If there is no other way then I'll do it with byte and bit address, but then I've ugly constructors.
Are here 3S developer? Maybe they can tell us what 3S thought about there oo concept, and how to use the oo stuff with IOs the right way.
BR elfrosch
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You can extend the problem of oop with io to oop and servo axes.
Imagine that you have a machine which is made of 10 equals sub elements. Every one of that elements are made of one servo axe and one cillinder.
You can made on fb which internally has declared one fb which manages the cillinder, but what do you do with axes. You can not work internally with axe1 or axe2...
One idea could be create an fb which will have an array which points to all axes (obviously this fb has to be an singleton).
I have another singleton with another array which points to all io map.
In my cillinder-axe fb i have two varinouts connected to the previous singletons. And I have refs (or pointers) to be used as dio nio or axes.
To assign a real axe to my internal axe, all my fb has one csv file where I can configure to which physical axe are the internal axe connected.
At the end all my code is made inside classes. But there has to be one moment in which we have to connect clases attributes to real world elements which are singletons.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've been since 2005 using extensively pointers to bool without problems...
You can simply use "ptr := ADR(input_variable);" to assign the right bool to the pointer.
And then "ptr^ := TRUE" will simply assign a TRUE to the bool pointed...
And yes, this works with inputs and outputs...
It would be terrible if that would not work.
Which CodeSys version are you using?
PS: at the beginning I remember having the problem you mention, but not now.
That's strange...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2017-02-20
Originally created by: scott_cunningham
I think your complaint is that a BOOL takes a BYTE space, right? Maybe this helps...
Take your oop one step further. Instead of your Cylinder directly writing to an IO, make an IO object. In the IO object, include a method to link to your hardware register. Inside, you can simply do:
FUNCTION_BLOCKDigOutputVAR
  Dummy:BOOL;
  HwReg:REFERENCETOBOOL:=Dummy;END_VARMETHODLinkRegisterVAR_INPUT
  Register:REFERENCETOBOOL;END_VARHwRegREF=Register;METHODTurnOnHwReg:=TRUE;
In your EtherCAT IO Mapping of the IO device, create BOOL variables linked to the hardware registers. Link to these BOOLs:
VAR
  O1:DigOutput;
  O2:DigOutput;END_VARO1.LinkRegister(Register:=HwOut0);O1.TurnOn();
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hey hey,
I was asking already on german board, but I got no answer...
http://forum-de.codesys.com/viewtopic.php?f=10&t=5291&sid=505c983d12df32355ae2dcc7304480af
maybe I've better luck here.
I tried to implement a cylinder class.
So I started with an interface:
then I was implementing a cylinder with two outputs and two inputs
I know it's not a real cylinder cause there is no error handling, and the position getter are so fine, but it doesn't matter for my questions.
I point to booleans and a boolean is one byte long, so when my outputs are on QX1.0 and QX1.1 it does not work. Pointer to bit is not possible, cause of word alignment.
Of corse I can do some thing like pointer to byte address and an integer for the bit address:
But from my point of view, it's stupid and the code looks crap, I mean this is a plc and the main cause of a plc is handle IOs.
The other thing which I don't understand, is why I've to use pointer. I couldn't initialize a reference with a setter.
I was happy to get a plc with interfaces and classes, but with out IO handling it's useless. I hope somebody knows how to deal with IOs and class.
I'm grateful for hints or solutions.
BR
elfrosch
Why do you want to use pointers to the inputs and outputs?
Why not use VAR_INPUT and VAR_OUTPUT and connect your actual inputs and outputs to the function block instance?
Or map your inputs and outputs to variables of your function block instance (local variables).
Hi elfrosch
I think that di/o has not to be inouts of cillinder fb. For me, the io of the cillinder has to be an Ref_cillinder for give orders and ask him (similar to ref_axe)
The di are declared internally in cillinder fb. Inside di fb we do
Var
Byte_8: reference to byte
End var
Byte_8 ref= ix0
And, for example if the di is in the 7th byte 2on bit:
Mydi:= (byte_8[7] and 16#4)
Obviously 7th byte and 2ond bit has to be configurable inside fb di using varinput constant or via a file which fb di reads at starting.
Related
Talk.ru: 7
Hi TimvH, hi Josep,
thanks for your replies...
Okay this is common way for plc, but then it's useless to use interfaces and classes. Think about I've now a cylinder with two outputs and two inputs, for example the mech. designer decides it's cheaper to use a cylinder with spring for return. If the code is interface driven I don't care, cause I write a new cylinder class with one output and one input and thats it. In your case I've to change all lines of code where I call the cylinder object. Normaly is encapsulation of data one thing what you try to get with oo.
@Josep
If I do this: >Zitat:
Byte_8 ref= ix0
cylinder, then I've a cylinder for one address byte. In a non chemistry automation you've normaly dozens of cylinders, and I'm honestly too lazy to handle more than one class, also I belive in don't repeat yourself while coding. However while playing with codesys v3, I couldn't inject a reference, so thats the reason why I use pointers.
If there is no other way then I'll do it with byte and bit address, but then I've ugly constructors.
Are here 3S developer? Maybe they can tell us what 3S thought about there oo concept, and how to use the oo stuff with IOs the right way.
BR elfrosch
Hi.
You can extend the problem of oop with io to oop and servo axes.
Imagine that you have a machine which is made of 10 equals sub elements. Every one of that elements are made of one servo axe and one cillinder.
You can made on fb which internally has declared one fb which manages the cillinder, but what do you do with axes. You can not work internally with axe1 or axe2...
One idea could be create an fb which will have an array which points to all axes (obviously this fb has to be an singleton).
I have another singleton with another array which points to all io map.
In my cillinder-axe fb i have two varinouts connected to the previous singletons. And I have refs (or pointers) to be used as dio nio or axes.
To assign a real axe to my internal axe, all my fb has one csv file where I can configure to which physical axe are the internal axe connected.
At the end all my code is made inside classes. But there has to be one moment in which we have to connect clases attributes to real world elements which are singletons.
Hi elfrosch,
I've been since 2005 using extensively pointers to bool without problems...
You can simply use "ptr := ADR(input_variable);" to assign the right bool to the pointer.
And then "ptr^ := TRUE" will simply assign a TRUE to the bool pointed...
And yes, this works with inputs and outputs...
It would be terrible if that would not work.
Which CodeSys version are you using?
PS: at the beginning I remember having the problem you mention, but not now.
That's strange...
Originally created by: scott_cunningham
I think your complaint is that a BOOL takes a BYTE space, right? Maybe this helps...
Take your oop one step further. Instead of your Cylinder directly writing to an IO, make an IO object. In the IO object, include a method to link to your hardware register. Inside, you can simply do:
In your EtherCAT IO Mapping of the IO device, create BOOL variables linked to the hardware registers. Link to these BOOLs: