strantor said:Hello, I would like to see if anyone can give me some pointers on how to optimize this function block that I have written for a Omron CJ2M. It is just simple piecewise line formula, but the only way I know to handle the piecewise portion is with a slew of if-then statements, which is gobbling up more memory than I can spare. This FB consumes 989 steps and 78 non-retain memory locations! As you can see, I'm not the text-based programming savant. please help!

I see one obvious thing: defining constants like "X2_Neg80:= -80.0;" and then using X2_Neg80 in the code when I could just use -80.0, but I don't think that's the bulk of the problem. I think the problem is deeper and there is an entirely different, better way to write the code from the ground up. I just don't know what that might be.Code:`(* This function block takes a bipolar floating point -100 to +100 reference with zero deadband and converts it to a unipolar integer reference with deadband compensation and multipoint mapping linearization for a bidirectional analog proportional flow control valve with nonlinear output. (EX: 2500 [full reverse] to 7500 [full forward] with deadband [zero speed] from 4000 to 6000) (*define variables and constants:*) X1_Neg100:= -100.0; Y1_NEG100Float:= INT_TO_REAL(NEG100); X2_Neg80:= -80.0; Y2_NEG80Float:= INT_TO_REAL(NEG80); X3_Neg60:= -60.0; Y3_NEG60Float:= INT_TO_REAL(NEG60); X4_Neg40:= -40.0; Y4_NEG40Float:= INT_TO_REAL(NEG40); X5_Neg20:= -20.0; Y5_NEG20Float:= INT_TO_REAL(NEG20); X6_Neg1:= -1.0; Y6_NEG1Float:= INT_TO_REAL(NEG1); X7_Pos1:= +1.0; Y7_POS1Float:= INT_TO_REAL(POS1); X8_Pos20:= +20.0; Y8_POS20Float:= INT_TO_REAL(POS20); X9_Pos40:= +40.0; Y9_POS40Float:= INT_TO_REAL(POS40); X10_Pos60:= +60.0; Y10_POS60Float:= INT_TO_REAL(POS60); X11_Pos80:= +80.0; Y11_POS80Float:= INT_TO_REAL(POS80); X12_Pos100:= +100.0; Y12_POS100Float:= INT_TO_REAL(POS100); (*INPUT CONDITIONING - invert incoming value an apply speed limit if speed limit if desired*) IF Invert = TRUE THEN IF SpeedLimit = TRUE THEN InputFloat_X:= Input_float100*(-1.0)*ScalingFactor*(0.5); ELSE InputFloat_X:= Input_float100*(-1.0)*ScalingFactor; END_IF; ELSE IF SpeedLimit = TRUE THEN InputFloat_X:= Input_float100*ScalingFactor*(0.5); ELSE InputFloat_X:= Input_float100*ScalingFactor; END_IF; END_IF; (*calculate slope and y-intercept of line segments for positive range and negative range:*) IF Input_float100 > X11_Pos80 THEN ValveCenter:= FALSE; M_Slope:= (Y12_POS100Float-Y11_POS80Float)/(X12_Pos100-X11_Pos80); Y_Int_B:= Y12_POS100Float-(M_Slope*X12_Pos100); ELSIF Input_float100 < X11_Pos80 AND Input_float100 > X10_Pos60 THEN ValveCenter:= FALSE; M_Slope:= (Y11_POS80Float-Y10_POS60Float)/(X11_Pos80-X10_Pos60); Y_Int_B:= Y11_POS80Float-(M_Slope*X11_Pos80); ELSIF Input_float100 < X10_Pos60 AND Input_float100 > X9_Pos40 THEN ValveCenter:= FALSE; M_Slope:= (Y10_POS60Float-Y9_POS40Float)/(X10_Pos60-X9_Pos40); Y_Int_B:= Y10_POS60Float-(M_Slope*X10_Pos60); ELSIF Input_float100 < X9_Pos40 AND Input_float100 > X8_Pos20 THEN ValveCenter:= FALSE; M_Slope:= (Y9_POS40Float-Y8_POS20Float)/(X9_Pos40-X8_Pos20); Y_Int_B:= Y9_POS40Float-(M_Slope*X9_Pos40); ELSIF Input_float100 < X8_Pos20 AND Input_float100 > X7_Pos1 THEN ValveCenter:= FALSE; M_Slope:= (Y8_POS20Float-Y7_POS1Float)/(X8_Pos20-X7_Pos1); Y_Int_B:= Y8_POS20Float-(M_Slope*X8_Pos20); ELSIF Input_float100 < X7_Pos1 AND Input_float100 > X6_Neg1 THEN ValveCenter:= TRUE; ELSIF Input_float100 < X6_Neg1 AND Input_float100 > X5_Neg20 THEN ValveCenter:= FALSE; M_Slope:= (Y6_NEG1Float-Y5_NEG20Float)/(X6_Neg1-X5_Neg20); Y_Int_B:= Y6_NEG1Float-(M_Slope*X6_Neg1); ELSIF Input_float100 < X5_Neg20 AND Input_float100 > X4_Neg40 THEN ValveCenter:= FALSE; M_Slope:= (Y5_NEG20Float-Y4_NEG40Float)/(X5_Neg20-X4_Neg40); Y_Int_B:= Y5_NEG20Float-(M_Slope*X5_Neg20); ELSIF Input_float100 < X4_Neg40 AND Input_float100 > X3_Neg60 THEN ValveCenter:= FALSE; M_Slope:= (Y4_NEG40Float-Y3_NEG60Float)/(X4_Neg40-X3_Neg60); Y_Int_B:= Y4_NEG40Float-(M_Slope*X4_Neg40); ELSIF Input_float100 < X3_Neg60 AND Input_float100 > X2_Neg80 THEN ValveCenter:= FALSE; M_Slope:= (Y3_NEG60Float-Y2_NEG80Float)/(X3_Neg60-X2_Neg80); Y_Int_B:= Y3_NEG60Float-(M_Slope*X3_Neg60); ELSIF Input_float100 < X2_Neg80 THEN ValveCenter:= FALSE; M_Slope:= (Y2_NEG80Float-Y1_NEG100Float)/(X2_Neg80-X1_Neg100); Y_Int_B:= Y2_NEG80Float-(M_Slope*X2_Neg80); END_IF; (*write valve output*) IF ValveCenter= TRUE THEN OutputFloat_Y:= +5000.0; ELSE OutputFloat_Y:= M_Slope*InputFloat_X+Y_Int_B; END_IF; OutputInt:= REAL_TO_INT(OutputFloat_Y);`