S7 - OP7 óra szinkronizálás

Itt egy rendkívül pitiáner probléma elképesztően bonyolult megoldása olvasható. Csak kitartó, erős idegzetűeknek ajánlom!

Az alap probléma

Gyakorlatilag minden S7-300 és S7-400 CPU-ban van valós idejű óra. Első ránézésre haszontalannak tűnhet ha a PLC nem lát el olyan feladatokat amelyekhez szükség van a pontos időre mint információra (pl. kapcsoló óra jellegű funkciók, események időbélyegzővel történő rögzítése, stb)
Az összetettebb rendszerekben találunk valamilyen operátor panelt, amin elvégezhetők a beállítások, és amin a rendszer üzeneteket jelenít meg.
Az órával kapcsolatos bonyodalmak is itt kezdődnek, hiszen az operátorpanelek is tartalmaznak beépített valós idejű órát. Ez önmagában még nem lenne nagy baj, de az egyszerűbb panelek órája újraindul ha megszűnik, majd visszajön a tápfeszültség.
Ez sem baj, ha nem ragaszkodunk ahhoz, hogy az OP órája szerinti pontos időt megjelenítsük a kijelzőn, hiszen ha nem látja senki az órát, akkor mindegy hogy jól jár-e vagy sem.
Az OP-k alarm és event üzenetmegjelenítő funkcióit azonban ritkán mellőzzük. Ha használjuk ezeket, akkor viszont kézenfekvő, hogy az OP által rögzített üzenetnaplót is megjelenítsük, mert ennek a naplónak a létrehozásával külön nem kell vesződni, az OP beépített alapfunkciói közé tartozik, és egy hiba utólagos kiderítésekor az üzenetnapló átnézése igen sokat tud segíteni. A napló tartalmazza, hogy a hiba (vagy esemény) mikor következett be, a kezelő mikor nyugtázta és a hibaállapot mikor szűnt meg (dátum és idő) továbbá, hogy melyik üzenetről van szó.
Az üzenetnaplóban tehát szerepel a dátum és idő, amit az OP a saját órája alapján jegyez be. Ha egyáltalán nem törődünk azzal, hogy az OP órája mindig a valós időt mutassa, akkor sajnos a hibanaplóban ezek a bejegyzések haszontalanok lesznek, mert visszamenőleg nem, vagy csak nehezen állapítható meg, hogy a bejegyzett 1995. január 8 18:47 mikori időpontot takar a valós időszámítás szerint. Ha ismert tény, hogy az OP mikor indult újra utoljára, akkor kisebb nehézségek árán kiszámolható a valós időpont, mert az OP órája bekapcsolás után 1995, január 01 00:00-tól indul. Ha nem lehet megállapítani hogy mikortól számolandó a naplóba bejegyzett idő, akkor a naplóbejegyzések időpontjának megállapítása sokkal nehezebb, vagy teljesen lehetetlen.


A megoldás

A problémát úgy tudjuk feloldani, hogy valamilyen módon gondoskodunk arról, hogy az OP órája mindig helyesen járjon. Mivel a CPU órája kevésbé amnéziás és tápfeszültség nélkül is ketyeg (kivételt képez néhány compact CPU típus, amiben csak szoftveres óra van) kézenfekvő, hogy az OP óráját szinkronizáljuk a CPU órájához.
Elvileg ezzel a problémát meg is oldottuk. Sajnos gyakorlatilag ezzel a megoldással újabb problémákat hoztunk létre, amiket szintén meg kell oldani.
Ha az OP óráját ciklikusan hozzáállítjuk a CPU órájához, vagy a tápfeszültség bekapcsolásakor egyszer szinkronizálunk, akkor az OP órája pontos lesz ugyan, de mi van akkor, ha a CPU órája viszont rosszul jár. A megoldásunk az OP-ba erőlteti a CPU rosszul járó órabeállítását.
Kell tehát valamilyen megoldás a CPU órájának kézzel történő beállítására. Három lehetőség kínálkozik:
  1. A CPU órájának beállítását programozó eszközzel, vagy egyéb módon kívülről végezzük el
  2. Készítünk az OP-ba egy olyan funkciót, amivel a CPU óráját a kezelő be tudja állítani magán az OP-n
  3. Kihasználjuk az OP-ban gyárilag is meglévő system screen-t, ami az OP órájának beállítását végzi
