timohei.net / Opintojaksot
/ Opintojaksot
/ Soveltava ohjelmointi
/ Tentti
/
ST-ohjelma
Tämän sivun ohjelman toiminta pitää pystyä selittämään tentissä. Tehtävänä voi olla myös ohjelmasta poistetun osan täydentäminen. Tausta-aineistoa on luentotallenteissa. Tällä sivulla esitetty ohjelma on esitelty omassa videossaan.
Alla oleva ohjelma on tunneilla tehty toimilohko (Function Block, FB), jolla syötetään kappale Feston jakelusolun (Distribution) makasiinista kääntövarren poimittavaksi. Kyseessä on tapahtumaketju, joka näkyy tässä simulaattorista kuvatussa Youtube-videossa kohdassa 5:12 - 5:15 sekä normaalinopeudella ja hidastettuna oikeasta laitteistosta kuvatussa Youtube-videossa.
Toimilohko koostuu kahdesta pääosasta: muuttujista ja varsinaisesta sovelluksesta.
Muuttujat
Muuttujataulukossa määritellään toimilohkon tulojen ja lähtöjen sekä sisäisten muuttujien nimi (Name-sarake), tyyppi (Type-sarake) ja muistissa pysyminen (Retain-sarake). Kukin näistä voidaan (ja myös pitää) kommentoida (Comment-sarake).
INTERNALS
Nämä ovat toimilohkon sisäisiä muuttujia, jotka ovat vain toimilohkon sisäiseen käyttöön, eivätkä ole käytettävissä toimilohkon ulkopuolella. Muuttujien tila ei säily oletusarvoisesti toimilohkon suorituskerrasta seuraavaan, mutta yksittäiset muuttujat voi asettaa säilyttämään tilansa asettamalla kyseisen muuttujan kohdalle Retain-sarakkeen arvoksi Yes.
Olen nimennyt sisäiset muuttujat alkamaan merkkijonolla int, jotta muuttujan tunnistaa internals-tyyppiseksi ohjelman sisälläkin.
OUTPUTS
Toimilohkon lähdöt ovat toimilohkosymbolin oikeassa reunassa. Asettamalla haluttujen lähtöjen Retain arvoon Yes saadaan lähtö pitämään sinne viimeksi toimilohkosta kirjoitettu arvonsa, vaikka toimilohko ei juuri menossa olevalla suorituskierroksella kirjoittaisi ko. lähtöön mitään.
EXTERNALS
Tässä esimerkissä ei ole käytetty ulkoisia (external) muuttujia. Tässä osiossa näkyvät projektin yhteiset muuttujat, joissa yleensä ovat Omronin logiikoihin kiinteästi ohjelmoidut järjestelmämuuttujat, kuten P_On, P_Off, P_1_s ja niin edelleen.
INTERNALS
Name Type Retain Comment
intVanhaKasky BOOL Yes Edellisen suorituskierroksen iKappaleUlos
intSeuraavaAskel INT No Askel, johon mennään seuraavalla ohjelman
suorituskierroksella
INPUTS
Name Type Retain Comment
iMantaSisalla BOOL No 1 = tökkyrisylinterin mäntä on sisällä ELI tökkyri on
työntänyt palikan ulos
0 = mäntä EI ole sisällä - voi olla matkalla tai perillä
ULKONA sylinteristä
iMantaUlkona BOOL No 1 = tökkyrisylinterin mäntä on ULKONA eli tökkyri on valmis
työntämään uuden palikan ulos makasiinista
0 = mäntä EI ole ulkona - voi olla matkalla tai perillä
sylinterin SISÄLLÄ
iKappaleUlos BOOL No 1 > pukkaa kappale ulos0 > vedä tökkyri pois makasiinin alta
OUTPUTS
Name Type Retain Comment
oAskel INT Yes Aktiivisen askeleen numero. 0 = sekvenssi ei ole käynnissä
oKappaleUlos BOOL No 1 > kappale työnnetään makasiinista ulos (mäntä vedetään
sisään)
0 > tökkyri vedetään makasiinin alta pois ja uusi kappale
pääsee putoamaan tökättäväksi (mäntä työnnetään ulos)
oOk BOOL No 1 = annettu toimenpide suoritettu
0 = toimenpide kesken
oOdottaa BOOL Yes Lähtö valvonta-aikahäytystä varten
Sovellus
(* FB KappaleMakasiinista
Toimilohko saa käskyn pääohjelmasta tulon iKappaleUlos kautta, jolloin:
a) Nollataan oOk ja oOdottaa
b) Toimilohko vetää tökkyrin alkuasentoon nollaamalla lähdön oKappaleUlos [*]
c) Odotetaan rajatietoa iMantaUlkona [*]
d) Toimilohko tökkää kappaleen ulos (oKappaleUlos > 1) [*]
e) Odotetaan rajatietoa iMantaSisalla [*]
f) Toimilohko palauttaa tökkyrin takaisin (oKappaleUlos > 0) [*]
g) Odotetaan rajatietoa iMantaUlkona [*]
h) Toimilohkon lähtö oOk asetetaan ykköseksi
i) Askelnumero nollataan merkiksi siitä, että sekvenssi on suoritettu loppuun
[*] oOdottaa pidetään ykkösenä, kunnes etenemisehto toteutuu *)
IF iKappaleUlos AND NOT intVanhaKasky THEN (* iKappaleUlos tuli juuri päälle *)
intSeuraavaAskel:= 1; (* Käynnistetään sekvenssi *)
END_IF;
IF oAskel = 1 THEN (* Askel 1 *)
oOk:= FALSE; (* Nollataan oOk-lähtö *)
oOdottaa:= FALSE; (* Nollataan oOdottaa-lähtö *)
intSeuraavaAskel:= 2; (* Edetään askeleeseen 2 *)
END_IF;
IF oAskel = 2 THEN (* Askel 2 *)
oKappaleUlos:= FALSE; (* Pukataan mäntä ulos *)
oOdottaa:= TRUE; (* Aktivoidaan valvonta-aika *)
IF iMantaUlkona THEN (* Kun mäntä on perillä ulkona, *)
oOdottaa:= FALSE; (* nollataan aikavalvonta ja *)
intSeuraavaAskel:= 3; (* edetään askeleeseen 3 *)
END_IF;
END_IF;
IF oAskel = 3 THEN (* Askel 3 *)
oKappaleUlos:= TRUE; (* Pukataan kappale ulos *)
oOdottaa:= TRUE; (* Aktivoidaan valvonta-aika *)
IF iMantaSisalla THEN (* Kun mäntä on perillä sisällä,*)
oOdottaa:= FALSE; (* nollataan aikavalvonta ja *)
intSeuraavaAskel:= 4; (* edetään askeleeseen 4 *)
END_IF;
END_IF;
IF oAskel = 4 THEN (* Askel 4 *)
oKappaleUlos:= FALSE; (* Pukataan mäntä ulos *)
oOdottaa:= TRUE; (* Aktivoidaan valvonta-aika *)
IF iMantaUlkona THEN (* Kun mäntä on perillä ulkona, *)
oOdottaa:= FALSE; (* nollataan aikavalvonta ja *)
intSeuraavaAskel:= 5; (* edetään askeleeseen 5 *)
END_IF;
END_IF;
IF oAskel = 5 THEN (* Askel 5 *)
oOk:= TRUE; (* Asetetaan oOk-lähtö *)
intSeuraavaAskel:= 0; (* Lopetetaan sekvenssi *)
END_IF;
oAskel:= intSeuraavaAskel; (* Näytetään askelnumero ulos *)
intVanhaKasky:= iKappaleUlos; (* iKappaleUlos-tila talteen *)
(* nousevan reunan ilm. varten *)