Aktuální vydání

celé číslo

07

2021

Automatizace řízení dopravy a infrastruktury, nabíjecí stanice, autonomní vozidla

celé číslo

Esperanto programátorů PLC: programování podle mezinárodní normy IEC/EN 61131-3 (část 3)

Výukový seriál o programování PLC pokračuje třetím dílem, který seznamuje s progra­movými organizačními jednotkami uživatelského programu PLC (funkce, funkční blo­ky, program) a vysvětluje, jak používat jednotlivé objekty programu PLC: identifikátory, klíčová slova, komentáře, typy dat, literály a deklarace proměnných.
 

Programové organizační jednotky (POU)

 
Při programování podle normy IEC/EN 61131-3 je základním pojmem programová organizační jednotka (POU – Program Orga­nization Unit). Je to nejmenší nezávislá jed­notka uživatelského programu PLC. Obvykle ji vytváří uživatel PLC pro svou aplikaci, ně­které může dodávat výrobce řídicího systé­mu se svým vývojovým systémem (např. jako knihovny funkcí a funkčních bloků). Jednot­livé POU mohou volat další POU a při tom si mohou vzájemně předávat potřebné para­metry. Existují tři typy POU: funkce, funkční blok a program.
 

Funkce

Funkce je nejjednodušší typ programo­vé organizační jednotky. Zpracovává vstup­ní parametry a předává jediný výstupní para­metr – ten je závislý jen na aktuální hodnotě vstupních parametrů, nezávisle na dřívějších aktivacích nebo na čase. Při opakovaném vo­lání se stejnými parametry předává funkce stejný výsledek (výstupní parametr). POU typu funkce je možné přirovnat ke kombi­nační logické funkci nebo k integrovanému obvodu, který ji realizuje (např. logického součinu AND, multiplexoru nebo dekodé­ru). V oboru spojitých a číslicových systémů je analogickým prvkem statický systém bez vlastní dynamiky, např. zesilovač, korekční člen. Norma popisuje široký sortiment stan­dardních funkcí:
  • funkce pro konverzi typu dat,
  • numerické funkce jedné proměnné (abso­lutní hodnota, odmocnina, exponenciální a logaritmické funkce, sinus, kosinus, tan­gens a k nim inverzní funkce),
  • numerické funkce dvou a více proměnných (sčítání, násobení, odčítání, podíl a dělení modulo, obecná mocnina),
  • funkce prováděné s řetězci bitů (rota­ce, booleovské funkce AND, OR, XOR, NOT),
  • funkce výběru (multiplexor, maximum, minimum, omezovač),
  • porovnávání (zobecnění relací nerovnosti větší, větší nebo rovno, menší, menší nebo rovno, rovnost, neshoda),
  • funkce pro řetězce znaků,
  • funkce s typy datum a čas,
  • funkce s výčtem.
Uživatel si může vytvářet své vlastní (uži­vatelské) funkce, může je získat i od výrob­ce PLC nebo vývojového systému v knihovnách problémově orientovaných POU ([1], [4], [12]). Deklarovaná funkce je v paměti programu obsažena jen v jednom exempláři a při volání se nevytvářejí její kopie – funk­ce se pouze provede a předá svou výstup­ní hodnotu.
 

Funkční bloky

Funkční blok je obecnější organizační jednotka než funkce. Může zpracovávat více vstupních parametrů a předávat více výstup­ních parametrů. Ve svých vnitřních pro­měnných může uchovávat informace o sta­vu z posledního volání. Je obvyklé, že při opakovaném volání se shodnými hodnota­mi vstupních proměnných předává funkč­ní blok odlišné hodnoty výstupních pro­měnných (např. u čítače nebo časovače) . Funkční blok lze přirovnat k sekvenční lo­gické funkci nebo k integrovanému obvo­du, který ji realizuje, např. klopnému obvo­du, čítači nebo časovači. V oboru spojitých nebo číslicových systémů jsou analogický­mi prvky systémy s vlastní dynamikou nebo jejich programové modely, regulátory nebo číslicové filtry.
 
Norma nabízí několik typů standardních funkčních bloků:
  • bistabilní prvky (klopné obvody SR s do­minantním nastavením a RS s dominant­ním mazáním),
  • detekce náběžné (R_TRIG) a sestupné hra­ny (F_TRIG),
  • čítače (dopředný CTU, zpětný CTD a oboustranný CTUD),
  • časovače (pulzní TP, zpoždění náběžné a sestupné hrany – TON a TOF).
