(* @PATH := '\/Functions_Collection' *) (* @SYMFILEFLAGS := '0' *) FUNCTION_BLOCK ADSVARREAD VAR_INPUT NETID : STRING(21); PORT : UINT; VARNAME : STRING(101); DESTLEN : UDINT; DESTADDR : DWORD; CONNECT : BOOL; READ : 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_DESTLEN : UDINT; i_DESTADDR : DWORD; i_TMOUT : TIME; i_IdxOffset : UDINT; fbRTrigCon : R_TRIG; fbRWCon : ADSRDWRT; fbWDiscon : ADSWRITE; fbAdsRead : ADSREAD; 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 READ 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_DESTLEN:=DESTLEN; i_DESTADDR:=DESTADDR; 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 READ 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 Reading *) fbAdsRead.READ:=FALSE; fbAdsRead(); 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 READ *) ERR:=FALSE; IF READ 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; fbAdsRead(READ:=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 *) fbAdsRead.NETID:=i_NETID; fbAdsRead.PORT:=i_PORT; fbAdsRead.IDXGRP:=ADS_IDXGRP_READVARBYHANDLE; fbAdsRead.IDXOFFS:=i_IdxOffset; fbAdsRead.LEN:=i_DESTLEN; fbAdsRead.DESTADDR:=i_DESTADDR; fbAdsRead.TMOUT:=i_TMOUT; fbAdsRead.READ:=TRUE; fbAdsRead(); iState:=41; (* go ahead *) 41: (* Sending read request *) fbAdsRead(); IF NOT fbAdsRead.BUSY THEN BUSY:=FALSE; IF fbAdsRead.ERR THEN ERR:=TRUE; ERRID:=fbAdsRead.ERRID; fbBlockTimer(IN:=(fbAdsRead.ERRID=16#745) AND (PORT<>uiS7ADS_PORTNO)); iState:=-41; (* go error state *) ELSE iState:=42; (* go ahead *) END_IF fbAdsRead.READ:=FALSE; fbAdsRead(); END_IF 42: (* Sending read request *) IF NOT READ THEN iState:=20; (* go idle *) END_IF -40: (* tried to READ while still blocked out *) BUSY:=FALSE; ERR:=TRUE; ERRID:=16#FFFFFFFC; IF NOT READ THEN iState:=20; (* go back *) END_IF -41: (* wasn't able to READ *) IF NOT READ THEN iState:=20; (* go back *) END_IF (* ########################################################## *) ELSE BUSY:=FALSE; ERR:=TRUE; ERRID:=16#FFFFFF00; IF NOT CONNECT AND NOT READ THEN iState:=0; (* go idle *) END_IF END_CASE END_FUNCTION_BLOCK