Typy funkcji

typy-funkcji

Dzisiaj podam Ci najbardziej fundamentalną wiedzę, którą powinieneś opanować w 100%. Pobieżne przeczytanie tego wpisu spowoduje, że przeszkodzisz sobie w dalszej nauce.

Typy funkcji

Przy okazji tworzenia pierwszych projektów pisaliśmy kod w bloku organizacyjnym OB1 zwanym też Main. To jest blok, od które sterownik PLC zaczyna wykonywanie instrukcji. Jeżeli tego bloku nie ma, to tak naprawdę sterownik będzie w stanie bezczynności. Graficzne przedstawienie projektu z blokiem OB1 znajduje się poniżej

program-liniowy

Jak widzisz, na blok OB1 bezpośrednio oddziałuje część sprzętowa w sterowniku PLC. W tym bloku OB1 można napisać wszystkie instrukcje, które realizują postawione zadanie. Instrukcje są wykonywana jedna po drugiej czyli linia po linii. Po wykonaniu ostatniej następuje przeskok do pierwszej i sytuacja się w nieskończoność (aż do wyłączenia zasilania dla sterownika).

Załóżmy, że sterownik kontroluje dwa silniki. W takim wypadku w bloku Main musimy napisać kod do obsługi tych silników. Jak zapewne się domyślasz, ten kod będzie się powtarzać. Dla każdego z nich może być ustawiona inne prędkość oraz silnik jest uruchamiany za pomocą innego wyjścia w sterowniku. Jednak idee kontroli każdego z nich jest taka sama. W przypadku zmian w sposobie kontroli silników, to należy poprawić kod w dwóch miejscach. Dwa silniki to modyfikacja w dwóch miejscach. A co by się stało, gdyby w Twoim projekcie było np. osiem silników? Wówczas ewentualne zmiany trzeba przeprowadzać aż w ośmiu miejscach. Jak pewnie zauważyłeś, nie jest to wygodne.

Więc aby ułatwić życie programiście, to powstały funkcje. Służą one krótko mówiąc do wykonywania powtarzających się zadań. W naszym przykładzie z silnikami trzeba byłoby napisać tylko jedną funkcje, która później byłaby wywołana kilkukrotnie (tyle razy ile jest silników). Każda z funkcji byłaby oczywiście parametryzowana, aby silniki mogły działać w niezależny sposób. W takim rozwiązaniu ewentualne zmiany są proste, ponieważ trzeba zmodyfikować kod w jednym miejscu, czyli w naszej funkcji.

Jeżeli mamy napisaną już funkcje kontrolującą silniki oraz w projekcie wykorzystujemy dwa silniki, to graficzna reprezentacja tego projektu została przedstawiona poniżej

program-modułowy

W tym wypadku będą wykonywane instrukcje z bloku Main. Gdy pojawi się wywołanie funkcje dla pierwszego z silników, wówczas nastąpi skok do kodu tej funkcji oraz jego realizacja (blok FC na górze) zgodnie z parametrami przekazanymi do tej funkcji. Po wykonaniu wszystkich instrukcji z tej funkcji następuje powrót do bloku Main. W tym momencie są wykonywane dalsze instrukcje. Gdy pojawi się wywołanie funkcje dla drugiego z silników, wówczas nastąpi skok do kodu tej funkcji (blok FC na dole) i wykonanie instrukcji, które się w nim znajdują z uwzględnieniem przekazanych parametrów.

Można inaczej powiedzieć, że kod programu (instrukcje) napisany w funkcji jest umieszczony gdzieś w pamięci sterownika. Dzięki temu, że jest to blok, to sterownik wie, że one stanowią całość. Przez to, że do funkcji przekazujemy parametry (jakieś wartości), to kod uwzględnia je i operuje na tych wartościach.

Stosowanie funkcji upraszcza projektowanie oraz implementację programu użytkownika. Jednak zalety stosowania funkcji widać szczególnie podczas wyszukiwania błędów (tz. debugowanie). Ta tematyka była również poruszana przy inżynierii oprogramowania oraz praktykach dobrego programowania.

Rodzaje funkcji

