Transistor Posted October 17, 2015 Report Posted October 17, 2015 (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 October 26, 2021 by Transistor
Inntele Posted October 18, 2015 Report Posted October 18, 2015 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).
Transistor Posted October 18, 2015 Author Report Posted October 18, 2015 (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 October 18, 2015 by Transistor
Inntele Posted October 18, 2015 Report Posted October 18, 2015 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
Transistor Posted October 18, 2015 Author Report Posted October 18, 2015 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.
Inntele Posted November 1, 2015 Report Posted November 1, 2015 (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 November 2, 2015 by Inntele
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now