Codesys Retentive Timer? (RTO/RTON)

Thanks!


So is there any difference between an argument in the VAR_INPUT block and an argument in the VAR_OUPUT block?
Yes. In the latest version at least, you cannot write to outputs from outside the Function Block


They also appear on the right hand side of the function block for the graphical languages.


In ST, your call must use the '=>' operator to assign the outputs to variables, so:
instance_name(in:= myin, out => myout);


Working the other side i.e. ET, just four statements, plus one for TT. Untested.

(* rtovar(IN:=RTOin, PT:=RTOpt, RST:= RTOrst // Inputs *)
(* , Q=>RTOq, TT=>RTOtt); // Outputs *)
(****************************************************************)



No.png
 
Last edited:
That is why there is a Var_In_Out, local variables are not guaranteed to hold their last status on return to the block (although it appears they do )and if there is a variable that needs to be exposed externally from/to the function it needs to be passed both ways i.e. Var_In_Out.
 
Thanks!


So is there any difference between an argument in the VAR_INPUT block and an argument in the VAR_OUPUT block?

Yes. In the latest version at least, you cannot write to outputs from outside the Function Block


They also appear on the right hand side of the function block for the graphical languages.


In ST, your call must use the '=>' operator to assign the outputs to variables, so:
instance_name(in:= myin, out => myout);


Yes, I just tried writing to VAR_Outs this morning in 3.5.18 and it said "No! DUMB@$$! You can't do that"



As for the => operator, I guess I never noticed as I don't assign outputs in the FB call. I just reference them as members of the instance some where else.


That is why there is a Var_In_Out, local variables are not guaranteed to hold their last status on return to the block (although it appears they do )and if there is a variable that needs to be exposed externally from/to the function it needs to be passed both ways i.e. Var_In_Out.

Where in the documentation does it say that Var_Inputs won't be guaranteed to keep there value? if that is so... I have some code I need to rethink.

I have been using FB sometimes as a Data Only class instead of Structs because in some cases I might want to add Methods or Properties later. SO I just use Inputs to hold all my data.


VAR_In_Out is just a reference so then your real data has to be stored some where else, which gets messy.

In Rockwell Land you can't even reference a IN_OUT using the AOI instance, which makes me want to strangle the Studio 5000 Product Manager, though she did seemed like a really nice person when I talked to her the one time, so maybe just strange her Boss instead LOLOLOLOlz

Edit:

Can you do that in Codesys? I need to find out. Usually I want to do it Rockwell as a hack because you can't pass structs/AOI Types in by value with an Input.
 
Last edited:
It's not variable inputs or outputs, it's the local variables, again I have never found an issue but I read somewhere in the IEC notes on this that the data is only valid within the block & cannot be relied on in returning to the block as it is supposed to be initialised on entering the block.
As for the IN_OUT this is a standard part of the IEC it does seem that this supposed transportable code idea is not that transportable from one system to another.
It does appear that there are many discrepancies in the interpretation of what this universal code is supposed to support.
 
Here's my attempt, lets you time past 49 days. You can add some line breaks and tabs to make the ET look a bit more readable.



Code:
//no rollover is given, please don't time beyond 500 years
FUNCTION_BLOCK LRTON
VAR_INPUT
    IN : BOOL;  // ET is increased when IN is TRUE
    RST: BOOL;  // TRUE will reset the ET to 0s
    PT : LTIME := TO_LTIME(TO_ULINT(LINT#-1)); // Timer Preset. If no PT is given, the default value is effectively an infiinte timer
END_VAR
VAR_OUTPUT
    ET : LTIME; // Elapsed time
    Q  : BOOL;  // Timer output, when ET reaches PT
END_VAR
VAR
    now           : LTIME;
    previous_time : LTIME;
    RTRIG_IN      : Standard.R_TRIG;
END_VAR


Code:
now := LTIME();

// you always get 0ns accumulated on the rising edge of IN.
RTRIG_IN(CLK := IN, Q => );
IF RTRIG_IN.Q THEN
    previous_time := now;
END_IF

ET := MIN(PT, SEL(RST, SEL(IN, ET, ET + now - previous_time), LTIME#0S));

previous_time := now;

Q := ET = PT;
 
Late to the Game

I'm late to the game here. I usually check the Oscat Basic library (source code available here: http://www.oscat.de/component/jdownloads/summary/2-oscat-basic/6-oscat-basic-333.html )

when looking for different implementations.

There is a function block in there called ONTIME. It is similar to RTO. The version there only measures to the second resolution but it is easy to modify it to read milliseconds.
There is a dependency in the ONTIME function block to a function called T_PLC_MS(). But this can be replaced with TIME_TO_DWORD(TIME()).
 
Last edited:

Similar Topics

Been a long time since I've posted, but here we go. Started a new role in august and progressively learning about Codesys programming in...
Replies
2
Views
1,145
Hello, I am using a Hitachi Micro EHV+ for a small project, and I wanted to have a Web visu, done with Codesys V3.5 SP13 Patch 2. I test the...
Replies
6
Views
263
Hello, I have a requirement to manage the text alignment dynamically. So, for example: 1. English Texts should be displayed from Left in...
Replies
0
Views
86
Hello, I am new to Codesys, and am trying to learn about it for a project we're developing. I've got a couple questions, but first a little...
Replies
1
Views
133
Hi everyone, as this is my first experience with Rockwell Software i would like to know what's the best way to make Enumerations?
Replies
10
Views
486
Back
Top Bottom