Dzięki funkcjom program można podzielić na odpowiednią liczbę sekcji (pewnego rodzaju modułów) w zależności od potrzeb. W ten sposób struktura całej aplikacji jest już modułowa. Właśnie w taki sposób należy pisać kod programu.

W przypadku sterownika S7-1200 (jak również innych sterowników firmy Siemens) można wyróżnić kilka typów (rodzajów) funkcji. Te rodzaje są niezależne od języka, w jakim będzie pisany kod programu. Przy tworzeniu funkcji nie zależnie od jej typu trzeba nadać jej nazwę. Ta nazwa musi być niepowtarzalna w całym projekcie (sugeruję nie używać polskich znaków oraz nie używać spacji). Jeden z typów funkcji już poznałeś oraz miałeś okazje dodać do projektu.

Organization block – blok organizacyjny OB

Pierwszy z nich to blok organizacyjny czyli organization blok lub w skrócie OB. Do tej pory był wykorzystywany właśnie ten typ, czyli OB1 (blok nieskończonej pętli programowej) nazywany również Main. Dodawałeś już ten blok do projektu poprzez okno Add new block.

blok-organizacyjny

Okno Add new block służy do dodawania każdego z dostępnych typów funkcji do projektu oraz określenia, w jakim języku będzie pisany kod programu w tej funkcji. W projekcie wykorzystujemy blok Program cycle. Uruchomieniem bloku OB zajmuje się hardware w sterowniku PLC. Programista nie ma wpływu na to, kiedy uruchomi się blok (są sterowane zdarzeniami). Można więc powiedzieć, że jest to pewnego rodzaju interfejs pomiędzy systemem operacyjnym sterownika (tz. firmwarem) a programem użytkownika.

Jak widzisz, jest kilka typów samych bloków organizacyjnych. W skrócie możne je podzielić na:

startowe – jest to blok Startup. Instrukcje umieszczone w tym bloku są wykonywane zawsze tylko raz tuż po włączeniu zasilania do sterownika lub po restarcie sterownika (przejście z trybu RUN do STOP i ponownie do RUN),

czasowe – kod znajdujący się w bloku tego typu zostaje wykonany jednokrotnie o ustalonym dniu i czasie (blok Time of day) lub jest wykonywany cyklicznie o określonym interwale czasowym (np. co 1 sekunde). Bloków cyklicznych (Cyclic interrupt) może być kilka w projekcie.

diagnostyczne – sterownik zaczyna wykonywać instrukcje znajdujące się w tym bloku, gdy pojawi się błąd (np. za długi czas wykonywania kodu programu w innych blokach (Time error interrupt)). Dostępne są też bloki diagnostyczne, za pomocą których można pobrać informacje diagnostyczne z innych urządzeń,

sprzętowe – gdy pojawi się specyficzne zdarzenie (np. zbocze narastające na wejściu cyfrowym), wówczas następuje przejście do odpowiedniego bloku OB powiązanego z obsługą tego zdarzenia. Tym blokiem jest Hardware interrupt.

W zależności od potrzeb każdy z tych bloków można dodać do projektu i napisać w nim kod odpowiedzialny za specyficzne zadanie.

Function blok – blok funkcyjny FB

Instrukcje (czyli też wywołania funkcji) są wykonywane cyklicznie. Blok funkcyjny FB należy wykorzystać w przypadku, gdy zadanie w nim zawarte potrzebuje kilku cyklów (kilku obiegów pętli programej). Aby te zadania mogły być zakończone, to przy każdym kolejnym wykonywaniu kodu tej funkcji muszą być pamiętane wartości z poprzedniej iteracji. Dlatego blok FB potrzebuje bloku danych czyli bloku danych skojarzonego właśnie z konkretną funkcją FB. Ten blok danych jest nazywany instance DB. Przechowuje on wszystkie wartości parametrów oraz zmiennych (zmiennych statycznych). Jak już wiesz, blok danych służy do przechowywania danych. Dzięki temu instance DB wszystkie wartości mogą być pamiętane. Ten blok danych jest tworzony podczas wywoływania funkcji FB (w tym momencie następuje właśnie skojarzenie bloku danych z funkcją FB). Jeżeli będziesz potrzebował wywołać kilkukrotnie funkcję FB, to przy każdym wywołaniu trzeba utworzyć nowy blok danych instance DB. Z bloków instance DB powinny korzystać tylko funkcje FB. Z innych miejsc (z innych funkcji lub bloków OB) nie powinieneś odnosić się do danych zawartych w blokach instance DB.

