CoDeSys+/n  Example_TempSens0.6 vom 8.10.2004A. Schiff, ICS GmbHtDas Programm kommuniziert mit dem Temperatursensor TS001, liest die Eingangsvariable und schreibt die ParameterSoC  .%(2K@KNK\Kq~+yyQs/`SSerial (RS232)Lokal_3S Serial RS232 driver,PortCOM1COM8YBaudrate4800%9600K1920038400576001152004ParityNoEvenOdd3Stop bits11,527dMotorola byteorderNoYesyQs/`SSerial (RS232)Lokal_3S Serial RS232 driver,PortCOM1COM8YBaudrate4800%9600K1920038400576001152004ParityNoEvenOdd3Stop bits11,527dMotorola byteorderNoYesK>,8T,CoDeSys 1-2.2. "$ '(P~@@@@@@MNOP`atyzbcde_Q\RUXZ  "!#$^fghijkFHJLNPRUSTVlopqrsuuv."$ '(tyzbde\RUXZ  "!#$fghijkFHJLNPRUSTVopqrsuuv)g geettiStandard Parameter OD(%Typ des OD-Eintrags whlen. BOOL 8-bit-Integer16-bit-Integer32-bit-Integerbyteword double wordrealstringlong real (64-bit)lowmiddlehigh read only write only read-writeStandard Variable ODlowmiddlehigh read only write only read-writedl I1:ep  Module.Root-1 __not_found__Hardware configurationIBdect * E%QBOO NDAR%MB%Module.ASI_Master11 Module.Root AS-i Master 1IBdect * E%QBOO NDAR%MB%   5AModule.ASI_ABSlave1Module.ASI_Master1 A/B SlaveIBct * E%QB NDAR%MB%aDI0Input 0Channel.ASIBitInput1Module.ASI_ABSlaveIX * E%aDI1Input 1Channel.ASIBitInput2Module.ASI_ABSlaveIX * E%aDI2Input 2Channel.ASIBitInput3Module.ASI_ABSlaveIX * E%aDI3Input 3Channel.ASIBitInput4Module.ASI_ABSlaveIX * E%aDO0Output 0Channel.ASIBitOutput5Module.ASI_ABSlaveQXNDAR%aDO1Output 1Channel.ASIBitOutput6Module.ASI_ABSlaveQXNDAR%aDO2Output 2Channel.ASIBitOutput7Module.ASI_ABSlaveQXNDAR% 30Module.ASI_StdSlave1Module.ASI_Master1 Single SlaveIBct * E%QB NDAR%MB%aDI0Input D0Channel.ASIBitInput1Module.ASI_StdSlaveIX * E%aDI1Input D1Channel.ASIBitInput2Module.ASI_StdSlaveIX * E%aDI2Input D2Channel.ASIBitInput3Module.ASI_StdSlaveIX * E%aDI3Input D3Channel.ASIBitInput4Module.ASI_StdSlaveIX * E%aDO0 Output D0Channel.ASIBitOutput5Module.ASI_StdSlaveQXNDAR%aDO1 Output D1Channel.ASIBitOutput6Module.ASI_StdSlaveQXNDAR%aDO2 Output D2Channel.ASIBitOutput7Module.ASI_StdSlaveQXNDAR%aDO3 Output D3Channel.ASIBitOutput8Module.ASI_StdSlaveQXNDAR%   31AModule.ASI_ABSlave1Module.ASI_Master1 A/B SlaveIBct * E%QB NDAR%MB%aDI0Input 0Channel.ASIBitInput1Module.ASI_ABSlaveIX * E%aDI1Input 1Channel.ASIBitInput2Module.ASI_ABSlaveIX * E%aDI2Input 2Channel.ASIBitInput3Module.ASI_ABSlaveIX * E%aDI3Input 3Channel.ASIBitInput4Module.ASI_ABSlaveIX * E%aDO0Output 0Channel.ASIBitOutput5Module.ASI_ABSlaveQXNDAR%aDO1Output 1Channel.ASIBitOutput6Module.ASI_ABSlaveQXNDAR%aDO2Output 2Channel.ASIBitOutput7Module.ASI_ABSlaveQXNDAR%   31BModule.ASI_ABSlave1Module.ASI_Master1 A/B SlaveIBct * E%QB NDAR%MB%aDI0Input 0Channel.ASIBitInput1Module.ASI_ABSlaveIX  * E%aDI1Input 1Channel.ASIBitInput2Module.ASI_ABSlaveIX  * E%aDI2Input 2Channel.ASIBitInput3Module.ASI_ABSlaveIX  * E%aDI3Input 3Channel.ASIBitInput4Module.ASI_ABSlaveIX  * E%aDO0Output 0Channel.ASIBitOutput5Module.ASI_ABSlaveQX NDAR%aDO1Output 1Channel.ASIBitOutput6Module.ASI_ABSlaveQX NDAR%aDO2Output 2Channel.ASIBitOutput7Module.ASI_ABSlaveQX NDAR%> ϮnAxVAR_GLOBAL END_VAR X# =j"`>$ALonStandard> > ND ϮnA\VAR_CONFIG END_VAR ',BB\Globale_Variablen> B?esVaabs  VAR_GLOBAL ASI1_AUTO_ADDRESS, ASI1_AUTO_ADDRESS_POSSIBLE, ASI1_CONFIG_OK: BOOL; ASI1_NORMAL, ASI1_OFFLINE, ASI1_POWER_FAIL: BOOL; ASI1_PROJECTION_MODE, ASI1_SLAVE0_EXIST, ASI1_PERIPHERY_OK: BOOL; ASI1_AUTO_ADDRESS_ENABLE, ASI1_DATA_EXCHANGE_ACTIVE: BOOL; ASI2_AUTO_ADDRESS, ASI2_AUTO_ADDRESS_POSSIBLE, ASI2_CONFIG_OK: BOOL; ASI2_NORMAL, ASI2_OFFLINE, ASI2_POWER_FAIL: BOOL; ASI2_PROJECTION_MODE, ASI2_SLAVE0_EXIST, ASI2_PERIPHERY_OK: BOOL; ASI2_AUTO_ADDRESS_ENABLE, ASI2_DATA_EXCHANGE_ACTIVE: BOOL; END_VAR < it&gphGlobale'XX;Variablen_Konfiguration> >futi, t VAR_CONFIG END_VAR D_VAR VAR_OUTPUT Q1: BOOL; END_VAR%,BPLC_PRGnA nA PROGRAM PLC_PRG (* ------------------------------------------------------------------------------------------------------------------------------------------------------- *) (* Parameter-Ausleseprogramm fr AS-Interface TS001, 2004 *) (* *) (* Dieses Beispielprogramm dient nur zur Demonstration der Funktion des AM004. Es kann keine Gewhr dafr *) (* bernommen werden, dass dieses Programm in einem realen Automatisierungsprojekt fehlerfrei luft. *) (* ------------------------------------------------------------------------------------------------------------------------------------------------------- *) VAR (* Variablen fr E/As *) DI2 AT %IX1.5.2: BOOL; (* Ein- und Ausgnge fr die serielle Kommunikation *) DI3 AT %IX1.5.3: BOOL; DO0 AT %QX1.5.0: BOOL; DO1 AT %QX1.5.1: BOOL; (* Hilfsvariablen *) Limit1:WORD; Limit2:WORD; Limit3:WORD; Limit4:WORD; Parameter: ARRAY[1..8] OF BYTE:=0,0,0,0,0,0,0,0; TempSens: SerComTS; iw:INT; SW2O: WORD; SW1U: WORD; Product_ID: WORD; Vendor_ID: WORD; Comp: BYTE; Vers: BYTE; END_VAR (* Ende des Deklarationsteils *)Parameter[1]:=INT_TO_BYTE(Limit1/256); Parameter[2]:=INT_TO_BYTE(Limit1-Parameter[1]*256); Parameter[3]:=INT_TO_BYTE(Limit2/256); Parameter[4]:=INT_TO_BYTE(Limit2-Parameter[3]*256); Parameter[5]:=INT_TO_BYTE(Limit3/256); Parameter[6]:=INT_TO_BYTE(Limit3-Parameter[5]*256); Parameter[7]:=INT_TO_BYTE(Limit4/256); Parameter[8]:=INT_TO_BYTE(Limit4-Parameter[7]*256); TempSens(DI2:=DI2, DI3:=DI3, Para_DatIn:=Parameter); DO1:=TempSens.DO1; DO0:=TempSens.DO0; iw:=TempSens.InputWord; Vendor_ID:=TempSens.ID_Data[1]*256+TempSens.ID_Data[2]; Product_ID:=TempSens.ID_Data[3]*256+TempSens.ID_Data[4]; Comp:=TempSens.ID_Data[5]; Vers:=TempSens.ID_Data[6]; SW1U:=TempSens.Para_DatOut[3]*256+TempSens.Para_DatOut[4]; SW2O:=TempSens.Para_DatOut[5]*256+TempSens.Para_DatOut[6]; .,;)SerComTSкnA кnAPR_PFUNCTION_BLOCK SerComTS (* Dieser Funktionsbaustein wickelt die gesamte serielle Kommunikation zu einem AS-Interface Slave nach dem Profil S-7.A.5 ab. *) VAR_INPUT DI2: BOOL; (* Eingnge fr serielle Kommunikation *) DI3: BOOL; Para_DatIn: ARRAY [1..8] OF BYTE :=2,0,7,208,3,232; (* Parameter-Solldaten *) END_VAR VAR_OUTPUT InputWord: INT; (* Eingabe-Datenfeld: Zhlerstand *) Diagnosis: BYTE; (* Diagnose-Daten *) ID_Data: ARRAY [0..15] OF BYTE; (* ID-Daten des Slaves *) Para_DatOut: ARRAY [1..8] OF BYTE; (* Parameter-Istdaten des Slaves *) DO1: BOOL; (* Ausgnge fr serielle Kommunikation *) DO0: BOOL; END_VAR VAR InputD: ARRAY [0..15] OF BYTE; (* Eingabe-Datenfeld *) InputData: ARRAY [0..15] OF BYTE; (* Eingabe-Datenfeld *) OutputData: ARRAY [0..15] OF BYTE; (* Ausgabe-Datenfeld *) OutputLen: BYTE; (* Lnge der Ausgabedaten in Byte; Zahlenbereich 1..15 *) InputL: BYTE; (* Lnge der Eingabedaten in Byte; Zahlenbereich 1..15 *) InputLen: BYTE; Taktalt: BOOL; In: BYTE; (* aktuell empfangene Nachricht *) Inalt: BYTE; (* letzte empfangene Nachricht *) Out: BYTE:= 3; Watchdog: BOOL; Timeout: BYTE; Lastin: BYTE; (* letztes gltiges empfangenes Informationsbit *) i: BYTE; IBitzeiger: BYTE; Outalt: BYTE; Outzeiger: BYTE; OBitzeiger: BYTE; x: BYTE; Send: BOOL; y: BYTE; NewData: BOOL; SSW: WORD; Inst1:TON; Inst2:TON; Takt:BOOL; Var2: BOOL; Acyclic: WORD; Para_Data: ARRAY [0..8] OF BYTE; MerkPara: BOOL; SCSlave: BOOL; Schluss: BOOL; Timeout2: BYTE; ARS0Request: BOOL; ARSResponse_0: BOOL; ARS1Request: BOOL; ARSResponse_1: BOOL; AWS2Request: BOOL; ARSResponse_2: BOOL; AWSResponse_2: BOOL; ARS2Request: BOOL; END_VAR 8(* Hier wird ein Takt mit einer Zykluszeit von 20ms generiert *) Inst1(IN:=Takt, PT:=t#10ms); Var2:=NOT Inst1.Q; Inst2(IN:=Var2, PT:=t#10ms); Takt:=Inst2.Q; (* Eingnge des Slaves lesen, ausmaskieren und auf Vernderung prfen *) IF DI2=FALSE AND DI3=FALSE THEN In:=0; END_IF; IF DI2=FALSE AND DI3=TRUE THEN In:=2; END_IF; IF DI2=TRUE AND DI3=FALSE THEN In:=1; END_IF; IF DI2=TRUE AND DI3=TRUE THEN In:=3; END_IF; IF In<>Inalt THEN (* eine Antwort ist eingetroffen *) IF Out=1 AND In=1 THEN (* die eine der erwarteten Antworten ist eingetroffen: Separator *) Watchdog:=FALSE; SCSlave:=TRUE; Timeout:=0; Lastin:=Inalt; (* Aktion 2: Trenn-Nachricht empfangen; Master sendet Information oder Idle *) IF Send=TRUE THEN IF Outalt=3 THEN (* Ausgabe initialisieren *) Outzeiger:=0; OBitzeiger:=0; y:=OutputData[0]; END_IF; IF Schluss=FALSE THEN Outalt:=Out; x:=y AND 2#1000_0000; IF x<>0 THEN Out:=2; ELSE Out:=0; END_IF; y:=SHL (y,1); OBitzeiger:=OBitzeiger+1; (* ein Byte fertig? Zeiger auf nchstes Byte stellen *) IF OBitzeiger>7 THEN Outzeiger:=Outzeiger+1; y:=OutputData[Outzeiger]; OBitzeiger:=0; IF Outzeiger>=OutputLen OR Outzeiger>=19 THEN Schluss:=TRUE; SCSlave:=TRUE; END_IF; END_IF; ELSE Outalt:=Out; Out:=3; (* zum Abschluss einer Nachricht wird mindestens 1 Idle gesendet! *) Send:=FALSE; Schluss:=FALSE; END_IF; ELSE Outalt:=Out; Out:=3; END_IF; IF Out=0 THEN DO0:=TRUE; DO1:=TRUE; END_IF; IF Out=1 THEN DO0:=FALSE; DO1:=TRUE; END_IF; IF Out=2 THEN DO0:=TRUE; DO1:=FALSE; END_IF; IF Out=3 THEN DO0:=FALSE; DO1:=FALSE; END_IF; ELSIF Out<>1 AND In<>1 THEN (* die andere der erwarteten Antworten ist eingetroffen: Idle oder Daten *) Watchdog:=FALSE; SCSlave:=TRUE; Timeout:=0; IF (In=0 AND Inalt<>2) OR (In=2 AND Inalt<>0) THEN (* Aktion 0/1: Slave hat Informationsbit gesendet: abspeichern; Master sendet Trenn-Nachricht *) IF Lastin=3 THEN (* Beginn einer Nachricht: Zeiger und Feld Initialisieren, wenn Feld bereit *) NewData:=FALSE; InputL:=0; IBitzeiger:=0; FOR i:=0 TO 19 DO InputD[i]:=0; END_FOR; END_IF; InputD[InputL]:=SHL(InputD[InputL],1); IF In=2 THEN InputD[InputL]:=InputD[InputL]+1; END_IF; IBitzeiger:=IBitzeiger+1; IF IBitzeiger>7 THEN InputL:=InputL+1; IF InputL>19 THEN InputL:=19; END_IF; IBitzeiger:=0; END_IF; Outalt:=Out; Out:=1; IF Out=0 THEN DO0:=TRUE; DO1:=TRUE; END_IF; IF Out=1 THEN DO0:=FALSE; DO1:=TRUE; END_IF; IF Out=2 THEN DO0:=TRUE; DO1:=FALSE; END_IF; IF Out=3 THEN DO0:=FALSE; DO1:=FALSE; END_IF; ELSE (* Aktion 3: Slave hat Idle gesendet: Abschluss einer Nachricht?; Master sendet Trenn-Nachricht *) IF Lastin<>3 THEN (* Abschluss einer Nachricht; wenn diese nicht vollstndig (also ganzzahlige Anzahl von Bytes), dann wird sie verworfen! *) IF IBitzeiger =0 THEN FOR i:=0 TO InputL DO InputData[i]:=InputD[i]; END_FOR; NewData:=TRUE; InputLen:=InputL; SCSlave:=TRUE; END_IF; END_IF; Outalt:=Out; Out:=1; IF Out=0 THEN DO0:=TRUE; DO1:=TRUE; END_IF; IF Out=1 THEN DO0:=FALSE; DO1:=TRUE; END_IF; IF Out=2 THEN DO0:=TRUE; DO1:=FALSE; END_IF; IF Out=3 THEN DO0:=FALSE; DO1:=FALSE; END_IF; END_IF; END_IF; ELSIF (Takt<>Taktalt AND Takt=TRUE) THEN (* Slave alle 120ms testen, ob er den seriellen Kommunikationsmodus untersttzt, dient auch zum Anlauf der Kommunikation *) Timeout:=Timeout+1; IF Timeout>4 THEN Outalt:=Out; IF (Out=0 OR Out=3) THEN Out:=1; ELSIF (Out=1 OR Out=2) THEN Out:=3; END_IF; Timeout:=0; SCSlave:=FALSE; SSW:=0; IF Out=0 THEN DO0:=TRUE; DO1:=TRUE; END_IF; IF Out=1 THEN DO0:=FALSE; DO1:=TRUE; END_IF; IF Out=2 THEN DO0:=TRUE; DO1:=FALSE; END_IF; IF Out=3 THEN DO0:=FALSE; DO1:=FALSE; END_IF; END_IF; END_IF; (* und hier luft die bergeordnete Steuerung des seriellen Slaves ab. Zyklus: 16s *) IF Taktalt<>Takt AND Takt=FALSE AND Acyclic<>0 THEN Timeout2:=Timeout2+1; IF Timeout2>151 THEN Timeout2:=0; Acyclic:=0; Diagnosis:=Diagnosis AND 16#EF; END_IF; END_IF; IF SCSlave=FALSE THEN Diagnosis:=Diagnosis OR 16#80; ARS0Request:=FALSE; ARSResponse_0:=FALSE; ARS1Request:=FALSE; ARSResponse_1:=FALSE; AWS2Request:=FALSE; ID_Data[1]:=0; ELSE Diagnosis:=Diagnosis AND 16#7F; END_IF; (* Kommandoaufrufe: ID des Slaves schon bekannt? *) IF ID_Data[1]=0 AND Acyclic=0 AND Send=FALSE AND SCSlave=TRUE THEN (* ID des Slaves abfragen *) OutputData[0]:=16; OutputData[1]:=0; OutputData[2]:=6; OutputLen:=3; Send:=TRUE; ARS0Request:=TRUE; Diagnosis:=Diagnosis OR 16#10; Acyclic:=100; END_IF; (* Zyklisch das Diagnose-Byte abfragen *) IF ARSResponse_0=TRUE AND ARSResponse_1=FALSE AND Acyclic=0 AND Send=FALSE AND SCSlave=TRUE THEN (* Diagnose des Slaves abfragen *) OutputData[0]:=16; OutputData[1]:=1; OutputData[2]:=1; OutputLen:=3; Send:=TRUE; ARS1Request:=TRUE; Diagnosis:=Diagnosis OR 16#10; Acyclic:=101; END_IF; (* Parameter des Slaves schon bekannt? *) IF ARSResponse_2=FALSE AND Acyclic=0 AND Send=FALSE AND SCSlave=TRUE THEN OutputData[0]:=16; OutputData[1]:=2; OutputData[2]:=6; OutputLen:=3; Send:=TRUE; ARS2Request:=TRUE; Acyclic:=102; Diagnosis:=Diagnosis OR 16#10; END_IF; (* Wenn Vernderung, dann Parameter schreiben *) IF ARSResponse_2=TRUE AND SCSlave=TRUE AND Acyclic=0 AND Send=FALSE THEN MerkPara:=FALSE; FOR i:=1 TO 6 DO IF Para_DatIn[i]<>Para_Data[i] THEN MerkPara:=TRUE; END_IF; END_FOR; IF MerkPara=TRUE THEN OutputData[0]:=17; OutputData[1]:=2; OutputData[2]:=6; FOR i:=1 TO 6 DO OutputData[i+2]:=Para_DatIn[i]; END_FOR; OutputLen:=9; AWS2Request:=TRUE; ARSResponse_2:=FALSE; Send:=TRUE; Acyclic:=103; END_IF; END_IF; IF Newdata=TRUE THEN (* ID-Daten sind angekommen *) IF InputData[0]=80 AND Acyclic=100 THEN FOR i:=1 TO 6 DO ID_Data[i]:=InputData[i+1]; END_FOR; NewData:=FALSE; ARSResponse_0:=TRUE; Timeout2:=0; Acyclic:=0; IF ID_Data[1]<>1 OR ID_Data[3]<>4 THEN (* richtiger Slave? *) Diagnosis:=Diagnosis OR 16#40; ELSE Diagnosis:=Diagnosis AND 16#BF; END_IF; Diagnosis:=Diagnosis AND 16#EF; END_IF; (* Diagnosedaten sind angekommen *) IF InputData[0]=80 AND Acyclic=101 THEN InputData[1]:=InputData[1] AND 16#0F; Diagnosis:=Diagnosis AND 16#F0; Diagnosis:=Diagnosis OR InputData[1]; NewData:=FALSE; ARSResponse_1:=TRUE; Acyclic:=0; Diagnosis:=Diagnosis AND 16#EF; END_IF; (* Parameter-Istdaten sind angekommen *) IF InputData[0]=80 AND Acyclic=102 THEN FOR i:=1 TO 7 DO Para_DatOut[i]:=InputData[i]; Para_Data[i]:=InputData[i]; END_FOR; NewData:=FALSE; ARSResponse_2:=TRUE; Timeout2:=0; Diagnosis:=Diagnosis AND 16#EF; Acyclic:=0; END_IF; (* Acknowlede for Parameter Schreiben ist angekommen *) IF InputData[0]=81 AND Acyclic=103 THEN NewData:=FALSE; AWSResponse_2:=TRUE; Timeout2:=0; Acyclic:=0; Diagnosis:=Diagnosis AND 16#EF; END_IF; (* Messdaten sind angekommen *) IF InputData[0]=0 AND SCSlave=TRUE THEN InputWord:=256*InputData[1]+InputData[2]; NewData:=FALSE; END_IF; (* Aufruf nicht ok *) IF InputData[0]=144 OR InputData[0]=145 THEN InputData[1]:=InputData[1] AND 16#0F; Diagnosis:=Diagnosis AND 16#F0; Diagnosis:=Diagnosis OR InputData[1]; NewData:=FALSE; Timeout2:=0; Diagnosis:=Diagnosis AND 16#EF; Acyclic:=0; END_IF; (* irgendein Fehler ist eingetroffen *) IF (InputData[0]=81 OR InputData[0]=0) AND Acyclic=0 THEN NewData:=FALSE; Diagnosis:=Diagnosis AND 16#EF; END_IF; END_IF; Taktalt:=Takt; Inalt:=In; ,Z;W..\..\..\..\Programme\CoDeSysForAutomationAlliance\Library\ecoasi20.lib 3.7.02 15:24:32[..\..\..\..\Programme\CoDeSysForAutomationAlliance\Library\ecoasi21ps.lib 10.10.03 14:10:08STANDARD.LIB 23.10.00 15:20:56IECSFC.LIB 23.10.00 15:20:30akt_IDCode_lesenakt_IOConf_lesenakt_Parameter_lesenakt_Parameter_refreshakt_Parameter_schreibenASiCmd20EAO_8IO Input7_1Light Input_lesen$Ist_Konfigurationsdaten_projektieren LAS_lesen LDS_lesen LPF_lesen LPS_lesenOutput_schreibenOutputP7_lightproj_IDCode_lesenproj_IOConf_lesenproj_Parameter_lesenproj_Parameter_schreibenPt100_4Channel SendReceiveESlave_adressierenGlobale_Variablen address_slaveASiCmd21 Exec_ASI_CmdGet_ASi_Config Get_ASi_InputGet_ASi_OutputGet_current_parameterGet_Global_ListsGet_LASGet_LDSGet_LPFGet_LPSGet_Master_flagsGet_projected_ASi_ConfigGet_projected_parameterGet_Slave_Error_CounterPeripheral_fault Project_allRefresh_current_parameterSet_ASi_OutputSet_current_parameterSet_ModeSet_projected_parameter SetTestMode Slave_activeSlave_detectedSlave_projectedGlobale_VariablenCONCATCTDCTUCTUDDELETEF_TRIGFINDINSERTLEFTLENMIDR_TRIGREPLACERIGHTRSRTCSEMASRTOFTONTPGlobal Variables 0SFCActionControlGlobale_Variablen,XX_ PLC_PRG.TempSens.In PLC_PRG.TempSens.Out  BausteinePLC_PRG%SerComTS. DatentypenVisualisierungenGlobale VariablenGlobale_VariablenVariablen_KonfigurationF