(* @PATH := '\/Functions_Collection' *) (* @SYMFILEFLAGS := '0' *) FUNCTION_BLOCK ADSVARWRITE VAR_INPUT NETID : STRING(21); PORT : UINT; VARNAME : STRING(101); SRCLEN : UDINT; SRCADDR : DWORD; CONNECT : BOOL; WRITE : BOOL; TMOUT : TIME; END_VAR VAR_OUTPUT CONNECTED: BOOL; BUSY : BOOL; ERR : BOOL; ERRID : UDINT; END_VAR VAR i_NETID : STRING(21); i_PORT : UINT; i_VARNAME : STRING(101); i_SRCLEN : UDINT; i_SRCADDR : DWORD; i_TMOUT : TIME; i_IdxOffset : UDINT; fbRTrigCon : R_TRIG; fbRWCon : ADSRDWRT; fbWDiscon : ADSWRITE; fbAdsWrite : ADSWRITE; fbBlockTimer : TOF; tBlockTime : TIME; iState : INT; END_VAR (* @END_DECLARATION := '0' *) fbRTrigCon(CLK:= CONNECT); tBlockTime := T#60s; fbBlockTimer(IN:=FALSE , PT:=tBlockTime ); CASE iState OF 0: (* Awaiting CONNECT *) ERR:=FALSE; CONNECTED:=FALSE; IF WRITE THEN BUSY:=TRUE; (* go error state, but create signals ... *) ERRID:=0; iState:=-1; ELSIF CONNECT THEN (* rising edge at CONNECT input, save input vars *) i_NETID:=NETID; i_PORT:=PORT; i_VARNAME:=VARNAME; i_SRCLEN:=SRCLEN; i_SRCADDR:=SRCADDR; i_TMOUT:=TMOUT; (* go active ... *) BUSY:=TRUE; ERRID:=0; IF fbBlockTimer.Q THEN iState:=-2; (* still blocked out, go error state, but create signals ... *) ELSE fbRWCon(WRTRD:=FALSE); iState:=10; (* start varconnect ... *) END_IF ELSE BUSY:=FALSE; (* still waiting ... *) END_IF -1: (* Tried to start without connect *) BUSY:=FALSE; ERR:=TRUE; ERRID:=16#FFFFFFFF; IF NOT WRITE THEN iState:=0; (* go idle *) END_IF -2: (* Tried to connect while still blocked out *) BUSY:=FALSE; ERR:=TRUE; ERRID:=16#FFFFFFFE; IF NOT CONNECT THEN iState:=0; (* go idle *) END_IF (* ########################################################## *) 10: (* Sending var connect request *) fbRWCon.NETID:=i_NETID; fbRWCon.PORT:=i_PORT; fbRWCon.IDXGRP:=ADS_IDXGRP_GETVARHANDLEBYNAME; fbRWCon.IDXOFFS:=16#0; fbRWCon.WRITELEN:= LEN(i_VARNAME); fbRWCon.READLEN:=SIZEOF(i_IdxOffset); fbRWCon.SRCADDR:=ADR(i_VARNAME); fbRWCon.DESTADDR:=ADR(i_IdxOffset); fbRWCon.TMOUT:=i_TMOUT; fbRWCon.WRTRD:=TRUE; fbRWCon(); iState:=11; (* go ahead *) 11: (* Sending var connect request *) fbRWCon(); IF NOT fbRWCon.BUSY THEN BUSY:=FALSE; IF fbRWCon.ERR THEN ERR:=TRUE; ERRID:=fbRWCon.ERRID; fbBlockTimer(IN:=(fbRWCon.ERRID=16#745) AND (PORT<>uiS7ADS_PORTNO)); iState:=-11; (* go error state *) ELSE (* Succeded *) CONNECTED:=TRUE; (* Prepare for writing *) fbAdsWrite.WRITE:=FALSE; fbAdsWrite(); iState:=20; (* go ahead *) END_IF fbRWCon.WRTRD:=FALSE; fbRWCon(); END_IF -11: (* wasn't able to connect *) IF NOT CONNECT THEN iState:=0; (* go idle *) END_IF (* ########################################################## *) 20: (* awaiting DISCONNECT or WRITE *) ERR:=FALSE; IF WRITE THEN BUSY:=TRUE; (* go ahead ... *) ERRID:=0; IF fbBlockTimer.Q THEN iState:=-40; (* still blocked out, go error state, but create signals ... *) ELSE iState:=40; fbAdsWrite(WRITE:=FALSE); END_IF ELSIF NOT CONNECT THEN BUSY:=TRUE; ERRID:=0; (* Prepare for Disconnect *) IF fbBlockTimer.Q THEN iState:=-30; (* still blocked out, go error state, but create signals ... *) ELSE fbWDiscon(WRITE:=FALSE); iState:=30; (* go ahead *) END_IF ELSE BUSY:=FALSE; (* still waiting ... *) END_IF 30: (* Sending var disconnect request *) fbWDiscon.NETID:=i_NETID; fbWDiscon.PORT:=i_PORT; fbWDiscon.IDXGRP:=ADS_IDXGRP_RELEASEVARHANDLE; fbWDiscon.IDXOFFS:=i_IdxOffset; fbWDiscon.LEN:= SIZEOF(i_IdxOffset); fbWDiscon.SRCADDR:=ADR(i_IdxOffset); fbWDiscon.TMOUT:=i_TMOUT; fbWDiscon.WRITE:= TRUE; fbWDiscon(); iState:=31; (* go ahead *) 31: (* Sending var disconnect request *) fbWDiscon(); IF NOT fbWDiscon.BUSY THEN BUSY:=FALSE; IF fbWDiscon.ERR THEN ERR:=TRUE; ERRID:=fbRWCon.ERRID; fbBlockTimer(IN:=(fbRWCon.ERRID=16#745) AND (PORT<>uiS7ADS_PORTNO)); iState:=-31; (* go error state *) ELSE (* Succeded *) CONNECTED:=FALSE; iState:=0; (* go idle *) END_IF fbWDiscon.WRITE:= FALSE; fbWDiscon(); END_IF -30: (* tried to DISCONNECT while still blocked out *) BUSY:=FALSE; ERR:=TRUE; ERRID:=16#FFFFFFFD; IF CONNECT THEN iState:=20; (* go back *) END_IF -31: (* wasn't able to DISCONNECT *) IF CONNECT THEN iState:=20; (* go back *) END_IF (* ########################################################## *) 40: (* Sending read request *) fbAdsWrite.NETID:=i_NETID; fbAdsWrite.PORT:=i_PORT; fbAdsWrite.IDXGRP:=ADS_IDXGRP_READVARBYHANDLE; fbAdsWrite.IDXOFFS:=i_IdxOffset; fbAdsWrite.LEN:=i_SRCLEN; fbAdsWrite.SRCADDR:=i_SRCADDR; fbAdsWrite.TMOUT:=i_TMOUT; fbAdsWrite.WRITE:=TRUE; fbAdsWrite(); iState:=41; (* go ahead *) 41: (* Sending read request *) fbAdsWrite(); IF NOT fbAdsWrite.BUSY THEN BUSY:=FALSE; IF fbAdsWrite.ERR THEN ERR:=TRUE; ERRID:=fbAdsWrite.ERRID; fbBlockTimer(IN:=(fbAdsWrite.ERRID=16#745) AND (PORT<>uiS7ADS_PORTNO)); iState:=-41; (* go error state *) ELSE iState:=42; (* go ahead *) END_IF fbAdsWrite.WRITE:=FALSE; fbAdsWrite(); END_IF 42: (* Sending read request *) IF NOT WRITE THEN iState:=20; (* go idle *) END_IF -40: (* tried to WRITE while still blocked out *) BUSY:=FALSE; ERR:=TRUE; ERRID:=16#FFFFFFFC; IF NOT WRITE THEN iState:=20; (* go back *) END_IF -41: (* wasn't able to WRITE *) IF NOT WRITE THEN iState:=20; (* go back *) END_IF (* ########################################################## *) ELSE BUSY:=FALSE; ERR:=TRUE; ERRID:=16#FFFFFF00; IF NOT CONNECT AND NOT WRITE THEN iState:=0; (* go idle *) END_IF END_CASE END_FUNCTION_BLOCK