CoDeSys
Siemens S7-1200 viide Siemens LOGO! viide Automatiseerimise viide Mehhatroonikaseadmete viide Pneumoautomaatika viide

PLC programmeerimine

Standard IEC 61131-3

Modernsed programmeerimistööriistad peavad vastama teatud nõudmistele, et nendega saaks odavalt luua piisava funktsionaalsusega automatsiseeritud tehnilisi rakendusi. Arendustöö efektiivsuse tõstmiseks kasutatakse erinevaid programmeerimiskeeli. Rakendusprogrammide loomiseks ja kergeks muutmiseks peab programmeerimistööriist võimaldama masina käivituseelset programmi testimist, simuleerimist ning tööstuskontrolleris (PLC-s) oleva tegeliku programmi dokumenteerimist. Sageli on vaja PLC programmi muuta ka masina töö ajal. PLC-s olevad programmilõigud peavad pärast dokumenteerimist olema korduvkasutatavad. Nende nõudmiste täitmisel astuti suur samm edasi rahvusvahelise standardi IEC 61131 kasutuselevõtmisega.

Kuna standard IEC 61131 on väga detailirohke, siis ei rakenda eri firmad oma programmeerimissüsteemides kõiki selles standardis kirjeldatud võimalusi. Standard pakub võimaluse kirjeldada funktsionaalseid nõudmisi tabeli abil. Tootja peaks tabelis ära märkima need funktsioonid, mida ja missuguses ulatuses nende tarkvaratööriist ja/või PLC täidab. Paljud PLC tootjad toetavad standardit IEC 61131, kuid nende tööriistade vastavus standardi nõudmistele kõigub laias ulatuses. Eri firmade programmeerimistööriistade täieliku vastavuse saavutamine ei ole kerge ülesanne. Sellele on kõige lähemale jõudnud ettevõte 3S-Smart Software Soultions GmbH oma tarkvara keskkonnaga CoDeSys ja tarkvaraliste kontrolleritega.

Standardi IEC 61131 kolmandas osas (IEC 61131-3) kirjeldatakse PLC programmeerimiskeeli ja juhtimisprogrammi ülesehitust. Standard harmoniseerib, pidades silmas ka tuleviku võimalusi, laialdaselt kasutatavaid programmeerimiskeeli [11viide].

Programmi struktuur

Joonisel 2.1 on esitatud programmi struktuuri hierarhiline ülesehitus vastavalt standardile IEC 61131-3. Kõik siin toodud elemendid on leitavad CoDeSys-is ja teiste PLC tootjate tarkvarades mõningal juhul teiste nimede all.

Joonis 2.1

Seadistus on programmi struktuuri (PLC projekti) kõige kõrgem tase (joonis 2.1). Tema alla paigutatakse PLC koos kõikide riistvaraliste moodulitega. Ühes masinas/projektis võib olla rohkem kui üks PLC ehk seadistus. Erinevad seadistused suhtlevad omavahel läbi andmeside plokkide (funktsioonide) ja globaalsete muutujate.

Ressurss on seadistuse alamüksus (joonis 2.1). Ta määratleb PLC CPU osa, kus hakatakse mingit ülesannet täitma. Ressursiks loetakse ka PLC enda rakendust. Ühes PLC-s võib olla mitu CPU-d ehk siis ressurssi. Need CPU-d saavad vahetada läbi globaalsete muutujate vajalikku informatsiooni. Siin ei ole vaja kasutada eraldi spetsiaalseid andmeside plokke.

Ülesannet kasutatakse ressursis oleva juhtimisprogrammi täitmise juhtimiseks ( joonis 2.1). Igas ressursis võib olla rohkem kui üks ülesanne, mis võimaldab teostada multitegumtööd PLC-s (vt pt "Multitegumtöö"). Erinevate ülesannete vahel saab jagada informatsiooni läbi globaalsete muutujate. Ülesande enda sees saab vahetada infot ka kohalike ehk siis sisemiste muutujate kaudu.

Ülesannet saab seadistada nii, et igat programmi ülesehituse plokki (POU) käitatakse kas

  • tsükliliselt,
  • vabalt,
  • või sündmuse põhiselt.

Tsüklilise ülesande käitamise puhul täidetakse seda vastavalt ettemääratud aja intervallile. Aeg tuleb valida piisavalt pikk, nii et kogu juhtimisprogramm (kogu kood) jõutakse ära täita enne, kui seda on vaja uuesti täitma hakata.

Vabalt käitavat ülesannet täidetakse kohe, kui CPU läheb töörežiimi. Kui CPU-s olev protsessor ei ole hõivatud mingi ülesande täitmisega, siis hakatakse kohe uuesti täitma vabalt käitavat ülesannet.

Ülesanne käitatakse sündmuse poolt, kui mingi määratud muutuja juures tuvastatakse tõusev signaali muutus. Veel on olemas ülesande käitamine välise sündmuse poolt, kui juhtimissüsteemis esineb sündmuse väljal defineeritud sündmus. Süsteemi sündmusi ei tohi ajada segamini CoDeSys süsteemisündmustega.

POU-desse kirjutatud programmiosade täitmist saab järjestada ka nende tähtsuste (prioriteedi) järgi. Igale ülesandele määratakse sobiv prioriteedi numbri (need võivad olla ka samad). Mida väiksem on ülesande prioriteedinumber seda suurem on sellega seotud POU-de prioriteet. Lugeda pt "Multitegumtöö", et saada aru, kuidas kasutatakse prioriteete ja millised reeglid kehtivad PLC-s multitegumtöö juures.

Programmi ülesehituse plokk

Standardis IEC 61131-3 nimetatakse funktsionaalseid plokke, millest moodustatakse kõik programmid ja projektid, programmi ülesehituse üksusteks (POU-deks). Tavapärases PLC arenduskeskkonnas vastavad nendele programmiplokid, juhtimisplokid, järjestusplokid ja funktsiooniplokid [viide]. Standardi üks oluline eesmärk on piirata eri plokitüüpide mitmekesisust ja seega lihtsustada nende kasutamist. Standard määratleb järgmised POU tüübid:

  • funktsioon (FUN)
  • funktsiooniplokk (FB)
  • programm (PRG)

Neid POU-sid kasutatakse ka CoDeSys-is, võimaldades struktureerida mingi seadme/protsessi juhtimisprogrammi paremini.

POU nimega "Programm"

Programm (PRG) on kõrgetasemeline POU, mida kasutatakse juhtimisprogrammi sidumiseks mingi ülesandega. See on liides masina juhtimisprogrammi ja PLC operatsioonisüsteemi vahel. PRG on samaväärne Siemensi STEP-7 juures kasutatava juhtplokiga (OB). PRG sees oleva programmi kirjutab programmeerija, kuid see käitatakse (hakatakse täitma) ülesande abil PLC operatsioonisüsteemi poolt. Ühes ülesandes võib olla rohkem kui ainult üks PRG tüüpi POU. Kuid kõik PRG-d ei pea olema seotud ülesannetega. Ülesandega mitte seotud PRG võib siduda teise PRG-ga. See teine PRG on siis seotud mingi ülesandega, et käitada tema sees olevat programmiosa. Selle sidumata jätmisel ei täideta selle sees olevat programmi. PRG tüüpi POU-d ei ole võimalik siduda teiste POU tüüpidega (kasutada nende sees).

CoDeSys tekitatakse PRG nimega PLC_PRG ja see seotakse automaatselt mingi tsüklilise ülesandega (CoDeSys on selle nimi MainTask), kui uue PLC projekti loomisel valitakse kohe ka kontroller (PLC, millele antud projekt luuakse). PLC_PRG-d võib käsitleda, kui peaprogrammi faili, mille sisse koostatud juhtimisprogrammi hakatakse täitma kontrolleri poolt teatud ajaintervalli järel. Seda muidugi kui CPU on töörežiimis.

