Codesys Retentive Timer? (RTO/RTON)

Yup, I have found examples of other peopling making there own, but nothing pre packaged. That I know has probably been tested.

I am already pretty far along with writing my own Sadly.
 
Hour meter example
exactly, it's been mentioned many times in this forum, good for about 5Ma, and too simple to not work (famous last words ;)):

IF reset_rtoch THEN ch_udint := 0; END_IF; (* Bell *)

TON(IN=on AND not rtoq,PT=T#36s,Q=rtoq); (* Here's *)
ch_udint := ch_udint + rtoq; (* the beef *)

display_rto_h_real := 0.01 * ch_udint; (* Whistle *)


Dunno if that [+ rtoq] will promote a BOOLEAN to a UDINT, but if it does not, then hopefully the intent is clear enough to code it properly.
_
 
Last edited:
Code:
FUNCTION_BLOCK RTO
VAR_INPUT
    IN : BOOL; // Run (Hold)
    PT : TIME; // Run Duration
    RST : BOOL; //Reset 
END_VAR
VAR_OUTPUT
    Q : BOOL; // Done
    ET : TIME; // Elapsed Time
    TT : BOOL; // Timer Running
    Remaining : TIME; // Time Remaining
END_VAR

VAR
    previousElapsed : TIME;
    IN_R : R_TRIG; // IN Rising Edge
    IN_F : F_TRIG; // IN Falling Edge
    Q_R : R_TRIG; // Done Rising Edge
    timer : TON;
END_VAR
[INDENT]

IN_R(CLK := IN);
IN_F(CLK := IN);


IF IN_R.Q THEN
    IF (Remaining > T#0MS) AND NOT Q THEN
        timer.PT := Remaining;
    END_IF
END_IF

IF RST THEN
    Reset();
END_IF

IF IN_F.Q THEN
    
    previousElapsed := timer.ET + previousElapsed;
END_IF

//** Keep before Timer Execution
ET := timer.ET + previousElapsed;

timer.IN := IN AND NOT RST;

timer();

IF timer.IN THEN
    Remaining := Timer.PT - timer.ET;
END_IF

IF IN_F.Q THEN
    //** Execute after assigning Remaining
    timer.PT := T#0MS;
END_IF

// Timer Done Rising Edge
Q_R(CLK := timer.Q);

IF Q_R.Q THEN
    ET := timer.PT + previousElapsed;
    timer.PT := T#0MS;
    Q := TRUE;
END_IF

TT := IN AND NOT Q;
[/INDENT]
ACTION Reset[INDENT]
IN := FALSE;
previousElapsed := T#0MS;
Remaining := PT;
ET := T#0MS;
Q := FALSE;
[/INDENT]
Is what I ended up with.

Feel free to offer advice on how it can be condensed while keeping accuracy, and behavior.
 
Code:
IF RST THEN
     Reset();
END_IF

...

timer.IN := IN AND NOT RST;

...
Code:
ACTION Reset[INDENT]
IN := FALSE;
previousElapsed := T#0MS;
Remaining := PT;
ET := T#0MS;
Q := FALSE;
[/INDENT]


If RST is 1, then [ACTION Reset] executes, and IN will be 0, so the [AND NOT RST] is not necessary, because IN can only be 1 at that point if RST is 0, so [NOT RST] will always be 1 if IN is 1 at that point.
 
Code:
FUNCTION_BLOCK RTO
...
VAR_OUTPUT
    ...
    Remaining : TIME; // Time Remaining
 END_VAR
...
[INDENT] IF IN_R.Q THEN
    IF (Remaining > T#0MS) AND NOT Q THEN
        timer.PT := Remaining;
    END_IF
END_IF
...[/INDENT]
If [Remaining] is an output, how can it have a value in the FUNCTION_BLOCK before that function block assigns it a value? Where does the value come from?
 
Code:
...[INDENT] 
// Timer Done Rising Edge
Q_R(CLK := timer.Q);

IF Q_R.Q THEN
    ET := timer.PT + previousElapsed;
    timer.PT := T#0MS;
    Q := TRUE;
END_IF[/INDENT]
This could be replaced with
Code:
// Timer Done Rising Edge
IF timer.Q and NOT Q THEN
     ET := timer.PT + previousElapsed;
     timer.PT := T#0MS;
END_IF
Q := timer.Q;
 
Code:
[INDENT] IF IN_F.Q THEN
    
    previousElapsed := timer.ET + previousElapsed;
END_IF

//** Keep before Timer Execution
ET := timer.ET + previousElapsed;[/INDENT]
If IN_F.Q is 1, then previousElapsed will be incremented by timer.ET, and then it will be incremented by timer.ET again to write the value of ET. Is that double-dipping?

Again, comments would be useful to understand the intent.

Also, if scan time is short, i.e. on the order of a few ms, the internals of the timer might be keeping track of fractional ms (more resolution than can be carried by the value timer.ET as integer ms), and those fractional ms might get lost in this approach that re-assigns a new integer value for timer.PT, resulting in a loss of accuracy. That said, any approach that uses whole ms might lose those fractional ms (if they exist),
 

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,157
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
296
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
90
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
160
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
509
Back
Top Bottom