A 10. fejezet („Változók, adattípusok és POU-k") gyakorlatainak részletes megoldásai és a tudáspróba megoldókulcsa. Előbb dolgozd ki magad, csak utána ellenőrizz!
Gyakorlatok — megoldások
10.1. feladat — Válaszd ki a hatókört
Megoldás
| # | Adat | Deklaráció | Típus | Indoklás |
|---|---|---|---|---|
| a | szalagsebesség, csak egy POU használja | VAR (lokális) |
REAL |
ami egy POU-n belül marad, maradjon lokális — így nem lehet máshonnan véletlenül elrontani |
| b | üzemmód, három POU olvassa | VAR_GLOBAL |
BOOL (vagy felsorolás) |
valóban közös adat; ez a globális változó indokolt esete |
| c | skálázó függvény nyersértéke | VAR_INPUT |
INT |
a függvény kívülről kapja, és nem módosítja |
| d | összes legyártott darab a gép élettartama alatt | VAR RETAIN (vagy VAR PERSISTENT) |
UDINT |
tápkimaradást is túl kell élnie; ha az új letöltést is, akkor PERSISTENT |
| e | megengedett legnagyobb hőmérséklet | VAR CONSTANT |
REAL |
soha nem változik — a konstans megvédi a véletlen felülírástól |
⚠ Gyakori hiba: mindent globálisnak felvenni, „mert úgy egyszerűbb”. Nagyobb programban ez teszi megtalálhatatlanná a hibát: ha bárhonnan írható a változó, akkor bárhol lehet a hiba.
10.2. feladat — Válaszd ki a POU-típust
Megoldás
| # | Feladat | POU-típus | Indoklás |
|---|---|---|---|
| a | 4–20 mA átváltása mérnöki egységre | FUNCTION |
tiszta számítás, nincs mit megjegyezni |
| b | szalag teljes logikája, háromszor ugyanaz | FUNCTION_BLOCK |
példányosítható: egy kód, három példány, három állapot |
| c | a fő program, a ciklikus task hívja | PROGRAM |
állapotos, de nem kell belőle több példány |
| d | két szám közül a nagyobb | FUNCTION |
állapotmentes, egyetlen visszatérési érték |
| e | adagolószelep állapotgépe | FUNCTION_BLOCK |
emlékeznie kell az aktuális lépésre |
A kérdés mindig ugyanaz: kell-e emlékeznie? Ha igen, funkcióblokk. Ha ráadásul több példány kell belőle, akkor különösen.
10.3. feladat — Találd meg a hibát
Megoldás
A hiba: egyetlen TON példány (tmr) szolgál ki két jelet. A funkcióblokk-példánynak
saját memóriája van — a második hívás felülírja az elsőt, mielőtt a bKeslelt1 értéke
értelmes lenne. A tmr.Q mindkét sorban ugyanannak az egyetlen időzítőnek az állapotát
adja vissza, ráadásul a PT is minden ciklusban felváltva 3 és 5 másodpercre vált.
Javítás: példányonként egy időzítő.
VAR tmr1 : TON; tmr2 : TON; END_VAR tmr1(IN := bJel1, PT := T#3S); bKeslelt1 := tmr1.Q; tmr2(IN := bJel2, PT := T#5S); bKeslelt2 := tmr2.Q;
⚠ Gyakori hiba: ugyanez a hiba élfigyelőnél (R_TRIG) még alattomosabb, mert ott a
tünet csak néha jelentkezik: két jel „ellopja” egymás éleit.
10.4. feladat — Mérd meg a remanenciát
Megoldás — a várt értékek
| Művelet | VAR RETAIN |
VAR PERSISTENT |
|---|---|---|
| meleg indítás | megmarad | megmarad |
| hideg indítás | elvész | megmarad |
| új letöltés | elvész | megmarad |
| tápelvétel → visszakapcsolás | megmarad | megmarad |
Ez pontosan a 10.3. alfejezet táblázata. A tápelvételes próba azt mutatja meg, hogy a remanens terület nem a futó memóriában él: a készülék tápfeszültség nélkül is megőrzi.
⚠ Fontos: a saját eszközödön mérd is meg, ne csak olvasd. Az I függelék M1 eljárása ehhez ad lépéssort és jegyzőkönyv-sablont; a gyártói dokumentáció a remanens terület méretét és élettartamát is korlátozhatja.
10.5. feladat — Írj függvényt és funkcióblokkot ugyanarra
Megoldás
FUNCTION Skalaz : REAL VAR_INPUT iNyers : INT; END_VAR Skalaz := INT_TO_REAL(iNyers) * 100.0 / 27648.0;
FUNCTION_BLOCK FB_Skalaz VAR_INPUT iNyers : INT; END_VAR VAR_OUTPUT rSzazalek : REAL; rMaximum : REAL; END_VAR rSzazalek := INT_TO_REAL(iNyers) * 100.0 / 27648.0; IF rSzazalek > rMaximum THEN rMaximum := rSzazalek; END_IF
Miért nem lehetett függvénnyel? Mert a legnagyobb eddigi értéket a hívások között meg kell
őrizni — a FUNCTION viszont állapotmentes: minden híváskor „újjászületik”.
⚠ Gyakori hiba: a skálázásban egész osztás. Az iNyers * 100 / 27648 kifejezés INT
aritmetikával számol, és túl is csordulhat; ezért kell REAL-lé alakítani a művelet előtt.
Tudáspróba — megoldókulcs
| # | Válasz | Indoklás | Szakasz |
|---|---|---|---|
| 1 | a | A VAR blokk változója lokális, kívülről nem írható. |
10.1 |
| 2 | b | A VAR_IN_OUT átadása mutatóval (call-by-reference) történik. |
10.1 |
| 3 | c | A VAR_TEMP minden POU-híváskor újrainicializálódik. |
10.1 |
| 4 | d | Új letöltést csak a VAR PERSISTENT él túl; a RETAIN törlődik. |
10.3 |
| 5 | a | Reset Warm után a RETAIN és a PERSISTENT is megmarad. |
10.3 |
| 6 | b | A FUNCTION-nek nincs belső állapota, és nem használhat globális változót. |
10.6 |
| 7 | c | A példányon kívülről csak a bemeneti és kimeneti változók érhetők el. | 10.7 |
| 8 | d | A PROGRAM-nak van állapota, de nincs példánya. |
10.8 |
| 9 | a | Három független késleltetéshez három TON-példány kell. |
10.10 |
| 10 | b | Az EXTENDS / IMPLEMENTS csak funkcióblokknál használható. |
10.11 |