W poprzednim wpisie poznałeś teorie odnośnie struktur oraz sposobu ich tworzenia oraz wykorzystywania w kodzie programu. Jednak w tym przykładzie trudno zobrazować to. Tak, jak pisałem ostatnio, strukturę wykorzystamy w projekcie naszej linii technologicznej. Dzisiaj będziemy dalej rozwijać ten projekt.
Struktury – Sterowanie silnikiem
Jak zapewne pamiętasz, struktury tworzy się w PLC data types. Dodajemy do projektu nową strukturę o nazwie stt_Motor. Należy utworzyć cztery pola, które zostały przedstawione na poniższym rysunku
Zgodnie z definicją struktury, należy ją wykorzystać do opisu złożonych obiektów. Takim obiektem może być właśnie silnik. W naszym przypadku wszystkie pola są tego samego typu. Jednak typy mogą być dowolne.
Pierwsze pole Run będzie wykorzystane do uruchamiana lub zatrzymywania pracy silnika. Natomiast kierunek, w jakim silnik ma zostać uruchomiony zależy od pół DirectionForward oraz DirectionBackward. Ostatnie pole Error będzie przechowywać informacje o błędzie, co powinno spowodować zatrzymanie silnika.
Obsługa pracy silnika
Mamy przygotowaną strukturę opisującą pewne stany silnika. Nasza linia składa się z trzech silników. Dla każdego z nich trzeba przetrzymać dane na temat jego stanu. Utworzona struktura, to nowy typ, który można nadać tworzonej zmiennej.
Teraz utworzymy takie zmienne. Silnik to jest sprzęt, więc tam umieścimy blok danych, czyli w warstwie sprzętowej nazwanej Hardware.
Do warstwy Hardware dodajemy nowy blok danych o nazwie HD_MotorData. Tworzymy w nim trzy zmienne typu stt_Motor, którym nadajemy nazwy T1, T2 oraz T3.
Teraz do tej samej warstwy dodajemy funkcję typu FC o nazwie HD_MotorControl. Funkcja będzie zajmowała się kontrolą pracy silnika, czyli przetwarzaniem danych ze struktury i uruchamianiem silnika. W sekcji interfejsu tworzymy parametr wejściowy (Input) typu stt_Motor o nazwie MotorData. Będą nam potrzebne też dwa parametry wyjściowe (Output) typu Bool o nazwach StartMotorForward oraz StartMotorBackward. Następnie dodajemy następujący kod, który przedstawiono poniżej
IF (#MotorData.Run = TRUE AND #MotorData.DirectionForward = TRUE) THEN #StartMotorForward := TRUE; #StartMotorBackward := FALSE; ELSIF (#MotorData.Run = TRUE AND #MotorData.DirectionBackward = TRUE) THEN #StartMotorForward := FALSE; #StartMotorBackward := TRUE; ELSE #StartMotorForward := FALSE; #StartMotorBackward := FALSE; END_IF;
Pierwsza instrukcja warunkowa IF sprawdza, że jest ustawione żądanie uruchomienia silnika oraz czy silnik powinien zostać uruchomiony w kierunku do przodu. Jeżeli ten warunek w nawiasie jest spełniony, to silnik jest uruchomiony w kierunku do przodu (w kierunku do odbiornika R3).
Druga instrukcja warunkowa IF działa na analogicznej zasadzie. W tym wypadku jest sprawdzane, czy silnik powinien poruszać się w stronę odbiornika R1.
Aby silnik mógł być uruchomiony, to funkcję HD_MotorControl() trzeba wywołać dla każdego z silników, czyli trzy razy. Te funkcje wywołamy w funkcji HD_ClassHardware(). Kod przedstawiono poniżej
"HD_MotorControl"(MotorData := "HD_MotorData".T1, StartMotorBackward => "T1_Back", StartMotorForward => "T1_Forward"); "HD_MotorControl"(MotorData := "HD_MotorData".T2, StartMotorBackward => "T2_Back", StartMotorForward => "T2_Forward"); "HD_MotorControl"(MotorData := "HD_MotorData".T3, StartMotorBackward => "T3_Back", StartMotorForward => "T3_Forward");
Po wywołaniu funkcji należy przypisać do parametrów odpowiednie zmienne. Parametrowi MotorData przypisana zmienną T1 z bloku danych HD_MotorData. Funkcja HD_MotorControl() ma również dwa parametry wyjściowe, które są powiązane z tagami. Parametr StartMotorBackward jest powiązany z nazwą symboliczną T1_Back. Jeżeli silnik powinien zostać uruchomiony w kierunku do odbiornika R1, to parametr StartMotorBackward zwraca wartość 1, która jest przypisywana do T1_Back. Analogicznie parametr StartMotorForward zwraca wartość 1, jeżeli transporter T1 powinien zostać uruchomiony w kierunku do odbiornika R3. Wówczas do tagu T1_Forward jest przypisywana wartość 1.
W podobny sposób działają wywołania funkcji HD_MotorControl() dla transporterów T2 oraz T3.
Testowanie kodu
Przechodzimy do funkcji LOG_ClassLogic(). Napiszemy kilka dodatkowych linijek kodu, aby przetestować działanie struktur. Kod przedstawiono poniżej
IF ("MAN_LineMode".StartLine) THEN IF ("MAN_LineMode".Manual) THEN //TODO MODE manual ; ELSIF ("MAN_LineMode".Auto) THEN //TODO MODE AUTO "Emitter" := TRUE "R3" := TRUE; //T1 "HD_MotorData".T1.Run := TRUE; "HD_MotorData".T1.DirectionForward := TRUE; //T2 "HD_MotorData".T2.Run := TRUE; "HD_MotorData".T2.DirectionForward := TRUE; //T3 "HD_MotorData".T3.Run := TRUE; "HD_MotorData".T3.DirectionForward := TRUE; END_IF; ELSE //TODO line STOP or LINE ERROR "Emitter" := FALSE; "R3" := FALSE; //T1 "HD_MotorData".T1.Run := FALSE; //T2 "HD_MotorData".T2.Run := FALSE; //T3 "HD_MotorData".T3.Run := FALSE; END_IF;
Test wykonany w trybie automatycznym, więc umieszczamy kod w miejscu odpowiedzialnym za wykonanie instrukcji dla trybu Auto. W linii 7 uruchamiamy podajnik palet. Następnie uruchamiamy odbiornik R3, aby palety były odbierane z linii. Do każdej ze zmiennych w bloku danych HD_MotorData przypisujemy do pól Run oraz DirectionForward wartości True. Dzięki temu transportery zostaną uruchomione.
Zatrzymanie linii, to przejście do trybu Stop. Więc w tym miejscu napisano kod zatrzymujący podajnik palet oraz odbiornik palet. W linii 21 i 22 przypisano do tagów Emitter oraz R3 wartości False. Do pól Run przypisano również wartości False, aby zatrzymać silniki.
Pozostało nam skompilować kod programu i wgrać do sterownika. Następnie przechodzimy do Factory IO i uruchamiamy symulację naciskając przycisk Play. Wybieramy tryb automatyczny naciskając przycisk Auto i uruchamiamy linie naciskając przycisk Start. W tym momencie palety zaczynają pojawiać się na linii i jechać w kierunku odbiornika R3. Naciśniecie przycisku Stop powoduje zatrzymanie linii. Palety zostają na linii.
Pisanie kodu oraz uruchomienie linii zostało przedstawione na poniższym nagraniu.
Praca domowa
Napisz tymczasowy kod programu, aby w trybie manualnym palety jechały w kierunku odbiornika R1. Podajnik palet (Emitter) oraz odbornik R3 powinny być wyłączone w trybie manualnym.
//———-
Licencja FACTORY I/O wypożyczona dzięki uprzejmości firmy Encon-Koester Sp. z o. o. Sp. K.
Encon-Koester Sp. z o. o. Sp. k.
ul. Gagarina 4
54-620 Wrocław
Kurs wideo
Więcej na temat programowania w języku SCL znajdziesz w kursie Sterownik PLC w praktyce:
Witam. Na wstępie gratuluje poradnika. Jest bardzo dobry.
Postanowiłem napisać, ponieważ mam problem z „Zadaniem domowym”:) Program piszę w taki sposób, że przerabiam kod SCL z tej strony na LAD (w ten sposób nie jest to bezmyślne przepisywanie całego programu tylko więcej główkowania). Mój problem polega na tym, że dodałem drabinkę odpowiedzialną za tryb manual do bloku LOG_ClassLogic i poszczególne gałęzie z wyjściami działają mi poprawnie, jednak w bloku HD_ClassHardware na wyjściu funkcji HD_MotorControl oba kierunki przyjmują wartość TRUE. W konsekwencji na wszystkich wyjściach (%Q0.7, %Q1.0 itd) mam sygnał i transporter stoi. W automacie jest ok. Trochę zamotałem ale nie wiem jak to dokładnie opisać
Witam,
Wyślij mi printscreena na maila.