Uživatel si může vytvářet své vlastní (uživatelské) funkční bloky, může je získat i od výrobce PLC nebo vývojového systé­mu v knihovnách problémově orientovaných funkčních bloků ([1], [4], [12]). Vzhledem k jejich paměťovému charakteru existují funkční bloky ve dvou formách: deklarace a instance.
 
Deklarací se vytvoří obecná matrice funkčního bloku se specifikací všech jeho proměnných (vstupních, výstupních a vnitřních proměnných) a s programem, který popisuje jeho činnost. Deklarace funkční­ho bloku je pouze předpisem, ve kterém je deklarována struktura dat spolu s algo­ritmy, které se budou s těmito daty prová­dět. V místě každého použití deklarovaného funkčního bloku se provede jeho instance – vytvoří jeho pojmenovaná kopie s doplně­ním jmen konkrétních proměnných a hodnot parametrů. Každé instanci je přiřazeno uni­kátní jméno funkčního bloku. Deklarovaný funkční blok je v paměti programu uložen v jednom exempláři, ale (na rozdíl od funk­ce) na místě každého použití se ještě dopl­ní jeho instance.
 
Obrazně je možné definovaný funkční blok přirovnat k razítku s volnými kolonka­mi a instanci k jeho otisku s individuálně doplněnými údaji. Jakýkoliv funkční blok, který byl již deklarován, může být použit v dekla­raci jiného funkčního bloku.
 

Programy

Program je vrcholnou programovou jed­notkou v uživatelském programu. V normě je definován jako „logický souhrn programovacích jazyků a konstrukcí nutných pro zamýšlené zpracování signálů, které je vy­žadováno pro zamýšlené řízení stroje nebo procesu systémem programovatelného au­tomatu“. Jinak řečeno, funkce lze přirovnat k podprogramům a funkční bloky k makrům (subroutines), zatímco POU typu program je hlavní program (main program). Progra­my mohou volat funkce a funkční bloky, nikoliv naopak. Centrální jednotka PLC může zpracovávat více programů. Rovněž program je třeba považovat za definici, ke které je třeba vytvořit instanci – k tomu je určen aparát konfiguračních prvků, konfi­gurací, zdrojů a úloh. Zde se jimi nebude­me zabývat, základní způsob aktivace je ob­vykle předdefinován ve vývojovém systému ([1], [4], [12]).
 
Deklarace všech POU mají obdobnou strukturu. Začínají deklarací jména POU, ná­sleduje deklarační část se jmény vstupních, výstupních a lokálních proměnných, pak vý­konná část (tělo POU) s příkazy programu, popř. s voláním dalších POU, a na závěr je napsáno klíčové slovo END s uvedením typu POU (obr. 8). Deklarace programu může mít např. tuto podobu:
 
PROGRAM Rizeni_Linky (*jméno programu*)
(*deklarační část*)
VAR_INPUT
pocetDavek : UINT; (*vstupní proměn- né*)
pocetKusu : UINT;
END_VAR
VAR
pomoc, odloz REAL;(*lokální proměnné*)
priznak BOOL;
END_VAR
(*výkonná část*)
priznak := (pocetDavek <> 0) AND (pocetKu- su <> 0);
IF priznak THEN ….
…..
END_IF
…..
…..
END_PROGRAM (*konec programu*)
 

Identifikátory

 
Identifikátory (identifiers) se používají jako jména konstant, proměnných, návěští, odvoze­ných datových typů, funkcí, funkčních bloků, programů a úloh. Identifikátor je řetězec ma­lých a velkých písmen anglické abecedy, číslic a podtržítek (_). Musí začínat písmenem nebo podtržítkem a nesmí obsahovat mezery. Zna­ky národních abeced (např. s čárkami a háčky) nejsou v identifikátorech povoleny. Umístění podtržítka v identifikátoru je významné (např. ZBL_BL, ZBLB_L, Z_BLBL jsou různé iden­tifikátory). Více podtržítek za sebou není pří­pustné. Velikost písmen se v identifikátorech nerozlišuje. Zápisy MOTOR_ON, motor_on, Motor_On, Motor_on, motor_ON představují shodné identifikátory a mohou označovat stej­nou proměnnou. Příklady platných a neplat­ných identifikátorů uvádí tab. 1.
 

Klíčová slova

 
Klíčová slova (keywords) jsou standard­ní identifikátory, které norma předurčuje pro specifické použití, např. FUNCTION, BOOL, TRUE, REAL, INT, VAR, VAR_INPUT, END_VAR, AND, IF, THEN, TON. Klíčo­vá slova se nesmějí používat pro vytváření jakýchkoliv uživatelských jmen. Pro jejich zápis mohou být použita malá i velká písme­na – pro odlišení od ostatních identifikátorů se však často píšou velkými písmeny (není to ale nutné). Ke klíčovým slovům patří pře­devším jména elementárních datových typů, standardních funkcí a funkčních bloků, a jmé­na jejich vstupních a výstupních parametrů, prvky textových jazyků IL a ST.
 

