Több kimenet (coil) jellegű utasítás egy programban


Sok váratlan problémát okozhat, ha egy programon belül véletlenül több különböző helyen is módosítjuk egy bit állapotát (write). Más szóval ha egy kimenetet többször is felhasználunk.
Haszna is lehet az ilyesminek, ha körültekintően használjuk.
Először is, ott az S (Set) és R (Reset) utasítás. Jellegéből adódóan ezt a két utasítást párban használjuk egy programban.
Az S (Set) bekapcsolja a hivatkozott bitet, ha az előtte lévő feltétel teljesül, de változatlanul hagyja, ha nem teljesül.
Az R (Reset) törli (kikapcsolja) a bitet, ha az előtte lévő feltétel teljesül, és nem változtatja meg, ha nem.



Ha az S és R utasítást így használjuk, akkor a program különböző helyeire is tehetjük ugyanannak az bitnek a be és kikapcsolását és egy-egy bitet különböző helyeken különböző feltételekkel is ki vagy be kapcsolhatunk. Vagyis tehetünk ugyanarra a bitre több S vagy R utasítást, amiket más-más feltétel aktivál.
Az ilyen megoldás használható az ellenség megtévesztésére is. :) Szándékosan áttekinthetetlenné és nehezebben érthetővé tehetünk vele egy programot. Egyéb apró praktikával ezt még fokozni lehet, de ilyesmit nem mutatok be. Az én filozófiám szerint egy PLC program legyen mások számára is érthető. használjuk ki a rendszer adta lehetőségeket, de csak annyira amennyire az szükséges.

Növeli az áttekinthetőséget, ha az RS vagy SR utasítást használuk létrában vagy FBD-ben:



A működése azonos a külön írt formával, de itt egy helyen van a Set és  a Reset utasítás, nem kell külön megkeresni a párját pl. hibakeresés során. Ha egy bitet különböző feltételekkel akarunk be vagy kikapcsolni, ilyenkor minden feltételt az SR (RS) flipflop bemenete elé kell írni.
Lényegében már ez is kimeríti a "coil duplication" fogalmát, mivel ugyanazt a bitet a programban több helyen is írjuk.
Amikor a Set és Reset ág előtti feltétel is teljesül, a hivatkozott bit a ciklus végén abban az állapotban lesz, amelyikbe sorrendben az utolsó utasítás billentette.

De címbeli történet nem is igazán erről szól, hiszen az RS tároló használatában mindig van szándékosság és remélhetőleg a működésével is tisztában van aki alkalmazza.
A problémákat az szüli, ha véletlenül használjuk fel többször ugyanazt a kimenetet vagy merkert olyan utasításban, ami megváltoztatja annak állapotát (írja).
 Egyszerű példa erre az, amikor egy kimenetet töbször is beleteszünk egy programba pl. így:



Ha ez a két network a programban egymás után van, akkor hamar feltűnik hogy kettő van egy kimenetből, de ha egymástól távoli helyen, más blokkban, akkor a dupla kimenet ténye nem derül ki olyan könnyen. Rögtön az első próbánál kiderül viszont, hogy valami itt bizony nincs rendben. A program nem úgy működik, ahogy azt várjuk.
Ilyenkor fordul elő, hogy ha hibakereséskor monitorozzuk a programot, akkor azt lehet látni, hogy a kérdéses kimenet bekapcsolt állapotban van, de a PLC fizikai kimenete inaktív, a kimeneti modul LED-je nem világít. Esetleg fordítva, a kimenetet az adott helyen inaktívnak látjuk, fizikailag mégis be van kapcsolva.
Ha egy ilyen problémát okozó bit állapotát a program felhasználja egyéb feltételek vizsgálatakor (ÉS, ill. VAGY kapcsolatokban, tehát mintha egy kimeneti "tekercs" "érintkezője" lenne) a két, egymással ellentétes logikai eredményt beleíró (duplikált) sor között a kérdéses bit az előtte lefutó írási művelet eredményét fogja tartalmazni.
Példa:


A fenti példa szerint tehát a Q4.0 kimenet fizikailag az I1.2 állapotával azonos lesz, attól teljesen függetlenül, hogy az I1.0 és az
I1.1 milyen állapotban van. A Q8.0 kimenet mégis az I1.0 állapotát, a Q8.1 pedig az I1.1 állapotát fogja felvenni.
Mindez azt bizonyítja, hogy a Q4.0 a cikluson belül úgy billeg, ahogy azt a programban billegtetjük, de a fizikai kimenet csak a ciklus végén
veszi fel azt az állapotot ami a Q4.0 programon belüli állapota.
Ugyanakkor azt is bizonyítja, hogy a PLC a kimenetek állapotát csak a ciklusok végén frissíti ezért a fizikai kimenet a programban billegtetett bit értékét csak a ciklus végén veszi fel és a következő ciklus végéig úgy is marad.

Amikor tehát olyan hibát látunk, hogy a kimenet nem úgy kapcsol, ahogy azt a monitorozott program mutatja, akkor a kimenetei modul cseréje előtt gyanakodjunk arra, hogy a kimenetet a program valahol máshol is írja. Annak megállapításában, hogy ez valóban így van-e, segít a kereszt referencia vagy a go to location ablak.
Kattintsunk jobb gombbal az adott kimenetre a szerkesztőben és a felbukkanó menüből válasszuk a Go to, majd a  location pontot:



Egy ablak fog megjelenni, amiben fel van sorolva a programban az összes előfordulása annak az elemnek, amire kattintottunk:



A type mező mutatja hogy az adott helyen írási vagy olvasási műveletben vesz-e részt. Ha ott egynél több "W" betű látható, és nem Set vagy Reset utasításról van szó, akkor  érdemes megnézni, hogy a program mikor és hol írja azt a kimeneti bitet. A példában az látható, hogy a Q4.0 kimenetet a program 3 helyen írja. Ez a 3 utasítás két különböző blokkban van (FC2-ben és FC3-ban)

Sajnos pár dolog bonyolítja a helyzetet.
1,
Nem biztos hogy az adott bit írása minden PLC ciklusban megtörténik. Pl. ha egy másik program blokk (FB, FC vagy OB) is írja, lehet hogy annak hívása valamilyen feltételhez kötött és a feltétel csak bizonyos esetekben teljesül, így az írási művelet is csak ekkor fut le. Vagy ha az írás helyén pl. feltételes ugró utasítással azt az utasítást átugorja amelyik az írást elvégzi, akkor szintén nem feltétlenül írja minden ciklusban. Ilyenkor, ha a kimenet véletlenül van duplikálva (pl. elírás miatt) akkor rendszerint olyan hibajelenséget kapunk, ami csak néha jelentkezik.

2,
A Go To Location funkció alapja a keresztreferencia tábla. A keresztreferencia táblát felépítő funkció pedig nem veszi figyelembe hogy egy blokk egyáltalán lefut-e majd vagy nem. Minden blokkot feldolgoz. Így azokat is, amelyeket nem hív meg más blokk soha. Ha egy ilyen nem használt blokkban van olyan utasítás ami miatt duplán lesz írva egy kimenet, az a Go to location ablakban látható lesz. Ott tehát azt fogjuk látni hogy egy kimenetet több helyen is ír a program, valójában azonban nem, mert az egyik nem fut le soha.

3.
Egy kimenetet vagy merkert nem csak bitenként out utasítással (=) lehet írni, hanem byte-onként, word-önként, double word-önként is!
Ezért ha pl. amikor az M6.2 merkert használja egy network:

Azt a bitet a program más részén úgy is felülírhatjuk, hogy adatot írunk az alábbiak valamelyikébe:
MB6 byte-ba, MW5 vagy MW6 word-be, MD3, MD4, MD5, vagy MD6 double word-be.
A Go to location ablakban alap esetben csak azonos címzésmóddal kezelt címek jelennek meg, ezért ha az M6.2-ről kérjük a go to location funkciót, a kapott listából nem fog kiderülni ha a programban valahol van egy MOVE utasítás, aminek a kimenete az MW6:

Az M6.2 az MW6-os word 10-es bitje, amit a fenti MOVE utasítás törölni fog!

Ha azonban a go to location  ablakban bekapcsoljuk az Overlapping access to memory areas opciót, a Step7 kijelzi a találatok között azoknak az utasításoknak a helyét is, amelyek operandusa átfedésben van az általunk keresett címmel:



A fenti képen látható, hogy bár az M6.2-es bitet kerestük, az opció bekapcsolása után kiderült, hogy az MW6-ot (ami az M6.2-es bitet is magában foglalja) az FC1 2-es networkjében egy T (store) utasítás írja.
4,
Ha a programban indirekt címzést is használunk, a kereszt referencia és a Go to location nem biztos hogy megtalálja azt az utasítást ami óvatlanul felülír valamit, amit nem kéne.
Néhány példa:
=     M [AR2,P#0.6]

=      [AR2,P#0.0]

T     MW [MD     4]
Az indirekt címzés lényege, hogy nem egy olyan memóriahelyhez férünk hozzá aminek acímét a program írásakor előre fixen megadjuk (direct címzés) hanem a program maga számítja ki valamiből, többnyire változók értékéből.
Ezért csak a program futásakor derül majd ki, hogy az indirekt címzés pontosan mit is fog címezni.
Hogy a fenti sorok melyik merker bitet vagy word-öt fogják felülírni az attól függ, hogy végrehajtáskor mi van az AR2 address regiszterben illetve az MD4-ben.

A keresztreferencia táblát is használhatjuk a felülírásgyanús részek kereséséhez:



Egyes biteket persze nem csak MOVE utasítással lehet felülírni, hanem bármivel, aminek byte, word, stb kimenete van és oda címezzük, ahova nem kéne.
Nem csak kimenetet, hanem belső változókat, időtagokat, számlálókat is duplikálhatunk véletlenül.
Hogy ez milyen következményekkel jár, az sokmindentől függ.
Véletlenül (pl. elgépeléssel keletkezett) kimenet duplikáláskor többnyire olyan hibajelenséggel találkozhatunk, ahol a hiba jellege nem utal a hiba helyére. Az ilyen hiba gyors megtaláláshoz egy kis szerencsére is szükségünk lesz :)
Plusz munkával könnyen elkerülhető az ilyen hiba. vezessünk pontos nyilvántartást arról, hogy melyik bitet, byte-ot stb mire használunk fel és kommentezzünk mindent. A Step7 messzemenőkig támogatja ezt. Mindig írjuk be a szimbólum táblába ha felhasználunk egy memória címet! Az adatblokkok minden elemnéhez írjunk megjegyzést!

Megjegyzés:
Ha a program írása közben használjuk a Go to location funkciót vagy a kereszt refrenciát, akkor a szerkesztett blokkot előbb mentsük ki (bezárni nem szükséges) mert a keresztreferenciába a szerkesztéskor megváltozott blokk hivatkozásai csak ekkor kerülnek bele!

Szirty