So this is basically how I approach two areas that I saw in your code.
IF conditions, I do my best to keep "uniform" (can't think of a better term). For example:
IF COLOR = White THEN
do this stuff;
ELSIF COLOR = BLUE THEN
// here I may prepare condition for another IF or CASE
ENGINE_TROUBLE := TRUE; // blue smoke or something
ELSE
do something different;
END_IF;
What I avoid is mixing two case or if statments:
IF COLOR = WHITE THEN
do this;
ELSIF ENGINE_STATUS = TROUBLE THEN
shut the engine off;
END_IF;
The above is difficult to follow by someone who is not intimately familiar with the code, or me after months or years.
For block enable I pretty much follow a template and add or remove from it as needed but again on requirement is to have my IF condition very easy to follow, a quick scan of the first section tells you when the block is enabled.
Then I follow Siemens and I think PLCOpen recommendation for status and error reporting and that I satisfy the requirement that goes with Enable which is to BLOCK_ENABLED, or ACTIVE or anything you want to call it.
Note: I made some quick changes in the code while posting and hopefully didn't screw it up, should still make the point.
Code:
FUNCTION_BLOCK "FB_Enable"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
Enable : Bool;
END_VAR
VAR_OUTPUT
ob_IS_Enabled : Bool;
ob_IS_Error : Bool;
Status : Word;
END_VAR
VAR_IN_OUT
END_VAR
VAR
Enable_Edge : Bool;
END_VAR
VAR_TEMP
tmpb_Init : Bool;
tmpb_IS_Block_Enabled : Bool;
tmpw_STATUS : Word;
tmpb_IS_Error : Bool;
END_VAR
VAR CONSTANT
//enable
BLOCK_ENABLED : Word := 16#7003; // block enabled
BLOCK_DISABLED : Word := 16#7004; // block disabled
// status
NO_ERROR : Word := 16#0000; // No errors
AWATING_FOR_REQUEST : Word := 16#0001; // got positions and wating for request to add more or load more
NO_CURRENT_JOBS : Word := 16#7000; // Initial value= IDLE
NO_POS_PENDING : Word := 16#8201; // no positions to process
INVALID_COUNTER_VALUE : Word := 16#8202; // counter value is invalid
INVALID_TARGET_POS : Word := 16#8203; // 1<= target position<=maximum counter value<=2147483647
INVALID_MAX_COUNTER_VAL : Word := 16#8204; // maximum counter value has to be greater than zero
END_VAR
BEGIN
// --------------------------------------------------------------------------------------------
//FUNCTION: Enable
//---------------------------------------------------------------------------------------------
//Enables and disables the block
//-------------------------------------------------------------------------------------------
IF NOT #Enable AND #Enable_Edge THEN // falling edge of enable
#tmpb_Init := TRUE; // reset the tags on the way out which is done at the bottom.
ELSIF NOT #Enable THEN
// exit block, return**nothing to do**
#ob_IS_Enabled := FALSE:
#Status := #BLOCK_DISABLED;
RETURN;
ELSIF #Enable AND NOT #Enable_Edge THEN //rising edge of enable
// intitialize variables
#tmpb_Init := TRUE;
ELSE
#ob_IS_Enabled := #tmpb_IS_Block_Enabled := TRUE;
//block Status
#tmpw_STATUS := #NO_ERROR; // idle
END_IF;
#Enable_Edge := #Enable;
// --------------------------------------------------------------------------------------------
//beginning of block execution
//---------------------------------------------------------------------------------------------
IF #tmpb_IS_Block_Enabled THEN
// block code goes here
//
//
//
// Update outputs
// ***********output tags here*******
// output status
#ob_IS_Error := #tmpb_IS_Error;
#Status := #tmpw_STATUS;
END_IF; // end of enable
// --------------------------------------------------------------------------------------------
//Reset variables
//---------------------------------------------------------------------------------------------
IF #tmpb_IS_Block_Enabled THEN
// Initialize some variables
;
END_IF;
END_FUNCTION_BLOCK