Timer "anomália"

Ismert és megszokott tény, hogy a PLC miközben a programciklusokat rója egymás után, a fizikai bemenetek külvilág által beállított állapotát a ciklus elején olvassa be a kimenetek program által beállított állapotát pedig a ciklus végén írja ki a fizikai kimenetekre.

Bármilyen hosszúra nyúlik is egy ciklus, és bármilyen rövid ideig is változik meg egy bemenet állapota, a PLC egy mintát vesz az állapotból, a program pedig ezt az állapotot látja egészen a ciklus végéig, ahol újabb mintavétel történik.
Mindennek az az oka, hogy ha egy bemenet a programban több helyen szerepel feltételként (ez majdnem mindig így van) akkor ha a PLC ciklus végrehajtása közben megváltozik a bemenet állapota, a programciklus hátralévő része ne viselkedjen a megváltozott bemenet állapotának megfelelően.
Az ilyesmi ugyanis komoly hibákat eredményezhet. Mivel a programciklusok végrehajtása és a bemenetek állapotainak megváltozása egymástól teljesen függetlenül, aszinkron módon zajlik, az ilyen működés miatt bekövetkező hibák is teljesen véletlenszerűen jelentkeznének.
A program tehát a ciklus futása alatt nem a bemenet tényleges állapotát látja, hanem egy ciklus eleji „befagyasztott” állapotot, ezzel nekünk nem kell törődni. A PLC alacsony szintű rendszerprogramja a háttérben gondoskodik erről.
Van azonban olyan speciális eset, amikor mégis gazdagon beletenyerelhetünk pontosan ugyanebbe a problémába, de nem a bemenetekkel, hanem a timerekkel kapcsolatban.
Erről szól ez az írás.

Az S7-300-ban az időzítőket (timer) a PLC rendszerprogramja kezeli. A PLC programban nekünk csak el kell indítani az időtagot, az majd „szól” ha letelik, vagyis a timer állapota „érintkezője” megváltozik.
De mi a garancia arra, hogy a timer éppen a PLC ciklus végén fog letelni?
SEMMI! Ez legtöbbször semmilyen problémát nem jelent, ha az időzítőt úgy használjuk, hogy több PLC cikluson keresztül is aktív marad. Ilyenkor a timer letelve mondjuk bekapcsol (on delay timer) és hosszabb ideig bekapcsolva marad, amíg az indító feltétele aktív. Ilyenkor teljesen mindegy, hogy az idő a ciklus végrehajtásának a közepén, elején vagy bárhol máshol telt le, a teljes PLC program értesülni fog róla, mert ciklusok sokaságán keresztül lesz aktív.
Más szóval ilyenkor garantált legalább egy olyan PLC ciklus, amely alatt az elejétől a végéig az időzítő aktív volt. Sejthető, hogy a dolog akkor lesz érdekes, ha nincs ilyen garancia!

Lássunk erre egy példát.
Tegyük fel, hogy van egy bekapcsolás késleltető időtagunk (S_ODT) amelyik valamilyen feltétel teljesülésekor elkezd letelni. Amikor letelt, akkor a programnak végre kell hajtani néhány műveletet, majd az időtag feltételét meg kell szüntetnie.

Pl. a gép egyik állapotból a másikba kell hogy lépjen az idő leteltekor, ezért a timerrel bekapcsolunk egy bitet (SET) ami feltétele a következő lépés végrehajtásának, majd valahol máshol a programban bekapcsolunk egy másik jelző bitet (szintén a timer aktív feltételéhez kötve), ami jelzi majd, hogy a művelet elvégzése megkezdődött, máshol számláljuk a timer letelését, majd töröljük a timer előtti feltételt, amitől a timer inaktív lesz.
Így bármikor az előtte lévő egyéb feltételek újra tudják indítani, hogy a folyamat megismétlődhessen.


Az ábrán tátható vázlattal próbáltam szemléltetni a leírtakat.
A network-ök közötti hullámos nyilak azt jelentik, hogy ott más programrészek vannak, az ábrázolt sorok tehát nem közvetlenül követik egymást.
Közvetlenül is követhetnék egymást, akkor a tárgyalt probléma ritkábban jelentkezne, mert a T1 feltétel lekérdezései között kevesebb idő telne el. A példa szemlétességének kedvéért tételezzük fel, hogy az ábrázolt sorok egy viszonylag nagy program különböző pontjain vannak (akár más-más program blokkokban) de ebben a sorrendben kerülnek végrehajtásra.

Az „A” network-ben tehát elindul a timer. Amikor letelik, a T1 aktív lesz, és azt gondolhatnánk, hogy ennek hatására a „B”, „C” és „D” network-ben lévő feladatok aktiválódnak, majd a timer letelését követő PLC ciklusban (amikor a ciklus kezdetekor a T1 már aktív) T1 törli saját indító feltételét (az M11.1-et), ezért inaktívvá válik. A T1 tehát csak egy impulzust ad.

Azt gondolhatnánk, hogy ennek az impulzusnak a hossza egy PLC ciklus, de nem így van!
A T1, miközben a programvégrehajtás zajlik, önállóan (attól függetlenül telik, hogy a program végrehajtása éppen hol tart).
Ennek következtében a T1 bármikor letelhet, akár a PLC ciklus közepén, elején vagy a végén is. Bárhol, ráadásul ez nem mindig ugyanott lesz!

Ha a „B” és a „C” network végrehajtása alatt még nem volt letelve a timer, de mire a „D” network-höz ér már letelik, akkor  „D”-ben lévő számláló számolni fog egyet, ám a „feladat 1” nem fog aktiválódni és a „folyamatjelző bekapcsolása” sem történik meg!
A timer tehát nem úgy viselkedik mint a bemenetek, nem lesz mindig teljes cikluson be vagy kikapcsolva. Ezért a program futása során teljesen véletlenszerű, hogy melyik network végrehajtásakor aktiválódik.

Az alábbi példaprogram bizonyítja a dolgot.






A példa az FC18-as program blokkot használja arra, hogy növelje a ciklus időt. Ez a blokk semmi lényeges dolgot nem csinál, csak végrehajt egy a „Ciklus” paraméterében megadott számú számolási műveletet. Ez a blokk helyettesíti a CPU egy nagyobb program különböző részeivel eltöltött idejét.
 
A példaprogram úgy működik, hogy I0.0 bement bekapcsolja M11.1 merker bitet. Amikor ez a bit TRUE, elindul T1 bekapcsolás késleltető (on delay) időtag. 1.2 másodperccel később T1 letelik és törli M11.1 bitet, mire visszaáll az alaphelyzet, a program várja I0.0 bemenet jelét.
A program többi részében különböző helyeken T1 bekapcsol különböző merker biteket (M10.0, M10.2, M10.4, M10.6). Ezek között meghívásra kerül az időtöltő FC18.
A program végén számlálók vannak elhelyezve. Ezek MW100, MW102, MW104 és MW106 merker wörd-oket növelik egyesével, amikor  M10.0, M10.2, M10.4, M10.6 bitek TRUE állapotba kerülnek.

Ha az a „probléma” ami miatt most ezt a cikket írom nem is létezne, akkor a program futásakor az I0.0 bemenet több mint 1.2 másodperc leteltével többször aktiválva minden számláló ugyanannyit mutatna, bármennyiszer is kapcsol be a bemenet.
Ám ha kipróbáljuk a programot (akár a PLCSIM segítségével) azt tapasztaljuk, hogy a programban hamarabb végrehajtásra kerülő számlálók kevesebbet számolnak mint a később végrehajtásra kerülők.


A képen egy VAT táblában látható a 4 számláló értéke 34 I0.0 aktiválás után.

A jelenség tetten érésének rendkívül kritikus körülménye a PLC ciklus ideje. Ha a PLCSIM-mel próbáljuk ki, akkor kritikus a számítógépünk sebessége és így a várakoztató FC18-ban eltöltött idő (vagyis az annak megadott ciklus szám értéke).
Ha a PLC ciklus ideje túl nagy, vagy túl kicsi, akkor a jelenséget nehezen (csak nagyon sok ciklus elteltével) lehet reprodukálni.
Persze ez is bőven elég ahhoz, hogy egy élesben működő programban kapjunk egy naponta egyszer-kétszer előforduló hibát, amit nagyon nehéz felderíteni.



A próba során a PLCSIM ciklus ideje 446 ms volt. Ez az idő gyorsabb PC-n a fenti FC18 paraméterekkel rövidebb is lehet.

Hogyan kerülhető el a probléma?

Ha nem közvetlenül a T1-et használja a program a feladatok végrehajtására, hanem egy közbenső változót, a probléma elkerülhető.
Ha az 1-es network-ben a T1 timerrel egy M11.2 merker bitet kapcsolunk ki és be, majd a program minden további részénél T1 helyett M11.2-re hivatkozunk, és az M11.1-et is ezzel töröljük, akkor mindig minden feladat elvégzésre kerül T1 letelésekor.



Miért?
Mert M11.2 egy teljes PLC cikluson át aktív lesz. T1 bármikor letelik, amikor a végrehajtás "A" pontba ér, M11.2-t T1 bekapcsolja, TRUE lesz. Lefut gey ciklus és M11.2 akkor lesz ismét FALSE, amikor a végrehajtás ugyanarra a pontba, vagyis "A" pontba ér.


Mivel így M11.2 mindenképpen aktív lesz egy teljes cikluson át, a program minden pontja értesül a T1 leteléséről és végrehajtja amit M11.2 feltételhez kötöttünk.



Szirty