Komentáře

 
Komentáře (comments) nemají syntaktic­ký ani sémantický význam, jsou však důležité k dokumentování programu a k jeho zpětné­mu pochopení. Lze je zapsat všude tam, kde je možné zapsat znak mezera. Při překladu pro­gramu jsou komentáře ignorovány. Proto mo­hou obsahovat libovolné znaky, včetně znaků národních abeced, např. znaky s háčky a čárka­mi. Překladač rozeznává dva typy komentářů: obecné a řádkové. Obecné komentáře jsou ře­tězce znaků uvozené otevírací závorkou a hvěz­dičkou (* a zakončené hvězdičkou a uzavírací závorkou *). Mohou být i víceřádkové, např.:
 
(* takto může vypadat obecný komentář
Může být víceřádkový a může obsahovat li­bovolné znaky české abecedy
Vyplatí se nešetřit výstižnými komentáři,
protože vynaložené úsilí se vrátí ve formě lep­ší čitelnosti programu
a ušetří čas i stres při ladění a úpravách pro­gramů
…. a takto obecný komentář končí *)
(*Obecným komentářem lze označit i části programu, které se z určitých důvodů nemají překládat, ale přesto mají zůstat zachovány a zůstat viditelné, např:
motor_1 := start OR motor_1 AND NOT stop;
alarm := sz_a AND (sz_b OR sz_c) OR sz_b AND sz_c);
… konec ignorovaného programu *)
 
Řádkové komentáře začínají dvojicí znaků // (lomítek) a končí s koncem řádku.
 

Typy dat

 
Typy dat zlepšují přehlednost progra­mu a jsou prevencí chyb programátora. Typ je nutné definovat pro každý použitý objekt (proměnné, data). V první části se­riálu budeme nejčastěji pracovat s jednot­livými dvouhodnotovými proměnnými (bi­tovými, booleovskými). Ty mají v normě určen formát BOOL (Boolean). Pro skupi­ny (řetězce) bitových proměnných použí­vá norma typy:
  • BYTE pro sekvence osmi bitů,
  • WORD (slovo) pro sekvence16 bitů,
  • DWORD (double word, dvojité slovo) pro sekvence 32 bitů,
  • LWORD (Long Word, dlouhé slovo) pro sekvence 64 bitů.
Pro různé typy celočíselných objektů jsou definovány typy uvedené v tab. 2 a pro čís­la s pohyblivou desetinnou čárkou lze po­užít typy specifikované v tab. 3. Samostat­né typy jsou vyhrazeny pro časové údaje (tab. 4). Pro celočíselné objekty (se znamén­kem i bez znaménka) platí, že řádová tečka se u nich sice neuvádí, ale je předpokládána na pevné pozici za poslední číslicí. Číselné objekty se znaménkem (SINT, INT, DINT) mají poloviční číselný rozsah, oproti odpo­vídajícím objektům bez znaménka (USINT, UINT, UDINT), protože pro zobrazení čísla je k dispozici formát o jeden bit kratší – je­den bit je vyhrazen pro zobrazení znaménka (znaménkový bit). U objektů s pohyblivou (plovoucí) řádovou tečkou je situace složi­tější. Podle zvolené přesnosti je pro formát čísla vyhrazena délka 32 bitů (REAL) nebo 64 bitů (LREAL). V tomto rozsahu jsou ulo­ženy dva číselné údaje – mantisa (ve které je zakódován číselný údaj v normalizovaném rozsahu) a exponent (řád mocniny, kterou je třeba násobit mantisu, aby byla získána skutečná hodnota čísla). Zjednodušeně lze říci, že mantisa určuje numerickou hodnotu čísla a exponent polohu řádové tečky. Podrobnosti jsou uvedeny např. v [1], [4]. Počítání v po­hyblivé řádové tečce je výhodné, jestliže se pracuje s necelými (zlomkovými) čísly nebo při provádění složitějších výpočetních opera­cí (např. násobení, dělení a složitější funkce). Počítání v pevné řádové tečce (s čísly celočí­selného formátu) je účelné pouze tehdy, jestli­že se s celými čísly (se znaménkem nebo bez znaménka) provádějí nejjednodušší výpočet­ní operace sčítání, odčítání a porovnávání.
 
