Adatkezelés

Utolsó módosítás: 2012.09.05
Automatizálási rendszerekben gyakori, hogy adatokat kell eltárolni bizonyos időközönként vagy adott esemény bekövetkezésekor.
Főleg méréseket is végző rendszerekben fordul elő ilyen igény, de "hagyományos" vezérléseknél is szükség lehet bizonyos állapot bitek tárolására pl. egy hiba bekövetkezésének pillanatában, ami segítheti a hibakeresést.
Nem évekre visszakereshető hosszú log listákra vagy táblázatokra gondolok. Arra is lehet igény, de az olyan feladatot inkább a HMI-re vagy SCADA-ra bízzák.
A PLC-ben (DB blokkban) tárolt néhány száz bejegyzést tartalmazó adathalmazról van szó, amit vagy HMI-n lehet visszanézni vagy maga a program dolgozza fel a tárolt adatokat valamilyen célból (pl. átlag kiszámítása).
Bemutatok néhány példát ennek a megvalósítására.

Példa

Az adatokat táblázatként képzeljük el, aminek minden sora egy-egy adat, vagy rekord (ami több, különböző adatot jelent)  és minden oszlopa egy mező a rekordból.
Az első példában olyan táblázatunk van, aminek minden sorában csak egyetlen integer típusú adat van.
Amikor új adat érkezik, az mindig a táblázat első sorába íródik be, miután a táblázat minden sora egyel lejjebb lépett. Így a tábla mindig tartalmazza a legutolsó annyi adatot, ahány elemű táblázatot használunk a tárolásra.
A megvalósításnak sokféle módszere van. Olyat fogok bemutatni, amit könnyű programozni (és a működését megérteni), de cserébe elég erőforrás igényes, mert minden érkező új adat beírása előtt a táblázat majdnem teljes tartalmát kétszer is át kell másolni és szükség van egy a táblázattal majdnem megegyező méretű átmeneti memóriaterületre is (lásd később a részletes magyarázatnál).

A módszer tehát az, hogy, amikor új adat érkezik, a táblázat mérete -1 sor mennyiségű adatot átmásolunk magába a táblázatba, de a második sortól kezdődően, majd az új adatot beírjuk a tábla első sorába:



Több adat másolását, vagyis a táblázat -1 sor mennyiségű adatot az SFC20 (Copying Memory Area with SFC 20 "BLKMOV") rendszerhívással tudjuk megvalósítani. Így megmenekülünk attól, hogy ciklust kelljen szervezni és pointerekkel kelljen bajlódni a táblázat sorainak másolására.
Sajnos az SFC20 nem engedi meg, hogy a másolás forrását és célját képező adatterületek átfedésben legyen egymással (márpedig itt éppen erről van szó), szükséges egy táblázat -1 sor méretű átmeneti adatterület is, továbbá emiatt egy másolás helyett két másolásra van szükség.

A táblázatot tehát az utolsó sor kivételével átmásoljuk egy átmeneti táblázatba, aminek a mérete egy sorral kisebb.
Ezután az átmeneti táblázatunk teljes tartalmát bemásoljuk az eredeti táblázat második sorától kezdődően (vagyis egy sorral lejjebb, mint ahonnan kimásoltuk).
Ezt követően beírjuk az új adatot a táblázat első sorába:



A fenti ábra szerinti 6 elemű táblázat 6 eleme mindig az utolsó 6 legutóbb beírt adatot tartalmazza időrendben. Amikor új adat jön, a legrégebbi elvész.
Lássuk hogyan valósítható ez meg létradiagramban S7-300/400 PLC-vel:

Először is szükség lesz egy hat elemű táblázatra, amit a DB20-ban hoztam létre egy 6 elemű integer tömb segítségével.
A DB20 deklarációs és adat nézete a tömbdefiníció miatt eltérő.

Deklarációs nézet:


Adat nézet:


Természetesen egyenként is fel lehetne venni a DB-be a táblázat hat sorát, akkor az adat nézet és a deklarációs nézet szerkezetében megegyezne. Ezt 6 sornál könnyen megtehetjük, de 100 sornál már elég nagy favágás. Tömb deklarációval akárhány soros a táblázatunk, a deklaráció akkor is csak két sor. A működés szempontjából mindegy hogyan deklaráltuk a táblázatot, az a lényeg, hogy annyi és olyan típusú adat legyen benne amilyen és amennyi kell.

A program:





Amikor I0.0 bemenet bekapcsol, a DB20-ban lévő 6 elemű táblázatunkba beíródik az, ami éppen akkor MW10 merker wordben van.
A -(P)- utasításra az I0.0 után azért van szükség, hogy a művelet csak egyszer kerüljön végrehajtásra, amikor az I0.0. 0->1 átmenete megtörténik (bekapcsolás, vagyis felfutó él). Anélkül a táblázat léptetése és az érték beírása minden PLC ciklusban (néhány milliszekundumonként) mindaddig megtörténne, ameddig az I0.0 bemenet be van kapcsolva.

Az SFC20 forrás blokk (SRCBLK) és cél blokk (DSTBLK) paramétere érdemel némi magyarázatot. Különösen akkor, ha valaki nem tudja mi az a P#... kezdetű dolog ott.
Nos a BLKMOV ANY típusú paramétert igényel. Ilyen ANY típussal kell neki elmagyarázni hogy mit, honnan és mennyit, hova másoljon. Ez univerzálissá teszi, mert képes biteket, byte-okat, word-öket, stb másolni merker, in, out és DB területről (illetve oda) is. Az univerzális lehetőségek ára az ANY pointer. Az ANY-ról részletesebben az "az ANY paramétertípus" és a "az ANY használata" írásokban lehet olvasni.
Itt csak arra térnék ki, hogy paraméterként megadható egy változó vagy tömb szimbolikus neve is. Ez történik amikor a #TMP paramétert kapja az SFC20. Ilyenkor a szimbólum mögött rejlő minden adatra vonatkozik a paraméter, tehát a #TMP szimbolikus név által takart teljes tömb változóra, minden elemével együtt (ami jelen esetben 5 darab integer változó). Így ha egy tömb vagy egyéb struktúra teljes tartalmát akarjuk másolni BLKMOV-val, akkor elég megadni annak szimbolikus nevét (akkor is, ha DB-ben van).
A mi esetünkben ez csak az átmeneti tárat realizáló #TMP változónál valósul meg, hiszen a DB-ben lévő hat soros táblának először csak az első öt sorát másoljuk (tehát nem a teljes tömböt), másodszor pedig az utolsó 5 eleme a másolás célja. Így kénytelenek vagyunk a pointer formátummal leírni az adatterületet.

A hivatkozott írások alapján tehát: P#DB20.DBX 0.0 INT 5 azt jelenti, hogy másoljon a DB20 adatblokk 0. címétől kezdődően 5 integert #TMP-be. Ez a DB-beli táblázatunk első 5 sora.
P#DB20.DBX 2.0 INT 5 jelentése pedig, hogy a forrás #TMP, a cél pedig DB20 adatblokk 2-es címétől kezdődően 5 integer. Tehát a DB-beli táblánk utolsó 5 sora.
Honnan tudjuk, hogy a táblázat második sorának kezdőcíme 2? A DB20 adat nézetének Address oszlopából kiderül. De kiszámolni sem nehéz, a második integer a 2-es címen van (egy integer 2 byte hosszú).

Egy rövid videón megtekinthető hogyan működik a fenti megoldás. (Adattabla1.avi)


Az eredeti "tervek" szerint több példát is szerettem volna írni, pl. amikor nem csak egy integer alkot egy adatsort, hanem egyéb adatok társulnak hozzá (pl. a bejegyzés időpontja), de az időm is, meg az ihlet is elment az írás közben. :) Semmit nem ígérek, de ha mindkettő jókor jó helyen (és egyszerre) lesz adott, további részekkel bővítem a témát...

Kapcsolódó írások:
Impulzusok előállítása
Az ANY paramétertípus
Az ANY használata



Szirty