Dodanie bloku funkcyjnego FB do projektu przedstawiono poniżej

funkcja-FB

Do funkcji FB można przekazać parametry. To dzięki możliwości przekazywania funkcji wartości za pomocą parametrów wejściowych, to funkcje mogą wykonywać powtarzające się zadania. Funkcja za pomocą parametrów pobiera do swojego wnętrza odpowiednie wartości. Następnie wykonuje na nich obliczenia zgodnie z napisanym kodem i następnie zwraca za pomocą parametrów wyjściowych wyniki.

Function – Funkcja FC

Funkcje FC również służą do wykonywania standardowych i powtarzających się zadań (np. obliczenia arytmetyczne). Podobnie, jak w przypadku funkcji FB, to funkcja FC też może przyjmować wartości przez parametry wejściowe i wykonywać na nich operacje (np. obliczenia). Wyniki są też zwracane przez parametry.

Dodanie bloku funkcyjnego FB do projektu przedstawiono poniżej

funkcja-FC

Jednak najważniejsza różnica, to do funkcji FC nie tworzy się bloków instance DB. Z tego względu wartości obliczone w poprzedniej iteracji nie są pamiętane w kolejnej.

Parametry funkcji

To właśnie dzięki parametrom funkcje mogą wykonywać powtarzające się zadania. Chociaż jak pamiętasz z praktyk dobrego programowania, nawet jeżeli w chwili obecnej zdanie się nie powtarza, to i tak należy utworzyć funkcję. Może w przyszłości program zostanie rozbudowany i wówczas to zadanie będzie się powtarzać? Dzięki temu będziesz musiał wówczas wykorzystać funkcje, którą już masz przygotowaną.

Jak dodasz do projektu nowe bloki FC oraz FB i przejdziesz do edytora, gdzie pisze się kod to zauważysz na górze sekcję interfejsu. Przedstawia to poniższy rysunek

interfejs-funkcji

W sekcji interejsu tworzy się właśnie parametry. Jak pamiętasz, ta sekcja wygląda inaczej dla bloków organizacyjnych (chociaż kilka rzeczy jest podobnych). Tworzenie każdego z dostępnych typów parametów jest podobne. W kolumnie Name wpisujemy nazwę dla tego parametru. W kolumnie Data typ określamy typ (np. USInt lub Bool) dla naszego parametru. W kodzie programu wszystkie parametry (nazwy parametrów) są poprzedzone znakiem #. Teraz powiem Ci, jakie parametry możemy utworzyć?

Parametry wejściowe

Ten parametr pobiera tylko wartość, która jest przekazywana do funkcji (można powiedzieć, że jest tylko odczyt). Następnie ten parametr w kodzie programu wykorzystujesz, jako odczyt wartości który on aktualnie przechowuje. Nie można do niego przypisywać żadnych innych wartości

Parametr wyjściowy

Wynik obliczeń, który został uzyskany w kodzie funkcji należy zwrócić (czyli przekazać do innego miejsca, którym może być kod z którego dana funkcja jest wywoływana). To jest właśnie realizowane przez parametr wyjściowy. Służy on tylko do zapisu. Nie można (tz. nie powinno się) z niego nic odczytywać.

Parametr Return

Jest on tylko dostępny dla funkcji FC. Jest to także parametr wyjściowy, więc ma takie same cechy charakterystyczne, jak parametr utworzony w Output.

Parametr wejściowo- wyjściowy

Ten parametr, jak sama nazwa wskazuje, to połączenie parametru wejściowego oraz wyjściowego

Zmienne lokalne

W sekcji interfejsu tworzy się zmienne lokalne.

Zmienne tymczasowe

Służą do przechowywania wartości tylko w momencie wykonywania kodu programu (w momencie wywołania funkcji). W kolejnym wywołaniu wartości tych zmiennych wynoszą tyle, ile zostało ustawione w polu Default value. Krótko mówiąc wartość jest inicjalizowana wartością początkową

Zmienne statyczne

Jest dostępna tylko dla funkcji FB. Wartość zmiennej statycznej jest pamiętana cały czas (od momentu włączenia napięcia zasilania dla sterownika). To właśnie dzięki bloku danych nstance DB ta wartość może być pamiętana cały czas

Stałe

W ramach funkcji można utworzyć stałą, która charakteryzuje się tym, że nie można do niej przypisać żadnej wartości. Wartość dla stałej jest ustawiona podczas jej tworzenia. Nazwy dla stałych pisze się zawsze dużymi literami. Stałe utworzone w sekcji interfejsu funkcji są widoczne tylko w obrębie tej funkcji. Czyli w każdym bloku funkcji możesz utworzyć dokładnie taką samą stałą, jeżeli jest tak potrzeba.

Wywołania funkcji

Aby funkcja mogła być wykonana, to należy ją wywołać w bloku OB1 lub innej funkcji, która już jest wywoływana w bloku Main. Wywołanie, to napisanie nazwy funkcji oraz nawiasów. Na końcu piszemy średnik. Przykładowa sekcja interfejsu dla funkcji FB przedstawiono poniżej

parametry-funkcji

Mamy utworzone trzy parametry.

Aby wywołać tą funkcję, to w bloku OB1 piszemy

MyFunctionFB(

Po wpisaniu nawiasu otwierającego pojawi się okno przedstawione poniżej

blok-instance-db

Jest to okno, które służy do utworzenia bloku instance DB. W polu Name jest automatycznie wpisywana nazwa funkcji oraz dodawana końcówka _DB. Ja zawsze dodaję na koniec numer tego bloku (numer z pola Number), czyli w tym wypadku 1. Następnie naciskam OK. Wówczas w bloku OB1 pojawi mi się taki kod

"MyFunctionFB_DB1"(MyInput:=false,
MyOutput=>_usint_out_,
MyInOut:=_int_inout_);

W nawiasie pojawiły się wszystkie parametry, jakie zostały utworzone w sekcji interfejsu tej funkcji. Jak widzisz parametry są oddzielone przecinkiem. Do parametru wejściowego jest dodany operator przypisania, czyli :=. Do parametru wyjściowego jest dodany operator =>. Teraz w miejsca false, _usint_out_, _int_inout_ trzeba wstawić odpowiednie zmienne (np. z jakiegoś globalnego bloku danych lub jakiś tag z tablicy PLC tags). Należy pamiętać, aby typy się zgadzały.

W przypadku wywołania funkcji FC sytuacja jest analogiczna. Różnica polega na tym, że nie trzeba tworzyć bloku instance DB.

Najłatwiej wywołać funkcje FC wpisując jej nazwę oraz nawias otwierający i zamykający i na końcu umieścić średnik. Następnie kursor myszki należy mieścić pomiędzy nawiasami i z klawiatury nacisnąć kombinację klawiszy CTRL+SHIFT+SPACJA. Dzięki temu nie trzeba ręcznie wpisywać wszystkich parametrów.

//————-

Kurs-wideo-CZPP

Więcej w kursie wideo: Chcę zostać programistą PLC

Nagrania są dostępne w wersji online jak również na płytach DVD. Napisz mailem, jaką wersje wybierasz.

Podziel się tym wpisem na:
  • Facebook
  • Google Bookmarks
  • Twitter
  • Wykop

Komentarzy

  1. Sebastian

    Najlepszy cykl artykułów o siemensie, jaki miałem okazję czytać.
    Życzę dalszego zaangażowania, wiedza którą Pan przekazuje jest bardzo intuicyjna, a zarazem konkretna i kluczowa do programowania. Czekam na kolejne wpisy.
    Pozdrawiam

    Powtórz

Pozostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Możesz użyć następujących tagów oraz atrybutów HTML-a: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>