Jump to content

FX5U user function block - percentage error - won't build


Recommended Posts

Posted (edited)

I'm trying to make a function block to calculate percentage error between target and actual weighings. Inputs are target and actual. Output is Percent. (Other i/o such as enable and error have been removed for clarity.) Calculation is

Percent = (Actual - Target) * 100 / Target

My code has got out of hand somehow and I'm getting errors or a hang at 63% when I Convert | Rebuild All. Can anyone simplify the ladder code below for me and sort out my confusion between INT and DINT?

          Local              Label           settings
          iTarget                            Word [Signed] 
VAR_INPUT Target             doseiActual     Word [Signed] 
VAR_INPUT Actual             dosedTempMult   Double Word [Signed] 
VAR Temp  MultdTarget                        Double Word [Signed] 
VAR DINT copy of iTarget required for DDIVdDifference Double Word [Signed] 
VAR DINT copy of iDifference required for DDIVdTempDiv Double Word [Signed](0..1) 
VAR       Temp               DiviDifference  Word [Signed] 
VAR       Difference between actual and target.iPercent Word [Signed] 
VAR_OUTPUT PercentFunction block ladder (extract)
--------------------------------------+-[SUB iActual iTarget iDifference] 
|                                     +-[INT2DINT iDifference dDifference] 
|                                     +-[MUL dDifference K100 dTempMult] 
|                                     +-[INT2DINT iTarget dTarget] 
|                                     +-[DDIV dTempMult dTarget dTempDiv] 
|                                     +-[DINT2INT dTempDiv[0] iPercent] 

I've tried to clean this up after the forum software upgrade messed it up. I can't remember what the correct syntax was but maybe it will help someone!

Many thanks.

Edited by Transistor

Posted
Transistor, Don't know, in what is a problem with convertation of code. But a percent calculation in PLC, using the mentioned equation 'as is', can give incorrect result. Probably, it will be useful for you to read this post http://forums.mrplc.com/index.php?showtopic=29251&p=139135, where I try persistently to draw attention of Bryll and to explain, why a substruction of INT16 can be dangerous for operational result. Also you forget about the rounding of result of calculation. When the value of numerator will be lower than the value of divider, the percent is equal to zero (while it's not equal to zero).
Posted (edited)
Thanks, Inntele. It is a simple % calculation. I am only interested in whole number percentages, 0%, 1%, 2%, etc., to compare these with a maximum deviation. e.g., If error < 3% then all is OK. I don't care about fractions of a percent. My problem is where to specify INT and where to specify DINT. Edited by Transistor
Posted
Don't mention it. If you are interested, I could share in PM a road map, how to make correct the calculation. However it can be done not earlier, than at the night, because I have to leave. And you have a time to "digest" my warnings and to make attempt to manage all yourself
Posted
I think the problem is that I am trying to edit with "Execute Program Check after Build or Online Program" set to "Yes". Gambit told me how to fix this five weeks ago - http://forums.mrplc.com/index.php?showtopic=29204- but I had forgotten. When I turned this off I was able to complete the conversion, fix the code as each warning came up, and get it working. Here's the code that works. SUB iActual iTarget iDifferenceMUL iDifference K100 dTempMult ; INT * INT -> DINTINT2DINT iTarget dTarget ; Need to convert iTarget to DINT before DDIVDDIV dTempMult dTarget dTempDiv ; dTempDiv is array [0], [1]DINT2INT dTempDiv[0] iPercent ; Convert the first element to INTAs Inntele points out this code has a few shortcomings: The output will be rounded down to the next integer. e.g., 3.72% -> 3%.It doesn't check for overflows on input.It gives negative result for Actual < Target. I also added a divide by zero check with error output and a deviation limit input (e.g., +/-3%) and associated alarm output.
Posted (edited)
To avoid problem with overflow: Percent = (Actual*100 - Target*100) / (Target*1)The result of division will consist of quotient (32bit) and remainder (32bit). To rounding the result: Percent_Remainder = Percent_Remainder + Percent_RemainderPercent_Remainder = Percent_Remainder / (Target*1)Percent = Percent_Reminder + Percent_Quotient Edited by Inntele

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...