Azt gondolom, hogy az első megoldás túlságosan nagyvonalú (hacsak nem olyan rendszerről van szó, ahol lehetőség van a CPU óra profibuszon keresztüli automatikus szinkronizálására).
A második megoldás munkaigényes, mert külön screen-t, és változókat kell létrehozni a célra az OP-ban és programot kell írni a funkcióhoz a PLC-ben.
A harmadik megoldáshoz is programozni kell a PLC-t, de nincs szükség külön változókra és OP képernyők készítésére, mert az idő beállítására külön, beépített kész funkció van az OP-ban. Ez a beépített funkció csak az OP óráját állítja, tehát amikor az OP-n órabeállítás történik, az OP óráját be kell írni a CPU órájába.



A képen az látható hogy az F1 gombhoz hogyan rendelhető hozzá a gyári dátum és idő beállító funkció képernyő.
Az OP-ban mást nem is kell tenni az ügy érdekében, csak biztosítani, hogy az óra beállítása a menüből vagy egyéb módon elérhető legyen.

A program

Egy funkció blokk leírása következik, ami megoldást kínál a CPU és az OP7 operátorpanel órájának szinkronizálásához.
A Windows alapú operátorpaneleknél nincs szükség ekkora hercehurcára, azok órája lényegesen egyszerűbben is szinkronizálható.
A régebbi szöveges vagy grafikus panelek esetén (pl. OP7, OP27, OP37) azonban nem találtam jobb megoldást. Az ismertetésre kerülő funkció blokk az OP7-hez lett kifejlesztve. Használható egyéb típusú panelekhez is, de a panelek kisebb eltérései miatt a blokk módosításra szorulhat).

A blokk funkciói:

A PLC JOB-ok

Az OP órájának lekérdezése és beállítása az ún. PLC JOB-ok segítségével történik.
A PLC JOB olyan funkció, aminek a végrehajtását a PLC kérheti az operátorpaneltől.
A JOB végrehajtást a PLC csak akkor tud kérni, ha a ProTool-ban be van állítva az Interface Area nevű areapointer:

 

Az Interface Area egy 16 word méretű adathalmaz. Az OP-ban az Interface Area nevű Areapointer beállításával egy PLC-ben lévő adatterületet határozhatunk meg az adathalmaz számára. Az Interface Area különböző vezérlő és állapot információkat tartalmaz amiket az OP folyamatosan ír és olvas.
Ezekre a következő funkciók kihasználásakor van szükség:
Az Interface Area szerkezete:



Az óra szinkronizálásához használt vezérlő bitek
A vezérlő bitek szinkronizálják az adatátvitelt az operátorpanel és az interface terület között, és tartalmaz néhány speciális funkciójú bitet.
Vezérlő bitek: n+0, n+1, n+3 byte-ok tartalmazzák. Az n+3 byte az adatrekordok átviteléhez szükséges.
n+0 byte:

Bit 5-6

Dátum és idő
41-es PLC job végrehajtásakor (dátum és idő lekérdezése az OP-ról) ezeket a biteket 1 állapotúra állítja, amikor a lekérdezett dátum és idő adat az OP-ból az interface területre megérkezik.
A biteket az OP csak beállítja, törölni (nullázni) az S7 programnak kell, mielőtt még újabb lekérdezést végrehajtana.

n+1 byte:


Bit 0

Startup (rendszerindítás)
Az operátorpanel ezt a bitet 1-be állítja, amikor tápfeszültséget kapott.
Az S7 programnak kell törölnie a bitet, miután az OP rendszerindítást érzékelte.

Bit 1

Működésmód
A bit 1 értékű lesz, ha az operátorpanel offline üzemmódban van és 0 értékű, amikor online módban van.
(offline módban az operátorpanel nem kommunikál a PLC-vel, a normál működésmód az online mód)

Bit 2

Life bit
Az operátorpanel ennek a bitnek a tartalmát másodpercenként ellentétesre állítja. A bit segítségével az S7 programban megállapítható, hogy az operátorpanel üzemel és kommunikál a CPU-val.


JOB mailbox

Ha élni akarok az eredeti név sugallatával, akkor zenés-táncos megfogalmazásban a dolog úgy működik, hogy írunk egy levelet az OP-nak (úgy is olyan messze van, ezért a megfogalmazás különösen találóan hat) és bedobjuk a postaládájába. Az OP észreveszi, hogy levele jött, odaslattyog a postaládához, kiveszi a levelet, szép komótosan elolvassa és végrehajtja amit írtunk neki a levélben.

A "postaláda" szerkezete:


A Job Mailbox segítségével tehát a PLC-ből indított feladatokat lehet végrehajtatni az operátorpanellel. A job-okat számok azonosítják.
A Job mailbox 4 word méretű (8 byte). Az első word a job száma. Ide a PLC írja be a végrehajtani kívánt feladat számát, a következő három word-be pedig a feladathoz tartozó esetleges paramétereket.
Az operátorpanel figyeli a Job mailbox első word-jét (ahol a job száma van). Amikor az nem nulla értékű, elkezdi a feladat végrehajtását, kiolvassa az esetleges paramétereket, stb. Amikor a feladatot végrehajtotta, a job számát az OP visszaírja nulla értékűre.
Az S7 program a job számának figyelésével tudja eldönteni, hogy az operátor panel befejezte-e a kiadott feladat végrehajtását.
Először mindig a feladat paramétereit kell beírni a Job Mailbox-ba, és csak ezután a job számát! Amíg egy job végrehajtás alatt van, nem lehet másikat indítani.

A 14-es job: Set Time
OP órájának beállítása.
Paraméterek:

Paraméter 1

---

óra (0-23)

Paraméter 2

perc (0-59)

másodperc (0-59)

Paraméter 3

---

---

Az értékeket BCD kóddal kell megadni!

15-ös job: Set Date
Az OP órájának dátumbeállítása.
Paraméterek:

Paraméter 1

---

A hét napja (1-7. 1:vasárnap, 2:hétfő, stb)

Paraméter 2

nap (1-31)

hónap (1-12)

Paraméter 3

év

---

Az értékeket BCD kóddal kell megadni!

A 41-es job: Transfer Date/Time to PLC
Kiolvassa az OP órájából a dátumot és az időt. A funkciónak nincs paramétere.
Az OP az óra tartalmát az interface area nevű területmutató megfelelő címeire teszi:
 
n+15 óra
n+16 perc
n+17 másodperc     
n+22 nap
n+23 hónap
n+24 év

Ahol n=az interface terület kezdőcíme

A funkcióblokk működése

Az FB két alapvető részből áll. Az egyik rész az OP óráját állítja be, amikor a START bemenet aktív lesz, a másik rész pedig a CPU óráját állítja be, amikor az OP-n a kezelő elhagyja az óra beállítása (Time/Date) beépített funkcióképernyőt.
Lássuk hogyan írhatjuk át az OP óráját.
A PLC job-ok fenti listájából látható, hogy ezt csak két lépésből tehetjük meg, mert külön job van az óra, perc, másodperc, és külön job az év, hónap, nap beállítására.
Az OP a job-ot viszonylag lassan hajtja végre, ezért nem lehet az óra beállítására egy olyan  programot írni, ami szekvenciálisan lefut egy PLC ciklusban.
Minden job kiadása után meg kell várni, hogy az OP visszajelezze a művelet befejeződését. Ez néhány másodperc időt is igénybe vehet.
A program az egyes részműveletek állapotát jelzők beállításával követi nyomon. Ezeket a jelzőket (FB blokk révén) olyan belső változókban tárolja, amik a blokk lefutásakor sem veszítik el tartalmukat (instance DB). Lásd az "Az S7 PLC programozása" c. részt.

A funkcióblokk változói:


Az OP óra beállításának menetét vázlatosan az alábbi ábra szemlélteti:


A blokk a start bemenetet figyeli. Ha azon felfutó élet érzékel, akkor bekapcsolja az #OSR jelzést, ebből fogja tudni az ezt követő PLC ciklusokban, hogy az OP órájának beállítása folyamatban van.

A következő feltételvizsgálat megállapítja, hogy az OP órabeállítás folyamatban van-e (megvizsgálja #OSR állapotát). Ha nem, akkor tovább ugrik a blokk második részére. Ha folyamatban van, akkor megvizsgálja egy másik (#PLCRTRdy) jelzés vizsgálatával, hogy a PLC órája le lett-e már kérdezve. Ha nem, lekérdezi, ha igen, átugorja a lekérdezést. A PLC óra lekérdezését az SFC1 rendszerhívással végzi. Ha ez a hívás hibával tér vissza, akkor töröl minden folyamatjelzést, és kilép. Ha a PLC óra lekérdezés sikerült, akkor az OP-nak kiadja a 14-es job-ot és bekapcsolja a PLC óra lekérdezve jelzést 
(#PLCRTRdy).
A Job Mailbox vizsgálatával megnézi hogy a 14-es job-ot az OP végrehajtotta-e. Ha még nem, akkor kilép.



Ha igen, akkor egy harmadik jelző (#JOB15) állapotának vizsgálatával megállapítja, hogy a 15-ös job végre lett-e már hajtva. Ha igen, akkor törli a folyamatjelzéseket és kilép, az OP óra beállítása kész.
Ha job 15 még nem lett végrehajtva, akkor az SFC1 által korábban lekérdezett PLC idő dátum adatainak felhasználásával kiadja a 15-ös job-ot az OP-nak és bekapcsolja a job 15 kiadva jelzést (#JOB15).



A CPU óra beállítás menete az alábbi:

A CPU óra OP órához állítása valamivel egyszerűbb, mert csak egy job kiadására van szükség.
A programrész eleje figyeli, hogy az OP kijelzőjén a dátum és idő beállítás van-e megjelenítve. Ha igen, akkor a kép elhagyásakor létrehoz egy impulzust. Ez az impulzus bekapcsolja a #CSR jelzést, ami azt jelzi, hogy a CPU óra beállítása folyamatban van.



Ezután vizsgálja, hogy a #CSR jelzés aktív-e. Ha nem, akkor a folyamatjelzések törlésével kilép. Ha igen, megnézi ki lett-e már adva a job 41 az OP-nak (dátum és idő lekérdezése).
Ha a job 41 még nem lett kiadva, akkor törli az OP dátum és idő lekérdezés állapotát jelző két bitet az interface területen (az n+0 byte 5-ös és 6-os bitje), majd kiadja a 41-es job-ot és bekapcsolja a job 41 kiadását jelző #JOB41 jelzést és kilép.
Ha a job 41 már el lett küldve (a #JOB41 jelzés állapota 1), akkor a Job Mailbox, valamint a dátum és idő lekérdezését jelző két bit segítségével vizsgálja, hogy a job 41-et végrehajtotta-e az OP. Ha még nem, akkor kilép.



Ha a job 41 lefutott, akkor az általa visszakapott dátum és idő adatokat az interface területről belelapátolja a Date_and_time típusú #OPTime változóba és ezt a változó paraméterként megadva meghívja az SFC 0 rendszerhívást, ami beállítja a CPU idejét.
Ha az SFC 0 nem futott le, kilép. Ha lefutott, akkor törli a folyamatjelzéseket és kilép, a művelet kész.



Az FB107 STL forrásprogramja letölthető vagy megtekinthető itt.

A funkció blokk használata

Mivel az óraszinkronizálást végző funkció blokknak (FB107) a job-ok kezelése és az OP-n megjelenített képernyő számának lekérdezése miatt információkra van szüksége, ezeket paraméterként át kell adni neki egy DB blokkban.
A DB blokk szerkezete kötött. Két fontos szabályt kell betartani ezzel kapcsolatban:
A DB 0-ás címén kezdődően kell elhelyezni az OP interface area mutatóját
Az ezt közvetlenül követő 32-es címre kell irányítani az OP "Screen Number" nevű areapointerét Az adatblokk száma és további tartalma közömbös, a példa szerint ez a DB6. Felépítése az alábbi:



A ProTool-ban elvégzendő beállítások:



Miután az OP projectben be van állítva minden területmutató és beletettük az óra állítás lehetőségét is, továbbá a területmutatók területeit elkészítettük a Simatic manager-ben. Jöhet a funkció blokk hívása és a híváshoz szükséges programrészek elkészítése.
Hogy hű legyek a cikk elején tett ígérethez, legyen ez is bonyolult. Persze egyáltalán nem a bonyolultság a cél, hanem a funkcionalitás.

Az OP óra szinkronizálása három esetben történjen meg:
A rendszer elindítása után (bekapcs)
Az OP kommunikáció leállását követő visszacsatlakozáskor
Adott időközönként (a példában 2 óránként) Az első biztosítja, hogy teljes rendszer újrainduláskor (amikor nem csak az OP, hanem a PLC tápfeszültsége is elmegy majd visszatér) is legyen óraszinkronizálás.
A második funkció az OP jelenlétét figyeli. Ha az OP abbahagyja a PLC-vel való kommunikációt, annak egyik (leggyakoribb) oka a tápfeszültségének a megszűnése. Különösen ha a PLC-től távol, más irányból kap betáplálást. Ez a funkció biztosítja, hogy amikor az OP újra feléled, az órája be legyen állítva.
Az utolsó pont biztosítja, hogy bizonyos időközönként rendszeresen akkor is frissüljön az OP órája, ha az első két eset nem következik be.

Az elsőhöz szükség lesz egy "first scan flag" jellegű bitre, ami egy ciklus ideig bekapcsol, amikor a PLC feléled. Ilyet nekünk kell létrehozni, ami nem túl bonyolult.
Hozzunk létre egy OB100-at, egy OB101-et, és egy OB102 blokkot. Ezek a blokkok egyszer lefutnak újraindításkor. Mindegyik más-más esetben:
OB100 - Warm restart
OB101 - Hot restart
OB102 - Cold restart
Mind a három blokkba írjuk be az alábbi három STL utasítást:
SET  
=     M      0.4
BE   
Ez a pár sor bekapcsolja az M0.4 merkert amikor a blokk lefut (vagyis újrainduláskor).
Megjegyzés: Bizonyos CPU típusokba nem tudjuk mindhárom blokkot feltölteni, mert nem mindegyik ismeri mindhárom módot. Ez nem baj, azokat töltsük fel amelyeket enged).
Az OB1 utolsó sora pedig ez legyen:
CLR
=     M      0.4
Minden más utasítást (a "BE" kivételével) a fenti két sor elé írjunk (pl. a blokk hívásokat).
Ez a két sor kikapcsolja az M0.4-es merkert.
Újrainduláskor tehát az M0.4-et bekapcsolja valamelyik restart OB, az OB1 első lefutása után pedig kikapcsolódik és úgy marad.
Természetesen az M0.4 funkciója mostantól az, hogy újrainduláskor ad egy impulzust, így a programban máshol nem változtathatjuk meg az értékét (csak olvasni szabad).

A következő feladat, a bekapcsolás jelzés késleltetése. Az M0.4-el nem indíthatjuk egyből az óra szinkronizálását, mert az OP általában nehezebben ébred mint a PLC, ezért tanácsos egy kis késleltetést tenni bele.




A fenti két network elvégzi a késleltetést és létrehoz egy impulzust M1.1 merkerben, ami rendszer újraindulás után 2 másodperccel következik be.

Most olyan jelet kell alkotni, ami bizonyos időközönként aktiválja az óra szinkronizálását.
Az alábbi két network ezt realizálja:



Már csak az OP kommunikációjának megszűnését és visszatérését kell érzékelni.
Sokat segít ebben az interface területen lévő "Life bit". Ez az interface terület 2. byte-jának (n+1) 2-es bitje.
Az operátorpanel ennek a bitnek a tartalmát kb másodpercenként ellentétesre állítja. Azt kell tehát figyelni, hogy változik-e ez a bit.



A fenti network a life bit felfutó élét figyeli. Az él (P) figyelése azért fontos, mert az OP olyankor is leállhat, amikor a life bit 1 és olyankor is, amikor a life bit értéke éppen 0. Az él (0->1 változás) figyelése lehetővé teszi, hogy a váltakozás leállása detektálható legyen akármelyik állapotban fagy be a bit.
A Life bit minden 0->1 átmenete újraindítja a T49 timert, így a timer nem tud letelni, kimenete ilyenkor állandóan 0 szinten van.
Ha az OP leválik, a life bit befagy, nem keletkezik több 0->1 átmenet rajta, ezért nem lesz ami a T49-et újraindítsa. A T49 le tud telni.
Ha  T49 letelik, a kimenete 1 állapotot vesz fel. A timer kimenetén lévő lefutó élet figyelő (N) nem kapcsolja be M14.6-ot, mivel a timer kimenete 0->1 (felfutó) és nem 1->0 (lefutó) átmenetet produkált.
Amikor a kommunikáció helyreáll, a life bit ismét billegni kezd, a következő felfutó éle újraindítja a timert, minek következtében annak kimenete megint nulla lesz. Ez egy 1->0 átmenetet jelent a T49 kimenetén, így az (N) miatt az M14.6 bekapcsol egy ciklusidőre.

Nincs más hátra, mint meghívni az óra szinkronizálását végző funkció blokkot:



Látható, hogy a start bemenetet az a három fentebb előkészített merker kapcsolja be, amelyik a feladatban rögzített esetekben lesz aktív.
Fontos, hogy az FB minden ciklusban lefusson, ezért az EN bemenete elé ne tegyünk feltételt, legfeljebb indokolt esetben. Ha a blokk hívását átmenetileg kiiktatjuk (az EN inaktív), akkor az FB107 "nem veszi észre" ha az OP-n átállítják az órát, emiatt a CPU óráját nem állítja hozzá a kezelő által beállított OP órához (csak az OP órája áll át). Ha ezután újra aktív lesz az FB107 hívása, akkor a ciklikus szinkronizálás során az OP órája visszaáll a korábbi időre.

Ha a rendszerben több OP7 is van, akkor az FB107-et megfelelően paraméterezve többször is hívhatjuk. A másik OP interface területét másik DB-re állítjuk be a másik FB107 hívás APtrDB paramétereként ezt a másik DB-t adjuk meg.
A bekapcsoláskor és ciklikus szinkronizáláskor aktív merkerek változatlanul felhasználható a másik FB107 hívásnál is, de természetesen az OP leválását érzékelő merkerből egy másikat kell készíteni, ami a másik OP-t figyeli.
Ha nem akarjuk, hogy mindkét OP-ról át lehessen állítani a CPU időt, akkor csak az egyikbe tegyük bele a Time/Date funkciókép meghívását.
Több OP mellett felmerül egy olyan probléma, hogy ha az egyiken kézzel átállítjuk az órát, akkor a másik OP-n csak akkor áll be az új idő, amikor a ciklikus óraszinkronizálás ideje elérkezik. Tehát két órás ciklikus szinkronizálás esetén legrosszabb esetben ez két óra múlva történik meg.


Figyelem!
Ha a PLC-ben használunk "Time of day" megszakításokat, és a fent ismertetett óra szinkronizálás blokk segítségével a CPU idejét úgy módosítják, hogy a módosítás következtében kimarad egy időmegszakítás, akkor az óraállításkor "time error" keletkezik. Emiatt a CPU megpróbálja meghívni az OB 80-as hibakezelő blokkot. Ha nincs OB80, akkor a CPU STOP üzemmódba kerül!
"Time of day" használatakor tehát mindenképpen írnunk kell egy OB80-at a probléma kezelésére, hogy a CPU ne álljon le.

A CPU Time of day interrupt beállítás panele a HW configban


CPU diagnostic  puffer tartalma két "time error" után


Kapcsolódó írások:
Siemens operátorpanelek programozása
Az S7 PLC programozása


Szirty