CODESYS - the IEC 61131-3 automation software

Welcome to the official CODESYS Forum by 3S-Smart Software Solutions GmbH | A member of the CODESYS Group
Deutsche Version English version russian version 
It is currently Wed Dec 19, 2018 4:40 pm

All times are UTC+01:00




Post new topic  Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Tue Oct 30, 2018 3:02 pm 
Offline

Joined: Mon Aug 13, 2018 4:59 pm
Posts: 2
Hi all

Can somebody please help me to understand how this basic function operates.

I generally understand how a TON timer works... but I need to REALLLLY understand how these things work. I think my question really pertains to how 'scan' cycles works, how code is implemented and when inputs are updated.

I'm familiar with the whole, read inputs, execute code, update outputs mantra - but I'm not fully following how this works.

Lets assume I have a program where a TON instance is declared with a PT:= 50ms. Assume my task is operating at 20ms.

Now in my program I call the FB:

tonDelay( IN :=NOT tonDelay.Q);
Output := tonDelay.Q;

Can somebody please explain how the variable: 'Output' ever achieves a result of TRUE.

In my mind: As soon as the program calls the tonDelay and sees that tonDelay.Q is false (timer hasn't yet reached the PT), it keeps tonDelay.IN at TRUE and allows the timer to keep running.

On the next cycle, let's assume the PT of 50ms has elapsed tonDelay is called and tonDelay.Q is TRUE (timer has finished), my understanding is that when this line of code is called:

tonDelay( IN :=NOT tonDelay.Q);

..., the tonDelay.IN condition falls to FALSE, which in turn will set the tonDelay.Q value to FALSE

So how can the following line of code ever fall TRUE:

Output := tonDelay.Q;

By the time it is executed, the timer has set IN to false, which in turn sets Q to false.

Like I said, I think I'm misunderstanding scan cycles and how the code is executed.

Can somebody please spell out to me (in detail... scan by scan if necessary) how each scan works, how inputs are calculated and how outputs are updated.

I'm getting close to understanding, but I'm in need of a wiser sole :)

Thanks in anticipation


Top
   
PostPosted: Tue Oct 30, 2018 3:40 pm 
Offline

Joined: Fri Feb 23, 2018 3:41 pm
Posts: 73
You feel not so familiar with :
Quote:
read inputs, execute code, update outputs mantra


Basicaly, what the code does ?
tonDelay( IN :=NOT tonDelay.Q);
1) Copies value NOT tonDelay.Q
2) Paste it to tonDelay.IN
3) Call tonDelay FB instance (so calls TON FB, with tonDelay memory)
4) tonDelay updates its outputs, setting the right value to tonDelay.Q
Output := tonDelay.Q;
5) Copies value of tonDelay.Q
6) Paste it to Output

So, in your exemple, this will produce :
1) While PT not reached
tondelay.Q FALSE
Output FALSE
2) Once PT reached, IN was evaluted before, so its true, and Q is set after so its TRUE
tondelay.Q TRUE
Output TRUE
3) Q is set, IN is now FALSE
tondelay.Q FALSE
Output FALSE
4) we are back to 1)

EDIT: It feels you Watch the code as it was the instant value. This is wrong. Code is full of steps.

Kind regards,
dFx


Top
   
PostPosted: Tue Oct 30, 2018 4:38 pm 
Offline

Joined: Mon Oct 01, 2012 8:33 am
Posts: 47
I think dFx has it right when he says:
Quote:
It feels you Watch the code as it was the instant value. This is wrong. Code is full of steps.

Set he task scan time to 1 or 2 seconds so that you can see the results after each scan. Set the TON timeout to 5 or 10 seconds. You should be able to see how it all works, all the steps just like dFx says.


Top
   
PostPosted: Tue Oct 30, 2018 7:18 pm 
Offline
Frequent User
Frequent User

Joined: Wed May 04, 2016 6:00 pm
Posts: 259
Hi.

The inputs are setted before fb execution. In the cycle when Q rises to true, Q is false before the fb execution.

In the next cycle fb see Q as true and after the fb execution Q falls to false.

You have made an oscilator.

Another question is about the temporizer time source. I prefer to work with temporizers wich be increased every cycle with task cycle time. In that case the code sees the time as it be executed at the beguining of the task, it is synchronized with input output latches.

Ton increases in the middle of the task, it could vary if your task code execution time is more or less long.

Sent from my Moto G (5S) Plus using Tapatalk


Top
   
PostPosted: Wed Oct 31, 2018 9:24 am 
Offline

