FUNCTION_BLOCK "ctd_example" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR secTimer {InstructionName := 'TON_TIME'; LibVersion := '1.0'; S7_SetPoint := 'False'} : TON_TIME; secTimerQ { S7_SetPoint := 'True'} : Bool; secTact : Bool; secTimerET : Time; testCounter {InstructionName := 'CTD_USINT'; LibVersion := '1.0'; S7_SetPoint := 'False'} : CTD_USINT; END_VAR VAR RETAIN testCounterInt { S7_SetPoint := 'True'} : Int; END_VAR VAR testCounterQ : Bool; chart : Char; init : Bool; END_VAR VAR_TEMP tempInt : Int; END_VAR BEGIN // https://www.lamaPLC.com // author: Sandor Vamos // 12.05.2023, with TIA 16 tested // Category: freeware // // timer set "secTimerQ" in every second #secTimer(IN:=NOT(#secTimerQ), PT:=t#1s, ET=>#secTimerET); #secTimerQ := #secTimer.Q; // secTact change state every second IF #secTimerQ THEN #secTact := NOT (#secTact); END_IF; // testCounter count down every 2 second (its works with positive edge // Q will "true" at 0 // CV cannot be less than 0 because it is an unsigned SINT counter (CTD_USINT) #testCounter(CD:=#secTact, LD:=NOT(#init), PV:=100, Q=>#testCounterQ, CV=>#testCounterInt); #init := TRUE; // actual state from testCounter #tempInt := #testCounterInt; END_FUNCTION_BLOCK