POU nimega "Funktsioon"

Joonis 2.2

Üldjoontes loetakse funktsiooniks (FUN) POU-d, millel on sisendid, üks väljund (väljund on seotud FUN nimega) ja kohalikud muutujad, mille väärtusi ei peeta meeles (mälus) pärast FUN täitmist. Samade sisendväärtuste puhul annab FUN alati ühesuguse väljundväärtuse. FUN teostab alati kindlat protseduuri ja sellel on reeglina üks väljund. FUN loomisel tuleb täpsustada selle (väljundi) andmetüüp, mille kadu väljastatakse selles oleva programmi tulemus (joonis 2.2). Samas võib CoDeSys-s loodud FUN omada rohkem kui üht väljundit.

FUN mõte seisneb selles, et mingit kindlat ülesannet täitva programmiosa peab funktsioonina kirjutama vaid ühe korra. Edaspidi, kui on soov seda programmiosa uuesti kasutada, ei tule seda iga kord uuesti kirjutada, vaid piisab vastava FUN-i väljakutsumisest (joonis 2.3). Sisendite ja väljundite abil saab määrata uued muutujad, millega antud FUN peab täitma kindla ülesande. FUN ossa tuleks koostada programm, mille sisendmuutujate väärtusi ei ole vaja meeles pidada ehk siis selle järgmisel käitamisel võivad need PLC mälust kustutatud olla. Tänu sellele ei ole vaja FUN-i deklareerida teistes POU-des, kus seda kasutatakse.

Joonis 2.3

POU nimega "Funktsiooniplokk"

Joonis 2.4

Funktsiooniplokk (FB) on FUN-ile sarnane POU. Vahe on selles, et sellel POU-l on mälu ja selle väljundite väärtus sõltub sisendmuutujate ja samuti ka plokisiseste (mälus olevate) muutujate väärtustest. FB-l võib olla mitu üheaegset väljundit. Kõikide plokisiseste muutujate (välja arvatud „VAR_TEMP“ piirkond) väärtused peetakse FB töö vaheajal meeles (hoitakse mälus). Ühest FB-st võib olla mitu instantsi. Instantsides kasutatakse sama FB-s olevat programmikoodi aga erinevaid muutujate väärtusi, kui FB-d on deklareeritud vastavas POU-s (milles käitatakse) muutujate deklaratsiooni osas (joonis 2.4).

FB kasutamine on mõttekas siis, kui on vaja täita spetsiifilist ülesannet ning selle ülesandega seotud andmeid on vaja meeles pidada. Mitme FB instantsi kasutamine on mõttekas näiteks mitme sarnase seadme (nt pumpade, mahutite, jne) juhtimisel, mille juhtimisega seotud andmed tuleb meeles pidada. Sellisel juhul luuakse iga pumba kohta eraldi instants pumpade juhtimise FB-st (joonis 2.4), mida on tegelikkuses on ainult üks FB. FB kasutamine ei pea olema ilmtingimata seotud seadmetega.

Muud POU-d

Peale tavaliste programmeerija poolt kasutatavate POU-de (PRG, FUN ja FB) pakuvad kontrollerite tootjad ja kolmandad osapooled veel lisa FB-sid ja FUN-d, mis ei ole standardis IEC 61131-3 defineeritud. Programmeerija saab neid kasutada (käitada) oma programmis, kuid ei saa nende sisu muuta ja vaadata. Need POU-d võimaldavad lahendada paljusid tavalisi ülesandeid ja funktsioone (näiteks andmeside, lambi vilgutamine) ning vähendavad seetõttu oluliselt programmi arendamise aega. Üks lisafunktsioonide pakkuja on OSCAT, mis on koostanud erinevaid teeke hooneautomaatika, andmeside, jne jaoks. OSCAT poolt pakutud POU-d ei ole riistavara põhilised ning neid saab kasutada peale CoDeSys ka Siemensi STEP 7 juures. Mainimist väärib ka teek Util.lib, mis on CoDeSys integreeritud ja omab päris mitut huvitavat funktsiooni.

Programmi täitmine PLC-s

Joonisel 2.5 on esitatud CoDeSys-ga programmeeritud PLC programmi tsükliline täitmine. Rakenduse põhiprogrammi täitmine toimub PLC_PRG kaudu. Pärast toite sisselülitamist ja CPU lülitamist TÖÖ režiimi hakatakse täitma PLC_PRG. PLC_PRG täidetakse igal PLC tsüklil kuni CPU TÖÖ režiimi katkestatakse või toide lülitatakse välja. Kuna PLC_PRG on ainuke POU, mis on seotud tsüklilise ülesandega (täidetakse koguaeg iga teatud aja tagant), siis tuleb teised plokid selle abiga käitada (aktiveerida). Kui mingi plokk oli käitatud PLC_PRG poolt ja see lõpetas oma ülesande (tegevused), siis antakse programmi juhtimine tagasi PLC_PRG-le. Ka FUN-d ja FB-d võivad aktiveerida teisi POU-sid (välja arvatud PRG). Joonisel 2.5 on aktiveeritud korraga kuni kaks plokki, nt FUN 1 ja FB 50. Nii saab mingis PLC juhtimisprogrammis käitada päris mitu erinevat POU-d järjest. Lubatud järjest käitavate POU-de arv on piiratud ja see on etteantud vastava PLC mudeli tootja poolt.

Joonis 2.5.

Kasutajaprogrammis (juhtimisprogrammis) on ka sündmuse aktiveerimisel põhinev kõrgema prioriteediga ülesanne, mis käitab PRGx (joonis 2.5). Sündmusega ülesanne aktiveerub näiteks siis, kui hüdraulika rõhk langeb masinas alla lubatud väärtuse. PRGx-i on kirjutatud programm, mis peaks viima masina ohutusse seisundisse. Sündmuse aktiveerimisel katkestatakse PLC_PRG ja temaga seotud teiste POU-de programmide täitmine. Kui PRGx-s olev programm on täidetud, siis jätkatakse PLC kasutajaprogrammi täitmist sealt, kus toimus põhiprogrammi katkestamine.

PLC programmeerimiskeeled

POU loomisel tuleb enamasti määrata ka selle programmeerimise keel. Standard IEC 61131-3 pakub kasutamiseks viit erinevat programmeerimiskeele vormi. Allpool tutvustatakse neid keeli lähemalt.

Käsulist (Instruction List - IL)

Joonis 2.6.
Joonis 2.7.

Käsulist on assembleri laadne madalatasemiline programmeerimiskeel, mida toetab enamus programmeerimise tööriistadest (joonis 2.6). Selle eeliseks on, et PLC ei vaja programmi täitmiseks eriti palju protsessori ressursse. Tema puuduseks on piiratud võimalused ning seda on raske õppida ja kasutada, kui rakenduste juhtimisprogrammid on keerulised. Mõne tarkvara juures kasutatakse seda vahekeelena programmide tõlkimisel teistesse keeltesse.

IL keeles kirjeldab üks programmirida üht korraldust, mis PLC jaoks on üks täidetav käsk. See rida koosneb joonisel 2.7 kujutatud elementidest [viide]. Korraldus algab operatsiooni või käsu sümboliga, millele järgneb üks või mitu komadega eraldatud operandi/muutujat. Kui reas on kommentaar, siis kirjutatakse see rea lõppu ümarsulgude ja tärnide (* ... *) vahele. Osades tarkvarades saab kasutada kommentaarina ka kaht kaldkriipsu //, mis pannakse selle osa ette, kus alustatakse kommentaariga.