Joined: Fri Feb 23, 2018 3:41 pm
Posts: 73
Josep M. Rams wrote:
Ton increases in the middle of the task, it could vary if your task code execution time is more or less long.

Not sure how TON works internaly, but I would bet on getting actual CPU time and comparing with previous scan one. This should avoid task scan jitter.


Top
   
PostPosted: Wed Nov 07, 2018 3:16 pm 
Offline

Joined: Mon Aug 13, 2018 4:59 pm
Posts: 2
Hi guys,

My apologies for the delayed response.

Thank you so much dfx & Josep for explaining the fundamentals. I'ts strange, I've managed to solve most of my algorithm dilemas without too much difficulty, but I hate not understanding the 'fine details' like PLC scan cycle behaviour having come from a coding background removed from PLC environments.

I'm still struggling a little to understand the behaviour of "software based variables". Rickj, I've taken your advice and slowed scan cycle time in an attempt to better understand execution behaviour (thanks for the tip).

With respect to the "read inputs, execute code, update outputs" sequence... how does this apply to system variables - and by that I mean, purely software based variables, not "physical IO". It seems as if the program can update variables dynamically as it is executing.

This question makes me feel a little dumb, I'm not fully grasping the logic as yet.

Thanks again


Top
   
PostPosted: Wed Nov 07, 2018 3:57 pm 
Offline

Joined: Mon Oct 01, 2012 8:33 am
Posts: 47
Software variables are updated whenever written, as you correctly observed. However, input and output parameters work a bit differently.

The other thing you may need to get your head around, if you haven't already, is that ladder language is basically an "all the code is executed all the time" kind of thing. Conditionally executed code needs to be wrapped in an action, function, method, etc and then called conditionally. Coils write to Boolean variables all the time so you can't have two coils writing to the same variable in the same pou. If you want to conditionally write to a Boolean in ladder language you would need to use a MOVE function block or Set/Clear type coils.

I appreciate where you're coming from and the fact that you want to understand. Don't be shy to ask questions.


Top
   
PostPosted: Thu Nov 08, 2018 12:36 am 
Offline
Frequent User
Frequent User

Joined: Fri Sep 02, 2011 8:02 pm
Posts: 291
Let’s think how the TON code works inside (at least one way):

Now = device time
If not EN then
Trip = Now + PT
End if

If Now > Trip then
Q = true
Else
Q = false
End if


Of course this way doesn’t give the ET, but it explains some things:

1) Scan time is not factored in - everything is based on the clock.

2) Once Q goes true, it will stay true until EN is dropped.

3) When you use Timer(EN:=NOT(Timer.Q)), EN will go false on the next code scan after Q goes true.

4) If you set the PLC scab to exactly 1ms, and use a PT of 1 sec, Timer.Q will be true for 1ms, every 1.002 seconds. (1 second plus 1 scan to set EN false plus 1 scan to EN true).

These observations are based on my experience and duplication of events with my own versions of TON FBs.

_________________
Scott Cunningham
KEB America, Inc.
www.kebblog.com
www.kebamerica.com


Top
   
PostPosted: Wed Nov 14, 2018 10:00 am 
Offline

Joined: Fri Feb 23, 2018 3:41 pm
Posts: 73
dFx wrote:
read inputs, execute code, update outputs mantra


This does NOT apply ONLY to physical I/Os. Every sub-code execution works also like this (functions, function blocks).

To me, you are confused by 2 things :
1) Code is executed line by line, up to down, and therefore, code that is in a IF block will be executed if, when reading the if condition line, it is true. Even if in this same IF block, the condition would be evaluated to false, because of some value change. What only counts was the value of your test WHEN evaluating it.
Code:
a := 5;
IF a == 5 THEN
   a := 8;
   b := 3;
END_IF;

In this exemple, "b := 3;" line will be executed, because your code is interpreted line by line, up to down, and therefore once you entered a IF block, you execute all the lines in it.


2) functions parameters and function blocks uses private memory, meaning the values in these memory addresses need to be set before executing the function. As says the mantra, you first update inputs, then execute code that update private memory outputs, then private memory outputs are copied over your calling outputs values.
Let say we have function name funcA, with only 1 input named inputA, and 1 ouput named ouputA.
When you call your function using
Code:
funcA (inputA := MyInputValue, ouputA => MyOutputValue);

internaly this is what your plc will do :
Code:
funcA.inputA  := MyInputValue;
funcA(); // execute you function code
MyOutputValue := funcA.outputA;


Hope it is as clear as possible.

Kind regards,
dFx

Edited for typo


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 9 posts ] 

All times are UTC+01:00


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited