, ERR=> , ERRID=> , TIMESTR=> GVL.tCurrentTime); iCurrentTimeSec := GVL.tCurrentTime.wHour*3600 + GVL.tCurrentTime.wMinute*60 + GVL.tCurrentTime.wSecond; WindSensor(); (****************************) // link to the outside temperature // NEED TO ADD ERROR CHECKING IF IO.TS3003_OutT1 <= IO.TS3007_OutT2 AND NOT GVL.bHMI_DisableOut1T_TC AND NOT GVL.bHMI_DisableOut2T_TC THEN GVL.iTempOutside := IO.TS3003_OutT1; ELSIF IO.TS3003_OutT1 > IO.TS3007_OutT2 AND NOT GVL.bHMI_DisableOut1T_TC AND NOT GVL.bHMI_DisableOut2T_TC THEN GVL.iTempOutside := IO.TS3007_OutT2; ELSIF GVL.bHMI_DisableOut1T_TC THEN GVL.iTempOutside := IO.TS3007_OutT2; ELSIF GVL.bHMI_DisableOut2T_TC THEN GVL.iTempOutside := IO.TS3003_OutT1; ELSE GVL.iTempOutside := -200; END_IF IF GVL.iTempOutside > 1000 OR (IO.TS3003_OutT1>1000 AND IO.TS3007_OutT2>1000) THEN GVL.iTempOutside := -200; // If for any reason outside temperature is out of the reasonable range, set it -20°C END_IF // Apply Chill Factor // GVL.iTempOutsideChill := GVL.iTempOutside + REAL_TO_INT((INT_TO_REAL((GVL.W.iWindChillT - GVL.iTempOutside)) * INT_TO_REAL(Set.iChillFactorUsage)/100.0)); Set.iSetMaxOper := REAL_TO_INT(Set.fHMI_SetMaxOper*10.0); (****************************) // Init Heat table from default values for each zone table // IF GVL.bHMI_HeatTableInit THEN Init_HeatLevels(); END_IF (****************************) // Activate Heat Enable if Main Mode Switch is in AUTO Mode. // IF IO.inCR1024_SftyBACREL AND GVL.iTempOutside <= Set.iSetMaxOper THEN // Set.iSetMaxOperHyst Set.HeatEnabled := TRUE; END_IF IF GVL.iTempOutside > Set.iSetMaxOper + Set.iSetMaxOperHyst THEN Set.HeatEnabled := FALSE; END_IF // Set Heat enable for each zone // IF Set.HeatEnabled THEN FOR i:=1 TO Set.iNoZones DO Set.arApInZone[i].bHeatEnabled := TRUE; END_FOR ELSE FOR i:=1 TO Set.iNoZones DO Set.arApInZone[i].bHeatEnabled := FALSE; END_FOR END_IF // Calculate required heat per each zone // FOR i := 1 TO Set.iNoZones DO Zone[i].iZoneNo := i; Zone[i](); END_FOR // Calculate Building Avarage Temperature // tmp := 0; FOR i:=1 TO Set.iNoZones DO tmp:= GVL.arZoneData[i].iTAver + tmp; END_FOR GVL.iTempAverage := tmp / Set.iNoZones; // Sum Zone's temperature and divide by nomber of zones HMI_SortApartments(); SSR_Outputs(); RelayOutputs(); MAU(); GVL.currentUserName:=visuelems.CurrentUserName; // Send_email(); Alarms();]]> 0 AND floor <= Set.iNoOfFloors THEN // n := xf[floor]; n := GVL.arZoneData[z].arAp[a].iFloorIndex; IF n>0 AND n<=Set.iNoApFloorMax THEN GVL.arHMIApt[floor,n].bSSR := GVL.arZoneData[z].arAp[a].bSSR; GVL.arHMIApt[floor,n].iAp := GVL.arZoneData[z].arAp[a].iAp; GVL.arHMIApt[floor,n].fValue := GVL.arZoneData[z].arAp[a].HMI_Value; GVL.arHMIApt[floor,n].bVisible := GVL.arZoneData[z].arAp[a].HMI_Visible; GVL.arHMIApt[floor,n].fT_SP := INT_TO_REAL(GVL.arZoneData[z].arAp[a].iT_SP)/10; GVL.arHMIApt[floor,n].iZoneNo := z; GVL.arHMIApt[floor,n].iInZoneNo := a; // xf[floor] := xf[floor]+1; // Increase index to write next apartment data into floor array of apartments END_IF END_IF END_IF END_FOR END_FOR IF Set.fSetT_HMI > 0.0 AND Set.fSetT_HMI<> REAL_TO_INT(Set.fSetT_HMI*10.0) THEN FOR f := 1 TO Set.iNoOfFloors DO FOR k:=1 TO Set.iNoApFloorMax DO IF GVL.arHMIApt[f,k].fT_SP = INT_TO_REAL(Set.iSetT)/10.0 THEN//check accordance of apt sp to building sp GVL.arHMIApt[f,k].fT_SP:=Set.fSetT_HMI; Set.arApt_T_SP[f,k]:=REAL_TO_INT(Set.fSetT_HMI*10.0); END_IF END_FOR END_FOR Set.iSetT:=REAL_TO_INT(Set.fSetT_HMI*10.0); END_IF]]> 100 THEN z := Set.arApartInit[i,a].iZone; // Read Zone number GVL.arZoneData[z].arAp[x[z]].iZone := z; // Fill up iZone Zone number where the appartment is GVL.arZoneData[z].arAp[x[z]].iAp := Set.arApartInit[i,a].iAp; GVL.arZoneData[z].arAp[x[z]].iFloor := ABS(Set.arApartInit[i,a].iAp/100); GVL.arZoneData[z].arAp[x[z]].iFloorIndex := Set.arApartInit[i,a].iAp - GVL.arZoneData[z].arAp[x[z]].iFloor * 100; // Shift index if Apartment number is >12 as Apartment 13 doesn't exist IF GVL.arZoneData[z].arAp[x[z]].iFloorIndex >12 THEN GVL.arZoneData[z].arAp[x[z]].iFloorIndex := GVL.arZoneData[z].arAp[x[z]].iFloorIndex -1; END_IF GVL.arZoneData[z].arAp[x[z]].iT_SP := Set.iSetT; // Need to move it out to make set different per apartment GVL.arZoneData[z].arAp[x[z]].HMI_Visible := TRUE; x[z] := x[z]+1; // Increase index to write next apartment data into zone array of apartments END_IF END_FOR END_FOR FOR i := 1 TO Set.iNoZones DO Set.arApInZone[i].iApsNo := x[i] - 1; // Automatically fill up number of apartments in the each zone END_FOR ]]> , PID_Y=> IO.MAU1_BoilerCTRL); *) IF GVL.iTempOutside < Set.iSetMaxOper THEN IO.MAU1_TemperatureSET := REAL_TO_INT(SCALE_R( // Scale set temperature to proper integer 0..32767 X:= Set.fSetTMAU_N, I_LO:= Set.MAU_N_0V, // 10 I_HI:= Set.MAU_N_10V, // 35 O_LO:= 0.0, O_HI:= 32767.0)); GVL.bHMI_MAU1_HeatON := TRUE; END_IF IF GVL.iTempOutside > Set.iSetMaxOper +10 THEN IO.MAU1_TemperatureSET := 0; // If Outside temperature is high, turn OFF MAU heater T command, 0VDC GVL.bHMI_MAU1_HeatON := FALSE; END_IF // ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ MAU SOUTH ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ // MAU 2 // SOUTH // 10..35°C scale IF GVL.iTempOutside < Set.iSetMaxOper THEN IO.CR2544_MAU_S_CTRL := TRUE; IO.MAU2_TemperatureSET := REAL_TO_INT(SCALE_R( // Scale set temperature to proper integer 0..32767 X:= Set.fSetTMAU_S, I_LO:= Set.MAU_S_0V, // 10°C I_HI:= Set.MAU_S_10V, // 35°C O_LO:= 0.0, O_HI:= 32767.0)); GVL.bHMI_MAU2_HeatON := TRUE; END_IF IF GVL.iTempOutside > Set.iSetMaxOper +10 THEN IO.CR2544_MAU_S_CTRL := FALSE; // If Outside temperature is high, turn OFF MAU heater IO.MAU2_TemperatureSET := 0; // If Outside temperature is high, turn OFF MAU heater T command, 0VDC GVL.bHMI_MAU2_HeatON := FALSE; END_IF ]]> , ET=> ); // Generate a pulse every 20sec MBRTUExecute := tModBusRTURead.Q; IF MBRTUExecute THEN IF NOT MBRTUReadBusy THEN MBRTUReadExecute := TRUE; ELSE MBRTUReadExecute := FALSE; END_IF ELSE MBRTUReadExecute := FALSE; END_IF IF MBRTUExecute THEN IF MBRTUExecStep = 1 AND NOT MBRTUReadBusy THEN MBRTUStartReg := 41; // dec-41, hex-0x0029 MBRTUExecStep := 2; ELSIF MBRTUExecStep = 2 AND NOT MBRTUReadBusy THEN MBRTUStartReg := 0; // dec-17, hex-0x0011 MBRTUExecStep := 3; ELSIF MBRTUExecStep = 3 AND NOT MBRTUReadBusy THEN MBRTUStartReg := 17; // dec-17, hex-0x0011 MBRTUExecStep := 1; END_IF END_IF MasterRTU.ReadInputRegs( UnitID:= MBRTUMBAddress, // 41 Quantity:= MBRTUQuantity, // 11. 22 bytes or 11 registers as a max MBAddr:= MBRTUStartReg, // 18 and 42 cbLength:= SIZEOF(MBRTUReadValue), pMemoryAddr:= ADR(MBRTUReadValue), AuxQuantity:= , AuxMBAddr:= , AuxcbLength:= , pAuxMemoryAddr:= , Execute:= MBRTUReadExecute, Timeout:= T#5S, BUSY=> MBRTUReadBusy, Error=> MBRTUReadErr, ErrorId=> MBRTUReadErrID, cbRead=> MBRTUcbRead); IF MBRTUReadErr THEN MBRTUReadExecute := FALSE; MBRTUExecute := FALSE; END_IF IF MBRTUExecStep = 1 AND NOT MBRTUReadBusy AND NOT MBRTUReadErr THEN // Starts from Addr 17 GVL.W.iAirPressureAver := WORD_TO_INT(MBRTUReadValue[0]); // Reg:18 Addr:0x0011, 3000..12000, 300..1200 hPa, Err:32767 GVL.W.iWindDirectionInst := WORD_TO_INT(MBRTUReadValue[1]); // Reg:19 Addr:0x0012; 0..3599, 0..359.9° x0.1°, Err:32767 GVL.W.iWindDirectionMin := WORD_TO_INT(MBRTUReadValue[2]); // Reg:20 Addr:0x0013; 0..3599, 0..359.9° x0.1°, Err:32767 GVL.W.iWindDirectionMax := WORD_TO_INT(MBRTUReadValue[3]); // Reg:21 Addr:0x0014; 0..3599, 0..359.9° x0.1°, Err:32767 GVL.W.iWindDirectionAver := WORD_TO_INT(MBRTUReadValue[4]); // Reg:22 Addr:0x0015; 0..3599, 0..359.9° x0.1°, Err:32767 GVL.W.iWindDirectionGust := WORD_TO_INT(MBRTUReadValue[5]); // Reg:23 Addr:0x0016; 0..3599, 0..359.9° x0.1°, Err:32767 END_IF IF MBRTUExecStep = 2 AND NOT MBRTUReadBusy AND NOT MBRTUReadErr THEN // // Starts from Addr 41 GVL.W.iHeaterTemperature := WORD_TO_INT(MBRTUReadValue[0]); // Reg:42 Addr:0x0029 , -500..1500, -50..150°C, Err:32767 GVL.W.iWindSpeedInst := WORD_TO_INT(MBRTUReadValue[1]); // Reg:43 Addr:0x002A; 0..750 x0.1 m/s ; 0..75 m/s GVL.W.iWindSpeedMin := WORD_TO_INT(MBRTUReadValue[2]); // Reg:44 Addr:0x002B; 0..750 x0.1 m/s ; 0..75 m/s GVL.W.iWindSpeedMax := WORD_TO_INT(MBRTUReadValue[3]); // Reg:45 Addr:0x002C; 0..750 x0.1 m/s ; 0..75 m/s GVL.W.iWindSpeedAver := WORD_TO_INT(MBRTUReadValue[4]); // Reg:46 Addr:0x002D; 0..750 x0.1 m/s ; 0..75 m/s GVL.W.iWindSpeedGust := WORD_TO_INT(MBRTUReadValue[6]); // Reg:48 Addr:0x002F, m/s, 0..750, 0..75 m/s, Err:32767 GVL.W.iWindChillT := LREAL_TO_INT((13.12+0.6215*INT_TO_LREAL(GVL.iTempOutside)/10-(11.37-0.3965*INT_TO_LREAL(GVL.iTempOutside)/10)*EXPT(GVL.W.iWindSpeedAver,0.16))*10); END_IF ]]>