Märgist kasutatakse hüpete tegemisel ühest programmi reast teisele, jättes mitu rida või segment vahele. CoDeSys-s on märgise jaoks segmendi alguses ette nähtud eraldi koht. Standardis ei ole kirjeldatud hüppeid programmi sees, kuid see on lubatud paljudes programmeerimissüsteemides, et parandada programmi täitmist ja lühendada sellega PLC töötsükli aega.

Struktureeritud tekst (Structured Text - ST)

  %QX4.0 := %I0.0 AND %I1.1 OR NOT %I0.1;
  IF %QX4.0 = TRUE THEN JMP M_001;
  ELSE %QX1.0 := NOT %QX4.0;
  END_IF;
M_001: %MW2 := 1 + %MW2;

Struktureeritud tekst on tekstil põhinev kõrgtasemeline programmeerimiskeel ülesannete juhtimiseks ja keeruliste matemaatiliste arvutuste tegemiseks (joonis 2.8). See sarnaneb PASCAL-i või C keelele. Antud keele eelis IL ees on selle parem arusaadavus ja jälgitavus inimesele (väga lühikesed ja selged programmilõigud) ning võimsad programmi käskude voo juhtimise elemendid (If-else, For, While, Case). ST keeles koostatud programmi saab jagada mitmeteks sammudeks (avaldusteks), mida kasutatakse väärtuste arvutamiseks ja määramiseks, programmi juhtimiseks ning POU-de kutsumiseks või katkestamiseks. Erinevalt IL-st võib ST avaldis enda alla võtta mitu rida. Samas võib mingi programmi lõigu koondada ka ühele reale.

Standard IEC 61131-3 lubab kasutada ka teisi programmeerimiskeeli (nt C++, C#, jne), kui need täidavad standardis määratud algnõudeid.

Funktsiooniplokkskeem (Function Block Diagram - FBD)

Funktsiooniplokkskeem on graafiline keel aritmeetika, Boole või teiste funktsioonide ja funktsiooniplokkide ühendamiseks. FBD keel on pärit signaali töötluse valdkonnast, kus on olulised reaal- või täisarvud. Selles keeles esitatakse masina juhtimisprogrammi elektroonikaskeemina. Praeguseks on FBD-st saanud universaalne programmeerimiskeel enamuse PLC-de jaoks.

Joonis 2.9.

FBD vormis kirjutatud programmikood on jagatud lõikudeks, mida tuntakse segmentidena. Segmendid võimaldavad struktureerida programmi ja luua ülesehitust POU-s. FBD segmendi graafiline osa sisaldab ristkülikuid (programmi elemendid) ja programmi juhtimise avaldusi koos ühendatud horisontaalsete ning vertikaalsete ühendusjoontega (joonis 2.9). Ristkülikute sisendid võivad olla ühendatud kas muutujatega, konstantidega, teiste programmi elementidega või siis jääda tühjaks kasutamata.

FBD-s kasutatakse horisontaalseid ja vertikaalseid ühendusjooni, mis võivad hargneda mitmeks, erinevate programmiplokkide/funktsioonide/elementide sidumiseks (joonis 2.9). Ühe sisendiga ei tohi ühendada mitut väljundit, kuna see võib põhjustada progammi käitumises ebakõlasid. Programmi juhtimiseks on eraldi olemas käsud lahkumiseks POU-st ja segmentide töötlemise järjekorra muutmiseks.

FBD keeles kirjutatud programmis liiguvad signaalid erinevate I/O-de ja FBD elementide vahel vasakult paremale ning ülevat alla. FBD elementi tulevate sisendsignaalide, mis võivad tulla PLC I/O-dest või teistest FBD elementidest, alusel teostatakse mingi loogikaoperatsioon (nt binaarloogika NING lüli) ning selle tulemus suunatakse elemendi väljundisse. FBD elemendi väljundsignaal edastatakse ühendusjoonte abil kas otse PLC väljundi(de)sse või teise/teistesse FBD keele elementi(desse).

Kontaktaseskeem (Ladder Diagram - LD)

Kontaktaseskeem on graafiline keel, mille abil seotakse tõeväärtuslikke muutujaid. LD on võrreldav varasemalt tuntud masina juhtimissüsteemi elektriliste releeskeemidega, milles esitatakse graafiliselt energia liikumist skeemis. Antud programmeerimiskeel on mõeldud tõeväärtuslikke signaalide (TÕENE/VÄÄR) töötlemiseks. LD keele segment on piiratud vasakult ja paremalt poolt vertikaalsete siinidega. Vasakult siinilt jõuab energia (loogika signaal väärtusega 1) kõikide temaga seotud elementideni (graafiliste sümboliteni). Sõltuvalt skeemielementide olekust lasevad need energial edasi liikuda paremale järgmise elemendini või katkestavad liikumise.

Joonis 2.10.

Nagu FBD puhulgi on ka LD elementide ühendamiseks horisontaalsed ja vertikaalsed ühendusjooned ning ristumispunktid (joonis 2.10). Kontakt LD-s teostab sissetuleva joonega seotud (nimelise) muutuja väärtusega loogikaoperatsiooni. Teostatav loogikaoperatsioon sõltub kontakti tüübist. Operatsiooni tulemusel saadud väärtus/signaal antakse kohe edasi väljuvale joonele (ühendatud paremale poole). Väljuvalt joonelt liigub see (operatsiooni tulemus) ühendusjoonte abil edasi kas siis PLC väljundi(te)sse või teise/teistesse LD keele elementi(desse).

Oma lihtsa jälgitavuse tõttu on see üks enim kasutatavaid PLC programmeerimiskeeli.

Järjestatud funktsioonide kaart (Sequential Function Chart – SFC)

Järjestatud funktsioonide kaart on graafiline programmeerimiskeel tootmisliini juhtimiseks ning selle kui funktsionaalse rakenduse jaotamiseks väiksemateks osadeks. Graafiline skeem näitab ilusti protsessi voogu (liikumist teostusel) ja on seetõttu oluline tööriist PLC programmi struktureerimiseks. SFC keeles on võimalik saavutada rakenduse protsesside järjestikust ja paralleelset täitmist.

Joonis 2.11.

Väiksemate programmiosade (nt protsess, ülesanne) samm-sammuline täitmine sõltub nii programmi voos defineeritud tingimustest kui ka I/O-de käitumisest. Programmi samm on võimalik programmeerida kas otse SFC keeles (joonis 2.11) või standardis IEC 61131-3 defineeritud teistes keeltes.

Esimene SFC struktureerimistase on segment koos selle alla kuuluva sammu ja siirde-elemendiga (joonis 2.11). Samm saab olla aktiivses või mitteaktiivses olekus. Aktiivse sammuga seotud juhiseid (käskusid) täidetakse kuni see muutub mitteaktiivseks. Sammu oleku muutus aktiivsest passiivseks määratakse siirde tingimusega, mis esitatakse tõeväärtusavaldise kujul. Kui aktiivse sammu taga oleva siirdetingimuse väärtus muutub "TÕESEKS", siis aktiveerub selle siirde järel olev samm ja eelnev lõpetab tegevuse. Siirde aktiveerimisega antakse eelneva sammu atribuudi "aktiivne" väärtus edasi järgmisele sammule või sammudele. Aktiivsus liigub läbi sammude, mis kõik koos moodustavad võrgu. Paralleelsete harude puhul jagatakse "aktiivne" olek mitmeks osaks ning harude lõpus liidetakse see uuesti kokku.

Jätkuvate funktsioonide kaart (Continues Function Chart – CFC)

Jätkuvate funktsioonide kaart on graafiline programmeerimiskeel, mis sarnaneb FBD keelele. Tema erinevuseks FBD keelest on see, et koguprogramm koostatakse ühele suurele valgele lehele ning ühendusjooned veetakse käsitsi. See tähendab, et siin ei eksisteeri segmente, mis võimaldavad programmi paremini struktureerida. CFC-s olevad ühendusjooned võimaldavad lisaks tõeväärtuslikele signaalidele kanda edasi ka muid signaale (andmeid nagu tekst, arv, aeg, jne) ühelt programmi elemendilt teisele.

Joonis 2.12.

CFC keeles koostatud programmi täitmise järjekorda märgistab iga elemendi ülemises parempoolses nurgas olev number (joonis 2.12). Neid numbreid on võimalik muuta kas käsitsi või automaatselt andmevoo liikumise järgi.

Jooniselt 2.12 näeb, et sisendeid ja väljundid lisatakse programmi spetsiaalsete kastidega. Ühest sisendist saab vedata ühendusjooned erinevate programmi elementide juurde. Kahjuks ei tööta see väljundite puhul (mitmest elemendist ühte väljundisse kokku).

Muutujate adresseerimine CoDeSys-s

PLC programmi loomisel kasutatakse palju muutujaid, mille poole saab pöörduda kas otse mälupiirkonna aadressi või muutuja sümbolite abil. Muutujad (operandid) on justkui kohahoidjad rakenduse spetsiifiliste andmete/väärtuste salvestamiseks PLC mälus. Vanades PLC-des on levinud otsene adresseerimine ehk siis PLC mälus oleva muutuja absoluutse aadressi kasutamine. Kuid uuemates PLC-des kasutatakse rohkem muutujate sümboleid. Viimast kasutatakse üha rohkem ja rohkem PLC arenduskeskkondades muutujate deklareerimisel.

Muutujate otsene adresseerimine

Enamus PLC-de mälus on piirkonnad, mille poole saab programmist pöörduda programmi täitmiseks vajalike andmete võtmiseks ja/või talletamiseks. PLC-s (nt CoDeSys-iga programmeeritav FESTO CECC-D PLC) kasutatavate muutujate mälupiirkonnad jagunevad järgmiselt:

  • sisendite protsessikuva (I)
  • väljundite protsessikuva (Q)
  • marker (M)

PLC loeb programmi iga tsükli alguses sisendite olekud ja salvestab need sisendite protsessikuvasse (PII). Edasi määratakse programmi täitmisel väljundi olekud ja salvestatakse väljundite protsessikuvasse (PIQ). Programmi iga tsükli lõpus edastatakse saadud tulemused (väljundite väärtused) signaalimoodulitele, et teostada reaalselt programmi käigus saadud tulemused. Nende poole pöördutakse kaas I või Q tähtede abil.

Marker (mälubitt) ehk globaalset mälupiirkonda (M) kasutatakse muutujate väärtuste haldamiseks, mille andmeid kasutatakse erinevates programmiosades ehk siis mitte ainult ühes POU-s vaid mitmes erinevas POU-s. Seda kutsutakse ka markeriks. Markerite poole võivad pöörduda ka teised seadmed (nt operaatori paneel, tööstusarvuti SCADA rakendusega, sagedusmuundur, jne) kui neil on vaja edastada ja/või võtta mingit infot PLC-st.

Vanematel PLC-del (nt Siemens S7-300 seeria PLC) lisandub nendele kolme mälupiirkonnale veel:

  • perifeeria sisend (PI)
  • perifeeria väljund (PQ)
  • kohalik (lokaalne) muutuja (L)
  • taimer (T)
  • loendur (C)

Iga PLC mälupiirkond on jagatud baitideks ja need omakorda bittideks. Programmis kasutatava muutuja poolt enda alla võetav mälupiirkonna suurus võib olla:

  • bitt
  • bait (8 bitti)
  • andmesõna (16 bitti)
  • topelt andmesõna (32 bitti)
  • pikk andmesõna (64 bitti)

Mälupiirkonna suurus sõltub programmis kasutatavatest muutujate andmetüüpidest (vt peatükk "PLC-s kasutatavad andmetüübid") ja CPU-s oleva protsessori võimekusest. Näiteks DINT, DWORD ja REAL tüüpi muutujad võtavad enda alla ühe topelt andmesõna ehk siis 4 baiti. FESTO PLC-d ei ole võimelised töötama muutujaid, mis võtavad enda alla suurema mälupiirkonna kui 32 bitti (4 baiti).

Joonisel 2.13 on esitatud näiteid otsese adresseerimise kohta. Biti suurusega muutuja aadressile viidatakse alati unikaalse sümboliga (absoluutne aadress), mis koosneb:

  • protsendi märgist
  • mälupiirkonna tunnusest (I, Q, M)
  • suuruse tähisest
  • millele järgnevad baidi number
  • punktiga eraldatud biti number

Näiteks sisend %IX28.3, väljund %QX20.1 (joonis 1.13). Mõnikord võib biti suurusega muutuja mälupiirkonna tähise X märkimata jätta.

Joonis 2.13.

Kui adresseerimisel viidatakse mälupiirkonna suurustele nagu bait, andmesõna, topelt andmesõna, pikk andmesõna, siis lisatakse mälupiirkonna tunnuse järgi täht B, W, D või L (nt %IB7, %IW7, %ID7, %IL7) (joonis 2.13). Suuruse mälupiirkonna aadressinumbriks kirjutatakse vastava suuruse mälupiirkonna number (baidi jaoks 0, 1, 2, jne, joonis 2.14). Samamoodi kirjutatakse ka teistele suurustele mälupesa numbrid. Andmesõna, topelt ja pikka andmesõna mälupesa nummerdamist alustadakse ka 0, 1, 2, jne numbritega.

Joonis 2.14.

Joonisel 2.14 on kujutatud digitaalsete andmete jagunemine tüüposadeks ja nende paiknemine mälupiirkondades. Nagu näha, tuleb mälupiirkondade adresseerimisega ja kasutamisega olla ettevaatlik, et mitte kirjutada üle teiste andmete väärtusi. Näiteks markeri mälupiirkondade %MB2 ja %MW1 ei saa kasutada programmis. Kui programmi täitmisel muutub %MB2 väärtus, siis muutub ka %MW1 väärtus, kuigi programmis seda ei soovitud teha. Selle vältimiseks tuleks kasutada markeri mälupiirkonda %MW2, mis ei kasuta mälupiirkonda %MB2. Samuti ei saa kasutada markeri mälupiirkondi nagu %MD0 ja %ML0 (joonis 2.14).

Muutujate deklareerimine sümbolite abil

Et paremini mõista programmi ja selle muutujaid, kasutatakse üha rohkem sümboolset adresseerimist. See võimaldab anda muutujatele tähenduslikud nimed (sümbolid) ja programmi koostamisel ei pea enam mõtlema, millest alates ja kui suure osa mälupiirkonnast peaks mingi muutuja enda alla võtma. Kõik see viimane osa tehakse PLC arenduskeskkondade poolt automaatselt (joonis 2.15). Selline lähenemine on standard IEC 61131-3 järgi lubatud ja CoDeSys kasutab seda.

Joonis 2.15.

Esimene asjana tuleb otsustada, kas deklareeritav muutuja on globaalne või kohalik muutuja (joonises 2.15 valik lahtris Scope). Esimese puhul (lahtris Scope on valitud VAR_GLOBAL) tähendab see, et muutujasse salvestatud väärtusele pääsevad ligi kõik selles ressursis või teistes ressurssides olevad POU-d. Globaalsetele muutujatele pääsevad ligi ka muud seadmed (nt teine PLC, sagedusmuundur, operaatorpaneel) ja rakendused (nt OPC UA server, inim-masin liides). CoDeSys salvestatakse globaalsed muutujad faili üldnimega Globaal Variable List (GVL). Kasutajad saavad ise määrata täpsema faili nime.

Kohalikud muutujad on enamasti POU sisesed muutujad (lokaalsed) ja need deklareeritakse POU-s programmikoodi kohal olevas muutuja deklaratsioonialas (joonis 2.16). PRG-s defineeritud muutujate andmetele on võimalik pääseda ligi ka teistest POU-dest, mis paiknevad samas ressursis. Tabelis 2.1 on esitatud võimalikud muutujate deklaratsioonijaotuste valikud lahtris Scope ja nende kohta käiv kirjeldus. Kõiki deklaratsioonijaotusi ei saa kasutada kõikides POU-des. CoDeSys hoiatab vale jaotise kasutamise eest. Iga deklaratsioonijaotus peab lõppema END_VAR sõnaga, enne kui uus deklaratsioonijaotis algab.

Joonis 2.16.

Jaotuse nimi Jaotus Kirjeldus
Kohalikud muutujad VAR POU-s deklareeritavad kohalikud muutujad, mille väärtusi peetakse meeles. PRG-s olevaid muutujaid saab kasutada ka mujal
Sisendmuutujad VAR_INPUT Muutujad, mis on mõeldud POU-sse tulevate sisendparameetrite talletamiseks. Nende väärtusi ei saa muuta POU-s
Väljundmuutujad VAR_OUTPUT Muutujad, mis on mõeldud POU-st välja antavate väljundparameetrite talletamiseks
Sisend/väljund-muutujad VAR_IN_OUT Muutujad, mis on mõeldud POU-sse tulevate ja samas ka välja antavate parameetrite talletamiseks. Kasutatakse siis, kui tahetakse mingi muutuja väärtusi lugeda (sisend), muuta POU programmis ja väljastada (väljund) POU-st muudetud kujul
Ajutised kohalikud muutujad VAR_TEMP POU-s deklareeritavad kohalikud muutujad, mille väärtused kustutatakse POU täitmise järel. Kasutatakse siis, kui CPU-s ei ole piisavalt mälu
Staatilised kohalikud muutujad VAR_STAT POU-s deklareeritavad kohalikud muutujad, mille väärtusi peetakse meeles ka vahepeal kui POU sees olevat programmi ei täideta
Globaalsed muutujad VAR_GLOBAL Globaalsed muutujad, mida saab kasutada igal pool erinevate ressursside sees

Järgmisena sisestatakse muutuja nimi (joonise 2.15 lahter Name). Sama muutuja nime võib kasutada nii globaalse kui ka kohalike muutujate juures. Sel puhul jääb peale kohalik muutuja, kuigi reaalselt võis programmeerija soovida kasutada globaalset muutujat. Seetõttu võiks jälgida, et globaalsete ja kohalike muutujate nimed ei kattuks.

Soovitav ei ole anda muutujatele liiga pikki nimesid, kuna neid on raksem programmis üles leida ja nende sisestamine võtab rohkem aega. Selle vältimiseks tuleks kirjeldada muutujat täpsemalt kommentaari lahtris (joonise 2.15 lahter Comment).

Andmetüübi lahtris (joonise 2.15 lahter Type) määratakse muutuja andmetüüp ehk siis selles hoitavate andmete tüüp ja muutujate mälupiirkonnas hõivatav ala. Andmetüüpidest räägitakse täpsemalt peatükis "PLC-s kasutatavad andmetüübid".

Muutuja esialgse väärtuse lahtris (joonise 2.15 lahter Initialization) määratakse muutujale esialgne väärtus, mis omistatakse muutujale kui vastava POU käivitub (täidetakse) esimest korda CPU-s. Mälupiirkonna aadress lahtris (joonises 2.15 lahter Address) määratakse muutuja mälupiirkonna absoluutne aadress, kui see on teada. Siia lahtrisse on mõttekas kirjutada PLC sisendite või väljundite aadressid. Mõlemad lahtrid võib jätta täitmata.

Muutuja deklareerimise aknas (joonise 2.15) on veel 3 valikut, mis on kirjeldatud lahti tabelis 2.2.

Nimi Võtmesõna Kirjeldus
Konstant CONSTANT Muutujad defineeritakse konstantidena ja nende väärtust ei saa muuta programmi täitmise käigus. Muutuja esialgne väärtus tuleb anda ette juba muutuja definitsiooni käigus. Kasutatav VAR ja VAR_GLOBAL jaotustes
Säilitatav väärtus RETAIN Muutuja väärtused säilivad pärast PLC välja lülitamist (toitepinge katkemist). Kasutatav VAR, VAR_GLOBAL ja VAR_OUTPUT jaotustega
Püsiv muutuja PRESISTANT Muutuja väärtused säilivad ka pärast programmi (uuesti) laadimist PLC-sse. Neil kehtib ka RETAIN funktsioon. Neid saab lähtestada ainult käsuga Reset origin

Muutujaid on võimalik sisestada ka käsitsi teksti abil kas POU muutujate deklaratsioonialas või failis üldnimega GVL. Muutuja deklareerimisel peavad kindlalt olemas olema muutuja nimi, kooloniga eraldatud andmetüüp ja deklaratsiooni lõputähistamiseks semikoolon (joonisel 2.17 kolmas rida).

Joonis 2.17.

Muutuja deklareerimisel võib ühel real olla rohkem kui ühe muutuja nimi. Need nimed tuleb eraldada üksteisest komaga. Muutuja deklaratsioonirea lõppu võib lisada ka kommentaari. Muutuja mälupiirkonna aadressi, lubatud väärtuste vahemiku ja algväärtuse võib jätta välja. Samas võivad kõik need olemas olla (joonisel 2.17 viimane rida). Mälupiirkonna aadress lisatakse muutuja nime ja andmetüübi vahele. Enne mälupiirkonna aadressi tuleb lisada sõna AT. Muutujale lubatud väärtuste vahemik lisatakse andmetüübi ja algväärtuse vahele sulgude sisse. Väikseim ja suurim lubatud väärtus eraldatakse kahe punkti .. abil. Kõige lõppu, enne semikoolonit lisatakse algväärtus, mis omistatakse muutujale kui näiteks CPU taaskäivitub. Algväärtuse kirjutamist alustatakse := ja seejärel lisatakse algväärtus.

PLC-s kasutatavad andmetüübid

Andmetüübid on andmete klassifikatsioonid, kus määratakse muutujates hoitavate andmete formaat (vorm, mis näitab kuidas mingit reaalset sisu kirjeldavate andmete väärtusi hoitakse), andmete reaalne pikkus bittides ja eelnevast tulenev mälu vahemik. Õigesti valitud andetüübid tagavad andmete optimaalse töötlemise võimalikkuse ja selle, et erinevate muutujate jaoks reserveeritakse sobiv hulk mälu nende deklareerimisel.

Andmetüübid jagunevad üldjoontes kahte leeri:

  • elementaarsed anmdetüübid
  • komplekssed andmetüüpid

Elementaarsed andmetüübid

Elementaarsed andmetüübid on need, mis on määratud standardis IEC61131-3. Siia alla kuuluvad kõik järgmistes tabelites esitatud andmetüübid.

Tabelis 2.3 on esitatud CoDeSys-s kasutatavate biti mustriga andmetüübid. Neid kasutatakse binaarsete andmete talletamiseks. Kõige rohkem kasutatav andmetüüp on BOOL, mis seotakse PLC digitaalsete I/O-dega, PLC ning muude seadmete oleku ja mälu lippudega. Andmetüüpi WORD kasutatakse rohkem PLC analoog I/O-dega seoses.

Tüüp ja kirjeldus Bittide arv Formaat Vahemik ja arvu tähistus
(Väiksemast suurema väärtuseni)
Näide
BOOL (bitt) 1 Tõeväärtus TRUE (signaal “1”)/FALSE (signaal “0”) TRUE
Kahendarv 0 või 1 0
2#0
BOOL#2#0
Kaheksandarv 8#0 või 8#1 8#1
BOOL#8#1
Kuueteist-kümnendarv 16#0 või 16#1 16#1
BOOL#16#1
BYTE (bait) 8 Kahendarv 2#0 .. 2#1111_1111 2#1001_0110
BYTE#2#1001_0110
Märgita kümnendarv 0 .. 255 123
BYTE#123
Kaheksandarv 8#0 .. 8#377 8#123
BOOL#8#123
Kuueteist-kümnendarv 16#0 .. 16#FF 16#10
BOOL#16#10
WORD
(andmesõna)
16 Kahendarv 2#0 .. 2#1111_1111_1111_1111 2#0001_0000_0000
WORD#2#0001_0000_0000
Märgita kümnendarv 0 .. 65_535 61241
WORD#61241
Kaheksandarv 8#0 .. 8#177777 8#150301
WORD#8#150301
Kuueteist-kümnendarv W#16#0 .. W#16#FFFF 16#1000
WORD#16#1000
DWORD
(topelt andmesõna)
32 Kahendarv 2#0 .. 2#1111_1111_1111_1111_1111_1111_1111_1111 2#1000_0001_0001_1000_1011_1011_0111_1111
DWORD#2#1000_0001_0001_1000_1011_1011_0111_1111
Märgita kümnendarv 0 .. 4_294_967_295 34522342
DWORD#34522342
Kaheksandarv 8#0 .. 8#37777777777 8#7753477
DWORD#8#7753477
Kuueteist-kümnendarv DW#16#0000_0000 .. DW#16#FFFF_FFFF 6#00A2_1234
DOWRD#16#00A2_1234
LWORD
(pikk andmesõna)
32 Kahendarv 2#0 .. 2#1111_1111_1111_1111_1111_1111_1111_1111
_1111_1111_1111_1111_1111_1111_1111_1111
2#1000_0001_0001_1000_1011_1011_0111_1111
LWORD#2#1000_0001_0001_1000_1011_1011_0111_1111
Märgita kümnendarv 0 .. 18_446_744_073_709_551_615 3453452234223
LWORD#3453452234223
Kaheksandarv 8#0 .. 8#1777777777777777777777 8#775347732156
LWORD#8#775347732156
Kuueteist-kümnendarv 6#0000_0000_0000_0000 .. 16#FFFF_FFFF_FFFF_FFFF 16#00A2_1234_AF23
LWORD#16#00A2_1234_AF23

Tabelis 2.4 on esitatud CoDeSys-s kasutatavad arv andmetüübid. Ka siin võidakse anda väärtusi ette teistes arvusüsteemides (vt pt "PLC programmis kasutatavad arvsüsteemid"), nagu seda on tehtud tabelis 2.3. Kümnendarvu asemele võib esitada väärtused kas kahend-, kaheksand- või kuueteistkümnendarvuna: nt 120 = 2#0111_1000 = 8#170 = 16#78. Arvu ette kirjutatakse arvusüsteemi baasarv ning nende vahele trellid #. Nagu näha, võib arvude juures kasutada alajoont _, et lugeda ja eraldada erineva tähtsusega arvude kohtasid: nt 100_000 (sada tuhat).

Tüüp ja kirjeldus Bittide arv Formaat Vahemik ja arvu tähistus
(Väiksemast suurema väärtuseni)
Näide
SINT
(Int, 8 bitti)
8 Märgiga väike täisarv -128 .. 127 63
USINT
(Int, 8 bitti)
8 Märgita väike täisarv 0 .. 255 63
INT
(Integer)
16 Märgiga täisarv -32768 .. 32767 1
UINT
(Integer)
16 Märgita täisarv 0 .. 65535 4532
DINT
(Int, 32 bitti)
32 Märgiga topelt täisarv -2147483648 .. 2147483647 -2546854
UDINT
(Int, 32 bitti)
32 Märgita topelt täisarv 0 .. 4294967295 265746
LINT
(Int, 64 bitti)
64 Märgiga pikk täisarv -9223372036854775808 .. 9223372036854775807 -35648882155644
ULINT
(Int, 64 bitti)
64 Märgita pikk täisarv 0 .. 18446744073709551615 9999999999999
REAL
(komakohaga arv)
32 IEEE koma-kohaga arv Ülemine piir: +/-3.402823e+38
Alumine piir: +/-1.175495e-38
1.234567e+4
12345.67
LREAL
(pikk komakohaga arv)
64 IEEE koma-kohaga arv Ülemine piir: +/-1.7976931348623158e+308
Alumine piir: +/-2.2250738585072014e-308
1.0e-3
0.001

Kui arv esitatakse konstandina, siis saab selle ette kirjutada ka andmetüübi nagu seda on tehtud tabelis 2.3. Andmetüübi abil öeldakse mis arvu tüübiga on tegemist (kas märgiga või märgita, täisarv või komakohaga arv) ning palju mälumahtu see võtab enda alla. Samuti võimaldab see esitada arvu õiges formaadis. Järgnevalt on esitatud näide märgita väikese täisarvu konstandi kohta erinevates arvusüsteemides: USINT#120 = USINT#2#0111_1000 = USINT#8#170 = USINT#16#78. Arvu ja arvusüsteemi baasavru ette kirjutatakse andmetüüp, mis eraldatakse trellidega # arvusüsteemi baasarvust.

Komakohaga arvud tuleb esitada punktiga, mitte komaga.

Tabelis 2.5 on esitatud CoDeSys-s kasutatavad ajalised andmetüübid. CoDeSys käsitleb TIME, DATE, TOD ja DT andmetüüpe kui DWORD. TIME ja TOD lühimaks ajaväärtuseks on millisekund. DATE ja DT lühimaks ajaväärtuseks on sekund.

Tüüp ja kirjeldus Bittide arv Formaat Vahemik ja arvu tähistus
(Väiksemast suurema väärtuseni)
Näide
TIME
(IEC-Time)
32 IEC-aeg 1 ms sammudega T#0D0H0M0S0MS .. T#49D17H2M47S295MS T#2D1H1M10S1000MS
TIME#2D1H1M10S100MS
LTIME
(pikk IEC-Time)
64 IEC-aeg 1 ns sammuga LTIME#0D0H0M0S0MS0US0NS .. LTIME213503D23H34M33S709MS551US615NS T#2D1H1M10S1000MS
TIME#2D1H1M10S100MS
DATE
(IEC-kuupäev)
32 IEC-kuupäev 1 päeva sammudega
aasta-kuu-päev
D#1970-01-01 .. D#2106-02-07 D#1994-3-15
DATE#1994-3-15
TOD
(TIME_OF_DAY)
32 Antud päeva kellaaeg, 1 ms sammuga
h:min:sek.ms
TOD#0:0:0.0 .. TOD#23:59:59.999 TOD#13:30:15.250
TIME_OF_DAY#13:30:15.250
DT
(DATE_AND_TIME)
32 Kuupäev kellaajaga
aasta-kuu-päev-tund:minut:sekund
DT#1970-01-01-00:00:00 .. DT#2106-02-07-06:28:15 DT#2020-06-06-15:36:30
DATE_AND_TIME#2020-06-06-15:36:30

Andmetüüpide TIME ja LTIME ajaintervall ehk siis ajaväärtus koosneb järgmistest osadest:

  • D – päev
  • H – tund
  • M – minut
  • MS – millisekund
  • US – mikrosekund
  • NS – nanosekund

Kaks viimast aja mõõtühikut on kasutavad ainult andmetüübi LTIME juures, mida kasutatakse väga kiiretele taimeritele aja väärtuse ette andmiseks. Aja väärtuse kirjutamisel ei pea kirjutama välja kõiki aja mõõtühikuid nagu nt: T#10s, T#10S500MS, T#1M.

Andmetüübi TOD ajaline väärtus koosneb:

  • h – tund
  • min – minut
  • sek – sekund
  • ms – millisekund

TOD ajaline väärtus kirjutatakse välja ilma aja mõõtühikuteta nagu nt TOD#10:56:10.100 (10 tundi, 56 minutit, 10 sekundit ja 100 millisekundit).

Andmetüüp DATE kuupäev kirjutatakse TOD#2020-12-31 ehk siis esimesel kohal on aasta number (aasta 2020), siis kuu number (12 ehk detsember) ja lõpus esitatakse kuupäeva number (31 päev). Väärtuste vahele kirjutatakse sidekriips.

DATE ja TOD väärtuste kokkupanemisel saadakse andmetüübi DT väärtus, millel puudub ajamõõt millisekund. Kahe andmetüübi väärtused pannakse kokku sidekriipsu abil (vt tabel 2.5 viimane rida).

Tüüp ja kirjeldus Bittide arv ühe märgi kohta Lisa bait Formaat Näide
STRING
(sõne)
8 1 ASC II formaadis tekst  ‘see on STRING tekst’
WSTRING
(topelt sõne)
16 2 Unicode formaadis tekst  “see on WSTRING tekst”

Tabelis 2.6 on esitatud CoDeSys-s kasutatavad teksti andmetüübid, mida saab kasutada mingi info esitamiseks kasutajale või masina operaatorile. STRING andmetüübi abil esitatakse teksti, mis on koostatud ASC II formaadis (märkide abil) ehk siis inglise keeles. WSTRING andmetüübis kasutatakse peale ASC II defineeritud märkide ka muid märke (Unicode), mis võimaldab selles olevat teksti esitada erinevates keeltes (nt vene või hiina keeles).

STRING andmetüübi järgi on võimalik määrata teksti pikkus (märkide arv), mida deklareeritud muutujasse saab salvestada. See kirjutatakse nurksulgude sisse nagu see on tehtud siin: str :STRING [30] := 'Tekst'. Kui lubatud teksti pikkus jätta märkimata siis määrab CoDeSys selleks automaatselt 80 märki (kaasa arvatud tühikud). STRING-i muutujasse sisestatava teksti maksimumpikkus on 255 märki. Kui sisestatava teksti pikkus on suurem kui lubatud, siis lõigatakse üleliigne osa tekstist ära. Need piirangud kehtivad ka WSTRING andmetüübi puhul.

Nagu juba mainitud eepool, ei ole osad PLC-d võimelised töötama muutujatega, mille mälumaht on suurem kui 32 bitti. See tähendab et need ei ole võimelised kasutama siin esitatud andmetüüpe, mille bittide arv on 64 (nt LINT, LREAL, LTIME, jne). 2017 aasta seisuga on sellised ABB ja FESTO PLC-d.

Kompleksandmetüübid

Kompleksandmetüübid või ka komposiitandmetüübid on andmetüübid, mis koosnevad elementaarsetest andmetüüpidest. Need on enamasti PLC tootjate või kasutajate poolt loodud andmetüübid, FUN-d ja FB-d.

Joonis 2.18.

Joonisel 2.18 on esitatud CoDeSys poolt kasutatavad üldandmetüübid, mida saab kasutada muutujate üldisemaks deklareerimiseks kasutaja poolt loodud POU-des. See võimaldab muuta loodavad funktsioonid üldisemaks. See tähendab, et loodud funktsiooni saab kasutada rohkem kui ühe kindla andmetüübiga. Näiteks kasutades funktsiooni sisendi andmetüübina ANY_NUM võib sellega siduda kõik muutujad mille elementaarandmetüübid on arvu andmetüübid (tabel 2.4). ANY andmetüübi alla kuuluvad ka TIME ja LTIME, millel ei ole omaette alamklassi.

ARRAY ehk massiiv on kogum sama tüüpi andmetest. Massiiv võib olla ühe, kahe või kolme mõõtmeline (joonis 2.19). Massiivi defineerimisel (massiivi nimi : ARRAY [alumine piir .. ülemine piir] OF andmetüüp;) kirjutatakse nurksulgudesse massiivi alumine piir ja peale kahte punkti .. ülemine piir. Järgmise dimensiooni mõõtmed (alumine ja ülemine piir) eraldatakse eelmise omast koma "," abil. Piiride väärtusi võetakse kui täisarvudena, mis jäävada andmetüübi DINT väärtuste vahemikusse. Alumise piiri väärtus peab olema alati väiksem kui ülemise piiri väärtus. OF teksti järele kirjutatakse andmetüüp, mille massiivi tahetakse luua.

Joonis 2.19.

Näiteks sisaldab Arr_1 :ARRAY [0..4] OF INT andmetüübiga määratud muutuja endas sisuliselt 5 INT tüüpi muutujat, millele vastavad indeksi numbrid 0, 1, 2, 3, 4 (joonis 2.19). Massiivi liikmete poole pöördutakse programmis kirjutades liikme indeksi numbri massiivi muutuja nime taha kantsulgudesse. Näiteks kui operandiks kirjutada Arr_1[2] pöördutakse massiivi nimega Arr_1 liikme poole, mille indeksi number on 2.

Massiivi liikmete poole saab ka dünaamiliselt pöörduda kasutades pöördumisel staatilise indeksinumbri asemel mõnda täisarvtüüpi muutujat. Näiteks Arr_1[indeksinumber], eeldades, et kohalik muutuja indeksinumber (see on pandud muutuja nimeks) on deklareeritud kui täisarv (nt INT, SINT, UINT, USINT). Seda meetodit kasutades tuleb ettevatlik olla ja kontrollida, et indeksinumbrit sisaldava muutuja väärtus ei ületaks massiivi piire (alumine ja ülemine piir). Mitmemõõtmelisel massiivil tuleb kasutada mitut erinevat indeksinumbri muutujat, millest kõige paremal pool oleva muutuja väärtus (indeksinumber) muutub kõige kiiremini.

Massiivi liikmetele saab selle deklareerimisel anda ette algväärtused. Tabelis 2.7 on esitatud näited, kuidas seda teha. Massiivi puhul on võimalik määrata mitmele järjest minevale liikmele sama algväärtus. Selleks kirjutatakse järjest minevate liikmete arv ja sulgude sisse algväärtus mida soovitakse vastavatele massiivi liikmetele omistada: LiikmeteArv(algväärtus). Sulgude sisse võib kirjutada ka mitu algväärtust, mis eraldatakse omavahel komadega. Iga järgnev sisestatav algväärtus omistatakse järgmisele massiivi liikmele. Näiteks 3(1,3,10) antakse järgnevale üheksale (kolm korda tuleb sisestada 3 algväärtust) massiivi liikmele algväärtuseks järgmised väärtused 1, 3, 10, 1, 3, 10, 1, 3, 10.

Näide Kirjeldus
Mass1 : ARRY [0..4] OF INT := [2, 34, 56, 2, 5]; Iga massiivi liikmele antakse ette oma esialgne väärtus
Mass1 : ARRY [0..4, 1..3] OF INT := [2, 34, 13(7)]; Esimesed kaks massiivi liiget saavad erinevad väärtused kui ülejäänud liikmed. Ülejäänud 13 liiget saavad oma väärtuseks sulgudesse kirjutatud väärtuse milleks on 7
Mass1 : ARRY [0..4, 1..3, 1..2] OF INT := [15(0),     13(20), 2, 15]; Esimesed 15 massiivi liiget saavad algväärtuseks 0. Järgmised 13 liiget saavad väärtuse 20. Viimased kaks (29 ja 30) massiivi liiget saavad väärtuseks 2 ja 15

Joonis 2.20.

PLC programmeerijad saavad ise luua uusi andmetüüpe, mida üldiselt kutsutakse kasutaja andmetüüpideks. Kasutaja andmetüübid defineeritakse CoDeSys-s failis DUT võtmesõnade TYPE ja END_TYPE vahele. DUT faili loomisel (joonis 2.20) tuleb anda failile sama nimi, mis tuleb andmetüübiks. See tähendab, et ühes failis saab defineerida korraga ainult ühe andmetüübi. Loodavate andmetüüpide valikuks pakutakse:

  • struktuuri (Structure)
  • loendit (Enumeration)
  • aliast (Alias)
  • ühendit (Union)

Alias võimaldab luua uue andmetüübi, mis baseerub elementaarsetel andmetüüpidel. Nii saab defineerida uue INT andmetüübi, millel on piiratud väärtuste vahemik ning antud uus algväärtus. Väärtuste vahemiku piirmaine on tehtav täisarvu ja biti mustri andmetüüpide juures.

TYPE INT_1 :INT (-60..150) := 2; END_TYPE

Alias võimaldab programmeerijal defineerida massiiviga andmetüüpe, mida saab kasutada POU-s massiivide deklareerimiseks. Seda saab teha assistendi (Input Assistant) abil (nupp >).

TYPE UhendiNimi;
UNION
    a : LREAL;
    b : INT;
END_UNION
END_TYPE

Ühend võimaldab defineerida andmetüübi, mis kasutab ühte ja sama mälupiirkonda erinevate andmetüüpide jaoks. Joonisel 2.21 on defineeritud ühend UhendNimi, mis hõivab suurima komponendi (LREAL) järgi ühise mälupiirkonna. Selleks on 64 bitti. Muutuja UhendNimi.a väärtuse muutmine muudab ka muutuja UhendNimi.b väärtust. Põhjus on selles, et mõlemad kasutavad sama mälupiirkonda oma väärtuste hoidmiseks.

Loend võimaldab defineerida tekstiloendil põhinevat andmetüüpi. Programmeerija sisestab sulgude sisse võimalikud teksti väärtused loodavale andmetüübile, nagu nt:

TYPE NadalaPaev: (Esmaspaev, Teisipaev, Kolmapaev, Neljapaev, Reede, Laupaev, Puhapaev); END_TYPE

Siin on defineeritud andmetüüp NadalaPaev, millel saab olla sitse erinevat päevanime väärtuseks. Muutujale, mis on seotud andmetüübiga NadalaPaev, määratakse algväärtuseks Esmaspaev. Programmeerija poolt koostatud tekstiloendid seotakse programmis täisarvuga. See võimaldab kasutada programmis arvväärtusi tekstide asemel.

  • Esmaspaev saab automaatselt väärtuseks täisarvu 0
  • Teisipaev vastab täisarv 1
  • Kolmapaev vastab täisarv 2
  • Neljapaev vastab täisarv 3
  • Reede vastab täisarv 4
  • Laupaev vastab täisarv 5
  • Puhapaev vastab täisarv 6

CoDeSys tuleb panna linnuke Textlist support ette (joonis 2.20), kui PLC programmis soovitakse kasutada täisarvude kõrval ka loendis olevaid teksti väärtusi.

TYPE Varv: (punane, kollane := 5, roheline := 10) := kollane; END_TYPE

Andmetüübil Varv on olemas algväärtus, mis omistatakse muutujale kui CPU hakkab tööle. Selleks on on kollane. Loendis olevatele tekstiväärtusletele on omistatud järgmised täisarvu väärtused:

  • punane on omistatud väärtus 0, kuna programmeerija pole andnud sellele mingit väärtust
  • kollane on omistatud väärtus 5
  • roheline on omistatud väärtus 10
TYPE Mahuti;
STRUCT
   Pinge : USINT; //Pinge voltides
   Vool  : USINT; //Vool amprites
   Olek  : BOOL//Kas seade on aktiivne
   Temp  : SINT//Temperatuur kraadides
   Taitunud : REAL; //Mahutis oleva vedeliku kogus liitrites 
END_STRUCT
END_TYPE

Struktuur võimaldab defineerida keerulisemat andmestruktuuri, mis võib koosneda erinevatest andmetüüpidest. Neid andmetüüpe vaadeldakse kui alamandmetüüpe struktuuri sees. Kõrval on esitatud struktuuri deklareerimise näide CoDeSys-s (joonis 2.22).

Antud struktuuri nimeks on pandud Mahuti ja selle sisse kuuluvad 5 erinevate andmetüüpidega muutujat. Seda struktuuri võidakse kasutada mingi mahutiga seotud täiturtite ja andurite väärtuste hoidmiseks. Pinge ja Vool näitavad, kui palju pinget ja voolu tarbib mahutis olev küttekeha. Olek näitab kas küttekeha on sees ning Temp näitab mahutis olevat temperatuuri. Taitunud näitab mahutis oleva vedeliku ruumala.

Struktuuri ühe liikme (nt Pinge) poole saab pöörduda POU-s olevas programmis, kui muutuja nimena kasutada Mahuti_1.Pinge. Ehk siis tuleb kirjutada struktuuri muutuja nimi (Mahuti_1) ja punktiga eraldatud alamliikme nimi (Pinge). Selle eelduseks on et muutuja on defineeritud POU muutuja deklaratsioonijaotis järgnevalt:

//POU-s defineeritud muutuja, mille andmetüübiks on struktuur Mahuti
  Mahuti_1 : Mahuti;
Joonis 2.23.

CoDeSys võimaldab olemasolevat struktuuri täiendada ja teha sellest täiesti uue eraldi seisva struktuuri andmetüüp. Selleks tuleb panna linnuke Extends kasti sisse ja valida nimekirjast struktuur, mida täiendada tahetakse (joonis 2.23).

Massiive, struktuure, programmeerija ja elementaarseid andmetüüpe saab omavahel kokku kombineerida tekitades veel komplekssemaid andmetüüpe. Tabelis 2.8 on esitatud programmeerija poolt defineeritud andmetüübid (loend ja struktuur) ja POU-s defineeritud muutuja. Loend ja struktuur on defineeritud eraldi kahes DUT failis.

Näide Kirjeldus
TYPE Olek_1: (SEES, VALJAS) := VALJAS; END_TYPE Loend masina oleku näitamiseks
TYPE Struct_1: //Mootori parameetrid
STRUCT
   Kiirus : UINT;  //Pööret minutis
   Suund : BOOL;   //Mootori pöörelmissuund
   Olek  : Olek_1; //Mootori olek
   Pinge : ARRY [1..3] OF USINT; //Faasipinge
END_STRUCT
END_TYPE
Struktuur mootori parameetrite hoidmiseks. Siia on lisatud ka loendi andmetüüp ja massiiv. Massiiv koosneb kolmest täisarvu elemendist
Mootor : ARRY [0..1] OF Struct_1; //Mootorid POU-s defineeritud massiiv koos viitega struktuuri andmetüübile Struct_1. Selles muutujas hoitakse meeles kahe mootori parameetrid

Joonisel 2.24 on esitatud muutuja Mootor-i struktuur, kui jälgida seda POU-s PLC töö ajal. Antud näites saab mootori nr 0 kiiruse poole pöörduda kasutades muutuja nime Mootor[0].Kiirus ning sama mootori kolmanda faasipinge poole kasutades muutuja nime Mootor[0].Pinge[3].

Joonis 2.24.
Creative Commons Licence
"CoDeSys" is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License .