flow

mail@pastecode.io avatar
unknown
pascal
a year ago
10 kB
2
Indexable
Never
FUNCTION_BLOCK "FlowMeters"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      RstCounters_ch1 : Bool;
      RstCounters_ch2 : Bool;
      Init : Bool;
   END_VAR
   VAR_INPUT RETAIN
      ch1_enabled : Bool;
      ch2_enabled : Bool;
   END_VAR

   VAR_OUTPUT 
      mass_flow_ch1 : Real;
      mass_flow_ch2 : Real;
      den_ch1 : Real;
      den_ch2 : Real;
      temp_ch1 : Real;
      temp_ch2 : Real;
      vol_flow_ch1 : Real;
      vol_flow_ch2 : Real;
      mass_cntr_ch1 : Real;
      mass_cntr_ch2 : Real;
      vol_cntr_ch1 : Real;
      vol_cntr_ch2 : Real;
      comm_err_ch1 : Bool;
      comm_err_ch2 : Bool;
      ch1_status : Int;
      ch2_status : Int;
      cur_mass_cntr_ch1 : Real;
      cur_mass_cntr_ch2 : Real;
      cur_vol_cntr_ch1 : Real;
      cur_vol_cntr_ch2 : Real;
   END_VAR

   VAR 
      Comm_load {InstructionName := 'Modbus_Comm_Load'; LibVersion := '3.1'} : Modbus_Comm_Load;
      Master {InstructionName := 'Modbus_Master'; LibVersion := '3.2'} : Modbus_Master;
      master_done { S7_SetPoint := 'True'} : Bool;
      master_busy : Bool;
      Master_error : Bool;
      Master_error_code : Word;
      error_code_ch1 : Word;
      error_code_ch2 : Word;
      ControlVar : Int;
      Send_P2P_Instance {InstructionName := 'Send_P2P'; LibVersion := '3.1'} : Send_P2P;
   END_VAR

   VAR_TEMP 
      i : Int;
   END_VAR

   VAR CONSTANT 
      log_1 : Word := 16#FF00;
   END_VAR


BEGIN
	IF #Init THEN
	    //Зануляем управляющий счётчик
	    #ControlVar := 0;
	    //Зануляем выходные переменные блока
	    #mass_flow_ch1 := 0;
	    #mass_flow_ch2 := 0;
	    #den_ch1 := 0;
	    #den_ch2 := 0;
	    #temp_ch1 := 0;
	    #temp_ch2 := 0;
	    #vol_flow_ch1 := 0;
	    #vol_flow_ch2 := 0;
	    #mass_cntr_ch1 := 0;
	    #mass_cntr_ch2 := 0;
	    #vol_cntr_ch1 := 0;
	    #vol_cntr_ch2 := 0;
	    #cur_mass_cntr_ch1 := 0;
	    #cur_mass_cntr_ch2 := 0;
	    #cur_vol_cntr_ch1 := 0;
	    #cur_vol_cntr_ch2 := 0;
	    #comm_err_ch1 := FALSE;
	    #comm_err_ch2 := FALSE;
	
	    "FlowMeters_data".rst.b01 := TRUE;
	
	    
	    //Устанавливаем режим работы порта
	    #Comm_load.MODE := 4;
	    
	    FILL_BLK(IN := 16#0,
	             COUNT := 8,
	             OUT => "FlowMeters_data".WriteBuf[0]);
	    
	    FILL_BLK(IN := 16#0,
	             COUNT := 12,
	             OUT => "FlowMeters_data".ReadBuf[0]);
	    
	END_IF;
	
	//Инит порта
	#Comm_load(REQ := #Init,
	           "PORT" := "Local~8B1_5",
	           BAUD := 9600,
	           PARITY := 0,
	           MB_DB := #Master.MB_DB);
	
	//Основной конечный автомат
	CASE #ControlVar OF
	    //0 - канал 1 проверка флага обнуления
	    0:
	            IF (NOT #ch1_enabled AND #RstCounters_ch1) THEN
	                
	               #Master(REQ := true,
	                            MB_ADDR := 1,
	                            MODE := 1,
	                            DATA_ADDR := 0004,
	                            DATA_LEN := 1,
	                            DONE => #master_done,
	                            BUSY => #master_busy,
	                            ERROR => #Master_error,
	                            STATUS => #Master_error_code,
	                            DATA_PTR := "FlowMeters_data".rst); 
	            ELSE
	                 #ControlVar := 1;
	            END_IF;
	    //1 канал 2 проверка флага обнуления   
	    1:
	        IF (NOT #ch2_enabled AND #RstCounters_ch2) THEN
	
	                       #Master(REQ := true,
	                        MB_ADDR := 2,
	                        MODE := 1,
	                        DATA_ADDR := 0004,
	                        DATA_LEN := 1,
	                        DONE => #master_done,
	                        BUSY => #master_busy,
	                        ERROR => #Master_error,
	                        STATUS => #Master_error_code,
	                        DATA_PTR := "FlowMeters_data".rst);
	            ELSE
	                #ControlVar := 2;
	            END_IF; 
	        2:
	        IF #ch1_enabled THEN
	            //Читаем данные со счётчика №1
	                       #Master(REQ := TRUE,
	                    MB_ADDR := 1,
	                    MODE := 0,
	                    DATA_ADDR := 400168,
	                    DATA_LEN := 12,
	                    DONE => #master_done,
	                    BUSY => #master_busy,
	                    ERROR => #Master_error,
	                    STATUS => #Master_error_code,
	                    DATA_PTR := P#DB6.DBX16.0 WORD 12);
	        ELSE
	            #ControlVar := 3;
	        END_IF;
	    3:
	        IF #ch2_enabled THEN
	            
	            //Читаем данные со счётчика №2
	                        #Master(REQ := TRUE,
	                    MB_ADDR := 2,
	                    MODE := 0,
	                    DATA_ADDR := 400168,
	                    DATA_LEN := 12,
	                    DONE => #master_done,
	                    BUSY => #master_busy,
	                    ERROR => #Master_error,
	                    STATUS => #Master_error_code,
	                    DATA_PTR := P#DB6.DBX16.0 WORD 12);
	        ELSE
	            #ControlVar := 4;
	        END_IF;
	        
	    4:
	       IF #ch1_enabled THEN
	                     #Master(REQ := TRUE,
	                    MB_ADDR := 1,
	                    MODE := 0,
	                    DATA_ADDR := 400259,
	                    DATA_LEN := 8,
	                    DONE => #master_done,
	                    BUSY => #master_busy,
	                    ERROR => #Master_error,
	                    STATUS => #Master_error_code,
	                    DATA_PTR := P#DB6.DBX16.0 WORD 8);
	        ELSE
	            #ControlVar := 5;
	        END_IF;
	    5:
	        IF #ch2_enabled THEN
	                    #Master(REQ := TRUE,
	                    MB_ADDR := 2,
	                    MODE := 0,
	                    DATA_ADDR := 400259,
	                    DATA_LEN := 8,
	                    DONE => #master_done,
	                    BUSY => #master_busy,
	                    ERROR => #Master_error,
	                    STATUS => #Master_error_code,
	                    DATA_PTR := P#DB6.DBX16.0 WORD 8);
	        ELSE
	            #ControlVar := 0;
	        END_IF;
	   END_CASE;
	 
	 IF #master_done THEN
	     CASE #ControlVar OF
	         0:
	
	                 #comm_err_ch1 := false;
	                 #error_code_ch1 := 0;
	
	         1:
	
	                 #comm_err_ch2 := false;
	                 #error_code_ch2 := 0;
	
	         2:
	
	                 #mass_flow_ch1 := "FlowMeters_data".ReadBuf[0];
	                 #den_ch1 := "FlowMeters_data".ReadBuf[1];
	                 #temp_ch1 := "FlowMeters_data".ReadBuf[2];
	                 #vol_flow_ch1 := "FlowMeters_data".ReadBuf[3];
	                 #mass_cntr_ch1 := "FlowMeters_data".ReadBuf[4];
	                 #vol_cntr_ch1 := "FlowMeters_data".ReadBuf[5];
	                 #comm_err_ch1 := false;
	                 #error_code_ch1 := 0;
	
	         3:
	
	                 #mass_flow_ch2 := "FlowMeters_data".ReadBuf[0];
	                 #den_ch2 := "FlowMeters_data".ReadBuf[1];
	                 #temp_ch2 := "FlowMeters_data".ReadBuf[2];
	                 #vol_flow_ch2 := "FlowMeters_data".ReadBuf[3];
	                 #mass_cntr_ch2 := "FlowMeters_data".ReadBuf[4];
	                 #vol_cntr_ch2 := "FlowMeters_data".ReadBuf[5];
	                 #comm_err_ch2 := false;
	                 #error_code_ch2 := 0;
	             4:
	                 #cur_mass_cntr_ch1 := "FlowMeters_data".ReadBuf[2];
	                 #cur_vol_cntr_ch1 := "FlowMeters_data".ReadBuf[3];
	                 #comm_err_ch1 := false;
	                 #error_code_ch1 := 0;
	             5:
	                 #cur_mass_cntr_ch2 := "FlowMeters_data".ReadBuf[2];
	                 #cur_vol_cntr_ch2 := "FlowMeters_data".ReadBuf[3];
	                 #comm_err_ch2 := false;
	                 #error_code_ch2 := 0;
	         END_CASE;
	
	 END_IF; 
	 
	  IF NOT #ch1_enabled THEN
	     #mass_flow_ch1 := -1;
	     #den_ch1 := -1;
	     #temp_ch1 := -1;
	     #vol_flow_ch1 := -1;
	     #mass_cntr_ch1 := -1;
	     #vol_cntr_ch1 := -1;
	     #comm_err_ch1 := false;
	     #error_code_ch1 := 0;
	     #cur_mass_cntr_ch1 := -1;
	     #cur_vol_cntr_ch1 := -1;
	 END_IF;
	 
	 IF NOT #ch2_enabled THEN
	     #mass_flow_ch2 := -1;
	     #den_ch2 := -1;
	     #temp_ch2 := -1;
	     #vol_flow_ch2 := -1;
	     #mass_cntr_ch2 := -1;
	     #vol_cntr_ch2 := -1;
	     #comm_err_ch2 := false;
	     #error_code_ch2 := 0;
	     #cur_mass_cntr_ch2 := -1;
	     #cur_vol_cntr_ch2 := -1;
	 END_IF;
	 
	 IF #Master_error THEN
	     IF #ControlVar = 0 OR #ControlVar = 2 OR #ControlVar = 4 THEN
	         #comm_err_ch1 := true;
	         #error_code_ch1 := #Master_error_code;
	     END_IF;
	     
	     IF #ControlVar = 1 OR #ControlVar = 3  OR #ControlVar = 5 THEN
	         #comm_err_ch2 := true;
	         #error_code_ch2 := #Master_error_code;
	     END_IF;
	 END_IF;
	 
	 IF #master_done OR #Master_error THEN
	     IF #ControlVar < 5 THEN
	         #ControlVar := #ControlVar + 1;
	     ELSE
	         #ControlVar := 0;
	     END_IF;
	     
	     #master_done := false;
	     #Master_error := false;
	 END_IF;
	 
	 #ch1_status := 0;
	 
	 IF NOT #ch1_enabled THEN
	     #ch1_status := 2;
	 END_IF;
	 
	 IF #comm_err_ch1 THEN
	     #ch1_status := 1;
	 END_IF;
	 
	 #ch2_status := 0;
	 
	 IF NOT #ch2_enabled THEN
	     #ch2_status := 2;
	 END_IF;
	 
	 IF #comm_err_ch2 THEN
	     #ch2_status := 1;
	 END_IF; 
END_FUNCTION_BLOCK