Znakovým řetězcům je vyhrazen typ STRING (String, řetězec, max. 255 znaků). Uvedené typy jsou označovány jako elemen­tární datové typy. Kromě nich norma definuje ještě rodové datové typy, které popisují celou skupinu (rod) typů, a dále odvozené datové typy (jednoduché, pole, struktury dat a je­jich kombinace).
 

Literály

 
Pro přímou reprezentaci hodnot proměn­ných se používají literály (numerické, řetěz­ce znaků, časové). Mohou udávat přímo hod­notu (např. 14, –18.5, nebo 0.123_4) nebo je na začátku literáru uvedeno jméno datového typu (INT#14, REAL#–18.5, REAL#0.123_4). U časových literálů je uvedení typu povinné, např. TIME#12h20m33s. Na rozdíl od češtiny, se v literálech uvádí řádová tečka, nikoliv čárka.
 

Numerické literály

Numerický literál je zápis číselné hodnoty (konstanty) v desítkové soustavě nebo v sou­stavě o jiném základu (např. dvojkové, osmič­kové, šestnáctkové). Základ soustavy se uvá­dí na začátku a od číselného údaje je oddělen znakem #. Základ desítkové soustavy se neu­vádí. Příklady numerických literálů pro pří­slušné typy dat jsou uvedeny v tab. 2 a tab. 3.
 
Například hodnotu 215 (v desítkové soustavě) lze zapsat těmito způsoby: 215, 2#1101_0111, 8#327, 16#D7. Mezi čísli­cemi smí být pro přehlednost použit znak podtržítka, jehož umístění nemá vliv na čí­selnou hodnotu. Podle číselného typu se rozlišují literály typu integer s pevnou řádo­vou čárkou (zde tečkou), např. 14, INT#14, –123, 12_345_678, a typu real s pohybli­vou řádovou tečkou, např. –12.3, 0.123_4, REAL#8.5). Pravdivostní hodnota logické (booleovské) proměnné se zadává literálem FALSE nebo BOOL#0 pro logickou nulu (ne­pravdu) a TRUE nebo BOOL#1 pro logickou jedničku (pravdu).
 

Řetězce znaků

Řetězec znaků (string) je posloupnost zna­ků (jednoho, více, popř. žádného – prázdný řetězec), uzavřená mezi apostrofy, ’’ např. ’teplota=’, ’°C’, prázdný znak se zapíše dvo­jicí apostrofů: ’’. Jako prefix pro zadání zna­ků v osmibitovém kódu ASCII se používá znak $ (dolar), např. řetězec dvou znaků CR (Enter, šestnáctkově 0D) a LF (odřádkování, šestnáctkově 0A) se zapíše ‚$0D$0A‘. Znak $ uvozuje ale i speciální znaky v řetězcích, např. $$ pro znak $ (dolar) nebo $‘ pro znak ’(apostrof). Literály řetězce znaků (string) se používají především při programování tex­tů pro operátorské panely, textová hlášení (např. pro SMS nebo e-maily, pro vizualizaci ve SCADA nebo pro webové stránky) a pro výměnu textů mezi různými PLC a počítači v distribuovaném systému.
 

Časové literály

Při řízení technologických procesů, ale i technických zařízení budov a energetic­kých zařízení jsou často potřebné časové úda­je dvou typů. Prvním z nich je údaj o době trvání, která uběhla či má uběhnout od ur­čité události. Ve druhém případě je to údaj o „absolutním čase“, tedy o datu podle ka­lendáře a o čase v rámci dne. Příklady ča­sových literálů pro příslušné typy dat jsou uvedeny v tab. 4. Časový literál pro dobu tr­vání je uvozen některým z klíčových slov T#, t#, TIME# nebo time#. Časový údaj je vyjádřen v časových jednotkách: hodinách (h, H), minutách (m, M), sekundách (s, S) a milisekundách (ms, MS) – zkratky mo­hou být vyjádřeny malými a velkými písme­ny, mezi údaji mohou být použita podtržít­ka, např. TIME#5h_35m_5s (trvání 5 hodin, 35 minut a 5 sekund), T#45ms (trvání 45 milisekund). Časový literál pro datum a pro denní čas reprezentuje údaje o kalen­dářním datu (DATE#, D#, např. DATE#2011-08-25, dne 25. 8. 2011) a o čase v rámci dne (TIME_OF_DAY#13:25:15.7 nebo rov­nocenně TOD#13:25:15.7, v 13 hodin, 25 minut a 15,7 sekund). Pro souhrnný údaj o „absolutním“ čase se používá kombinova­ný zápis, např. DATE_AND_TIME#2011-08--25-13:25:15.7 nebo rovnocenně DT#2011--08-25-13:25:15.7, dne 25. 8. 2011 v 13 ho­din, 25 minut a 15,7 sekund. Velikost písmen opět není rozlišována.
 

Proměnné

 
Podle normy jsou proměnné určeny pro identifikaci datových objektů, jejichž obsah se obvykle mění, např. dat přiřazeným ke vstupům, výstupům nebo k vnitřní paměti PLC. Proměnná může být deklarována někte­rým z elementárních nebo odvozených (uži­vatelských) datových typů. Proměnné jsou identifikátory, zvolené programátorem, kte­ré jsou obvykle určeny k rezervování místa v paměti pro uložení dat. Součástí deklarace proměnných může být i údaj o jejich počá­teční hodnotě (inicializace). Stejnou formu jako deklarace proměnných ovšem mají i de­klarace konstant. Každá deklarace programo­vé organizační jednotky (POU, tedy progra­mu, funkčního bloku nebo funkce) by měla v úvodu obsahovat alespoň jednu deklarační část, která definuje jména a datové typy pro­měnných používaných v této POU.
 
Deklarační část je zahájena klíčovými slo­vy VAR (pro vnitřní proměnné POU), popř. některým klíčovým slovem, které začíná VAR_, např.:
  • VAR_TEMP pro vnitřní proměnné pře­chodného typu,
  • VAR_INPUT pro vstupní proměnné,
  • VAR_OUTPUT pro výstupní proměnné,
  • VAR_IN_OUT pro vstupní a výstupní pro­měnné.
Deklarační část končí klíčovým slovem END_VAR. Proměnné platí vždy pouze uvnitř té POU, v níž jsou deklarovány (jsou zde lokální), a nejsou přístupné pro ostatní POU (nejsou z vnějšku POU „viditelné“). Výjimkou jsou proměnné pro předávání pa­rametrů mezi POU a jejím okolím – vstup­ní proměnné, do kterých lze z vnějšku za­pisovat (VAR_INPUT), výstupní proměnné (VAR_OUTPUT), které lze z vnějšku číst, a proměnné pro obousměrný přístup (vstup­ní a výstupní proměnné - VAR_IN_OUT).
 
Proměnné deklarované jako VAR mají vy­hrazeno pevné místo v paměti a mají dlou­hodobou platnost. Skončí-li aktivace POU, pamatují si poslední hodnotu, která je pak použita jako výchozí při opětovné aktivaci POU. Naproti tomu proměnné deklarované jako VAR_TEMP mají přechodný charakter, při ukončení aktivace POU zanikají (jejich místo v paměti se uvolní) a při opětovné ak­tivaci se znovu vytvoří s nulovým nebo jinak iniciovaným obsahem.
 
Existují ale i proměnné s všeobecnou (glo­bální) platností – VAR_GLOBAL. Jsou dekla­rovány vně POU (obvykle před programem) a jsou dostupné pro všechny POU v programu. Za klíčovým slovem VAR_GLOBAL může být ještě uveden kvalifikátor RETAIN (tedy VAR_GLOBAL RETAIN), který označuje zá­lohované proměnné, nebo CONSTANT pro označení konstantního obsahu proměnné, tedy pro deklaraci konstanty. Celý blok deklarací tedy může mít tvar:
 
VAR_GLOBAL RETAIN
RemanentniBit BOOL;
RemanentniPamet BYTE := 123;
DalsiRemanent BYTE := 63;
END_VAR
 
V uvedeném příkladu jsou všechny tři pro­měnné deklarovány jako globální a remanentní. Po zapnutí (horkém restartu) se obnovuje jejich poslední obsah, který měly těsně před vypnutím. Bitová (booleovská) paměť RemanentniBit není iniciována, zatímco proměnné RemanentniPa­met a DalsiRemanent jsou po prvním zapnutí a po studeném restartu iniciovány – nastavovány na hodnotu 123 a 63 (obě v desítkové soustavě).
 
Podobnou vlastnost mohou mít proměnné deklarované jako VAR_EXTERNAL. Zde je ale situace složitější. Obecně jsou takto de­klarovány proměnné, které pocházejí z ex­terního zdroje. V systému Mosaic jsou tak­to označeny proměnné definované v původ­ním jazyku mnemokódů pro PLC systémy Tecomat. V jiných vývojových systémech to může být jinak.
Ladislav Šmejkal
 
Obr. 8. Ukázka definice jednoduchého funkčního bloku, funkce a programu v jazyce ST
 
Tab. 1. Příklady platných a neplatných iden­tifikátorů
Tab. 2. Typy dat pro celočíselné objekty
Tab. 3. Typy dat pro objekty s pohyblivou desetinnou čárkou
Tab. 4. Typy dat pro časové údaje