Języki programowania dla sterowników PLC

controlbyte.pl 3 miesięcy temu

W tym artykule nie będę dogłębnie wnikał w normę IEC opisującą graficzne i tekstowe języki programowania dla sterowników, bo takich tekstów jest dużo w czasopismach branżowych czy internecie. Bardziej zależy mi, żeby w prosty sposób przybliżyć Ci jakie języki masz do dyspozycji podejmując się programowania systemu automatyki z użyciem sterownika PLC. Do dyspozycji mamy języki graficzne i o ile nie miałeś styczności z automatyką to od tych języków warto rozpocząć swoją przygodę! Następnie koniecznie trzeba zainteresować się językami tekstowymi (przyśpiesza to realizację projektów).

Języki programowania dla sterowników PLC

IEC 61131-3 to międzynarodowa norma dotycząca programowania w przemyśle automatyki. Została opracowana przez Międzynarodową Elektrotechniczną Komisję Normalizacyjną (IEC) i określa standardy dotyczące języków programowania, środowisk programistycznych i interfejsów użytkownika dla systemów automatyki przemysłowej. Norma ta zapewnia interoperacyjność różnych systemów automatyki poprzez ustanowienie wspólnych standardów dla programowania i komunikacji. Dzięki temu umożliwia łatwe tworzenie i integrację różnych systemów automatyki w jedną, spójną całość. Norma IEC 61131-3 jest szeroko stosowana w przemyśle automatyki przemysłowej na całym świecie.

Norma IEC 61131-3 określa pięć języków programowania dla systemów automatyki przemysłowej. Są to:

  • Język LD (Ladder Diagram), który umożliwia tworzenie programów dzięki schematów drabinkowych. Jest to język popularny wśród elektryków i znany z jego prostoty i intuicyjności.
  • Język FBD (Function Block Diagram), który pozwala tworzyć programy dzięki bloków funkcyjnych. Jest to język skierowany do inżynierów elektryków i elektroników.
  • Język SFC (Sequential Function Chart), który umożliwia tworzenie programów dzięki diagramów sekwencyjnych. Jest to język skierowany do inżynierów procesów i automatyków.
  • Język ST (Structured Text), który pozwala tworzyć programy dzięki strukturalnego języka tekstowego. Jest to język skierowany do programistów i inżynierów informatyków.
  • Język IL (Instruction List), który umożliwia tworzenie programów dzięki list instrukcji. Jest to język skierowany do elektryków i elektroników.

Wszystkie te języki są zgodne z normą IEC 61131-3 i mogą być stosowane do programowania sterowników PLC w aplikacjach przemysłowych. Każdy z tych języków ma swoje własne zalety i wady, dlatego wybór odpowiedniego języka zależy od indywidualnych potrzeb i preferencji programisty.

Język Ladder

Mówiąc żargonem automatyków (wbrew pozorom taki już istnieje) jest to popularna drabina. W końcu tłumacząc z angielskiego Ladder to drabina 🙂 Zresztą sama nazwa języka jest bardzo słuszna z tego względu, iż patrząc na strukturę programu napisanego w tym języku możemy zauważyć podobieństwo do drabinki. Nie znam dokładnie historii programowania, bo jestem trochę futurystą i nie patrzę w przeszłość, ale prawdopodobnie był to pierwszy język stworzony dla nowych stworzeń na rynku pracy zwanych automatykami. Pierwsi automatycy wyewoluowali z elektryków i ktoś mądry pomyślał, żeby stworzyć język, który będzie podobny do schematu elektrycznego! Mamy tutaj do dyspozycji styki – ze styczników też możemy stworzyć układy automatyki, mamy do dyspozycji cewki – tak jak stycznikach. To oznacza, iż dotychczas osoba tworząca układy automatyki wyłącznie na stycznikach i przy pomocy schematów elektrycznych mogła bezboleśnie przejść na sterowniki PLC.

Oprócz sterownika PLC ktoś mądry musiał jeszcze opracować graficzny interfejs programowania dla użytkowników. Pamiętasz jeszcze system DOS? Ja jestem z pokolenia lat 90-tych i akurat jeszcze przez chwilę miałem z tym kontakt (nawet można było odpalić tam grę). o ile pamiętasz to wiesz, iż GUI w DOSie było bardzo ubogie, ale to tam powstały pierwsze systemy programowania dla PLC, dlatego wykorzystano znaki, które były dostępne na klawiaturze – kreski, nawiasy, myślniki etc. To wystarczyło, żeby w graficzny sposób przedstawić styk NO, styk NC, cewkę, timer i resztę podstawowych elementów.

Jeżeli otworzysz sobie nowoczesne oprogramowanie przeznaczone do programowania PLC np.: Codesys 3.5 to zauważysz, iż ta konwencja pozostała do dzisiaj.

Realizacja bramki logicznej OR w języku Ladder

Pamiętam, iż ja też zaczynałem od tego języka i to było po prostu przepisanie wejścia na wyjście PLC, czyli tak naprawdę zapalenie diody dzięki przycisku. Pamiętam tą niesamowitą euforia w momencie gdy podniosłem przełącznik i dioda się zapaliła, a po modyfikacji programu zaczęła migotać. Tak czy siak, język Ladder musi znać każdy automatyk bez znaczenia czy jest starej czy młodej daty – od tego należy zacząć.

W języku Ladder program podzielony jest na tzw. Networki czyli linie programu, które są ponumerowane. Jest to bardzo wygodne rozwiązanie z tego względu, iż możemy podzielić program na sekcje – dużo łatwiej analizować taką strukturę podczas serwisu danej maszyny.

Ciekawostka: największy program napisany w języku Ladder z jakim się spotkałem miał 1200 Networków i nie był podzielony na podprogramy. Była to maszyna importowana z Azji – tam szczególnie upodobali sobie język Ladder. W Europie jest troszkę inne podejście – programy dzieli się na bloki funkcyjne, funkcje, podprogramy – moim zdaniem jest to bardziej czytelne.

Jaki program możesz napisać na początek? Napisz program dla układu gwiazda-trójkąt dla silnika indukcyjnego.

Program napełniania zbiornika z cieczą z wykorzystaniem języka Ladder (TiA Portal)

Język FBD (Funtion Block Diagram)

Kolejny język graficzny, który bardzo często wykorzystywany jest przez automatyków. Analizując składnię języka możemy znaleźć wiele podobieństw do języka Ladder. Występuje tutaj podział na linie programowe czyli Networki. W języku drabinkowym funkcje logiczne realizujemy dzięki odpowiedniego ułożenia elementów takich cewka czy styk. W wypadku FBD korzystamy z odpowiednich bloków funkcji logicznych i w tej sposób budujemy strukturę programu. Co ważne w zależności od producenta sterowników PLC dane języki są lepiej już mniej rozwinięte. Mam wrażenie, iż w Codesys 2.3 FBD jest dużo przyjemniejszy niż Ladder.

Jeżeli będziesz miał okazję programować duże linie technologiczne to zobaczysz, iż większość programów głównych jest napisanych w tym języku. Duże firmy ustalają zwykle pewien standard dla programowania w swoich zakładach. Miałem kolegę, który pracował w wielu fabrykach BMW na całym świecie i wspominał o tym, iż główne programy były pisane właśnie w tym języku. Pamiętaj, iż program główny w większości wypadków powinien być pisany w języku graficznym, dzięki takiego zabiegowi osoba analizująca program podczas np.: awarii maszyny będzie miała łatwiejsze zadanie. Dział utrzymania ruchu pracuje często pos presją czasu i często na nocne zmiany – warto o tym pamiętać 🙂

Przykład programu napisanego w języku graficznym FBD

Język SFC (Sequential Function Chart)

Jest to język głównie dla automatyków zajmujących się automatyką procesową np.: WOD-KAN etc. Oczywiście można stosować go w każdej innej dziedzinie automatyki. Na czym polega programowanie w tym języku. Jest on trochę odmienny od reszty języków. Najważniejsze cechy SFC:

  • program składa się z grafu
  • program podzielony jest na poszczególne kroki – w każdym kroku wykonywane są odpowiednie instrukcje zawarte w blokach. Bloki w każdym kroku mogą być pisane w dowolnym języku np.: LAD, FBD czy ST
  • bloki zawarte w kolejnych krokach zawierają dwie akcje: akcję wejściową, która wykonywana jest tylko raz po aktywacji danego kroku oraz akcję wyjściową, która wykonuje się tylko raz przed wyjściem z danego kroku. Akcje mogą byc pisane w dowolnym języku
  • przed przejściem do kolejnego kroku sprawdzany jest warunek tranzycji po spełnieniu, którego program przechodzi dalej. Tranzycja to inaczej warunek przepływu sterowania

Dla ćwiczeń możesz jak zwykle napisać prosty program dla przejścia dla pieszych – jest to oczywista sekwencja dla zmiany świateł. Inna opcją jest napisanie programu dla stołu obrotowego z wierceniem i smarowaniem materiału wierconego. Ostatnim przykładem może być automat do parzenia kawy 🙂

Przykład programu napisanego w języku sekwencyjnym SFC w środowisku Codesys

Język ST (Structured Text)

Dochodzimy moim zdaniem do jednego z najważniejszych języków programowania dla automatyka czyli do języka ST (Structured Text). Jest to język tekstowy, który składnią do złudzenia przypomina język Pascal. Pewnie mało Ci to mówi, ale to nie ważne – ważne jest to, iż gdy nauczysz się tego języka czas pisania Twoich programów może drastycznie się skrócić.

Z moich doświadczeń wynika, iż program, który wcześniej pisałem w językach graficznych zajmował mi 2x więcej czasu niż napisanie tego samego w języku ST. Powszechnie wiadomo, iż o ile coś robisz szybciej i lepiej tym więcej zarabiasz – uwierz mi, ta reguła szczególnie znajduje zastosowanie u programistów systemów automatyki.

Z moich doświadczeń wynika, iż program, który wcześniej pisałem w językach graficznych zajmował mi 2x więcej czasu niż napisanie tego samego w języku ST. Powszechnie wiadomo, iż o ile coś robisz szybciej i lepiej tym więcej zarabiasz – uwierz mi, ta reguła szczególnie znajduje zastosowanie u programistów systemów automatyki.

Zaletami języka ST są:

  • prostota składni
  • łatwiejsza analiza programu
  • możliwość szybszego programowania

Jeżeli rzucisz okiem na składnię języka ST to gwałtownie zauważysz analogię do języków wysokiego poziomu takich jak : Python, Pascal czy język C. Znajdziemy tu:pętle, instrukcje warunkowe operatory itd. Polecam naukę języka ST osobom zaawansowanym jak i początkującym.

IF iTemperatura < -20 AND iWilgotnosc > 100 THEN (* sprawdź warunek dla temperatury i wilgotności *) xGrzalka := TRUE; (* włącz grzałkę *) xWentylator := TRUE; (* włącz wentylator *) ELSE xGrzalka := FALSE; (* wyłącz grzałkę *) xWentylator := FALSE; (* wyłącz wentylator *) END_IF;

Język IL (Instruction List)

Na temat tego języka nie będę się długo rozwodził, aczkolwiek niektórzy automatycy, którzy serwisują stare maszyny powinni go znać. Ja spotkałem się kilka razy z tym językiem w fabryce Bosh’a, niektóre maszyny pochodziły jeszcze z lat 80-tych. W tej chwili żaden z producentów automatyki nie szkoli ani promuje programowania w tym języku. Programowanie w IL jest to zbyt żmudne. Język IL jest podobny do assemblera – dzięki niemu można było optymalizować/zarządzać pamięcią sterownika PLC. W 21 wieku nie polecam stosowania tego języka – chyba, iż masz inne zdanie to opisz to w komentarzu do tego artykułu.

A czy mogę stosować języki wysokiego poziomu?

Dobry automatyk oprócz języków z normy IEC musi znać także jeden lub kilka języków wysokiego poziomu. Kiedyś nie było to wymagane, ale teraz to podstawa do wejścia w nowe projekty i możliwość automatyzacji pewnych powtarzalnych zadań. Producenci automatyki coraz częściej oferują sygnalizują dodatkowe możliwości płynące ze znajomości języków wysokiego poziomu. Przykładowo: systemem operacyjnym sterowników WAGO jest Linux. Dzięki temu można pisać własne biblioteki w języku C lub C++, a następnie wywoływać je z poziomu Codesys. W przypadku powtarzalnych/skalowalnych projektów jest to świetna opcja do zaoszczędzenia czasu i zaangażowania automatyków ze znajomością języków wysokiego poziomu. Ok, Linux 🙂 to znaczy, iż mogę także pisać skrypty w Pythonie? Oczywiście! Na poziomie systemu operacyjnego sterowników WAGO możesz pisać skrypty obsługujące daną funkcjonalność np.: protokół MQTT i tworzenie plików CSV. Ktoś zapyta: ale po co przecież mogę robić to z poziomu Codesys. Tak, ale niektóre funkcjonalności szybciej napiszemy w Pythonie – pamiętajmy, iż to język wysokiego poziomu z nieskończoną ilością bibliotek do analizy danych, obsługi plików, komunikacji etc. Python w Codesys 3.5 może być także stosowany do automatyzacji pewnych powtarzalnych zadań na poziomie graficznego interfejsu użytkownika GUI tzn. możemy np automatycznie dodać sterownik do projektu, karty I/O, tagi i wiele więcej.

Kolejnym ważnym językiem o którym nie można zapomnieć jest język przeznaczony głównie do pisania makr w Excel czyli Visual Basic. Stary dobry Excel 🙂 Jest to narzędzie niezastąpione w wielu przypadkach. Tabelki, wykresy i własnie możliwość pisania skryptów w VBA dają automatykom rozwiązania, które warto stosować w każdej fazie projektu automatyki. W Excel możemy zrobić wycenę elementów automatyki, dzięki skryptów VBA zrobić swój własny cennik usług lub produktów, widziałem też mini system SCADA napisany w VBA! No i na koniec wspomnę jeszcze o języku C++. Bardzo istotny jeżyk z tego względu, iż u wielu producentów systemów SCADA istnieje możliwość pisania skryptów właśnie w tym języku. Także o ile zależy Ci na poszerzeniu swoich kompetencji automatyka o znajomość systemów SCADA to z pewnością język C++ bardzo Ci w tym pomoże.

Na koniec ciekawostka. o ile byłeś na studiach związanych z automatyką to z pewnością spotkałeś się z takim programem jak Matlab oraz Simulnik. Nie cierpiałem obu programów i miałem z nimi straszne problemu. Do momentu kiedy okazało się, iż dzięki Simulika można zaprogramować sterownik PLC X-20 firmy B&R. Wygląda to w ten sposób, iż cały algorytm sterowania realizujesz po stronie Simulink, nastepnie dzięki odpowiedniej nakładki do systemu Automation Studio generujesz kod programu w języku C i całość wgrywasz do sterownika. Na początku miałem pewne wątpliwości z tym związane, ponieważ cały proces wydawał mi się zbyt skomplikowany (przecież dla sterowników stosujemy drabinkę!), ale okazało się, iż wszystko działa jak należy. Mało tego – nie był to zwykły projekt z załączeniem wyjścia w zależności od wejścia, ale skomplikowany algorytm estymacji pewnych parametrów na podstawie pomiarów prędkości obrotowej silnika i prądu silnika. Rozwiązanie Target to Simulnik firmy B&R stosowane jest głównie przez firmy R&D np.: w lotnictwie lub motoryzacji.

Nasza firma ControlByte idzie z duchem czasu i cały czas poszukujemy nowych możliwości programistycznych na rynku automatyki. Ciekawym rozwiązaniem jest sterownik Finder Opta, który może być programowany w odmianie języka C. Przykładowy kod sterowania rolety w inteligentnym domu poniżej:

/** Home Automation with Opta (Application Note) Name: window_shade_roller_opta.ino Purpose: Open or close a roller window shade based on a programmed scenario @author: José Bagur and Taddy Chung @version: 1.3 (15/02/23) */ // Libraries used in the sketch #include <WiFi.h> #include <NTPClient.h> #include <mbed_mktime.h> // Wi-Fi network credentials char ssid[] = "YOUR_WIFI_SSID"; char pass[] = "YOUR_WIFI_PASSWORD"; int status = WL_IDLE_STATUS; // NTP client configuration and RTC update interval WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "pool.ntp.org", -6*3600, 0); unsigned long interval = 60*30*1000UL; unsigned long lastTime = 0; // Programmed scenarios for opening or closing the shade int local_hour; int local_minutes; int programmed_hour_1 = 6; int programmed_hour_2 = 18; int programmed_minutes_1 = 0; int programmed_minutes_2 = 0; bool shade_state = false; // Opta initialization void setup() { Serial.begin(9600); while (!Serial) { ; } delay(5000); // Attempt Wi-Fi connection while (status != WL_CONNECTED) { Serial.print("- Attempting to connect to WPA SSID: "); Serial.println(ssid); status = WiFi.begin(ssid, pass); delay(500); } // Display Wi-Fi network information Serial.println(); Serial.println("- NETWORK INFORMATION"); Serial.print("- You're now connected to the network "); printCurrentNet(); printWifiData(); delay(5000); // NTP client object initialization and time update, display updated time on the Serial Monitor timeClient.begin(); updateTime(); // Digital inputs, digital outputs, built-in LEDs initialization pinMode(LED_D0, OUTPUT); pinMode(LED_D1, OUTPUT); pinMode(D0, OUTPUT); pinMode(D1, OUTPUT); pinMode(A2, INPUT); pinMode(A3, INPUT); // Stop the roller window shade from moving digitalWrite(LED_D0, LOW); digitalWrite(LED_D1, LOW); stop_shade(); } void loop() { // Check and verify if it's time to move up or down the roller window shade local_hour = getLocalHour(); local_minutes = getLocalMinutes(); if (programmed_hour_1 == local_hour && programmed_minutes_1 == local_minutes) { Serial.println("- Rolling down shade!"); roll_down_shade(); } else if (programmed_hour_2 == local_hour && programmed_minutes_2 == local_minutes) { Serial.println("- Rolling up shade!"); roll_up_shade(); } else { stop_shade(); } // Update time client periodically unsigned long currentTime = millis(); if (currentTime - lastTime >= interval) { updateTime(); lastTime = currentTime; } } /** Updates Opta's internal RTC using a NTP server @param none @return none */ void updateTime() { Serial.println(); Serial.println("- TIME INFORMATION:"); timeClient.update(); const unsigned long epoch = timeClient.getEpochTime(); set_time(epoch); Serial.print("- UTC time: "); Serial.println(getLocalTime()); Serial.print("- Unix time: "); Serial.println(epoch); } /** Retrieves Opta's RTC time @param none @return Opta's RTC time in hh:mm:ss format */ String getLocalTime() { char buffer[32]; tm t; _rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT); strftime(buffer, 32, "%k:%M:%S", &t); return String(buffer); } /** Retrieves Opta's RTC hour @param none @return Opta's RTC hour (int) */ int getLocalHour() { int hour; tm t; _rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT); hour = t.tm_hour; return hour; } /** Retrieves Opta's RTC minutes @param none @return Opta's RTC minutes (int) */ int getLocalMinutes() { int minutes; tm t; _rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT); minutes = t.tm_min; return minutes; } /** Rolls down the shade @param none @return none */ void roll_down_shade() { while(digitalRead(A2) == LOW) { Serial.println("- ROLLING DOWN SHADE!"); digitalWrite(D0, HIGH); digitalWrite(D1, LOW); digitalWrite(LED_D0, HIGH); digitalWrite(LED_D1, LOW); } Serial.println("- STOP SHADE!"); digitalWrite(LED_D0, LOW); digitalWrite(LED_D1, LOW); stop_shade(); shade_state = false; } /** Rolls up the shade @param none @return none */ void roll_up_shade() { while(digitalRead(A3) == LOW) { Serial.println("- ROLLING UP SHADE!"); digitalWrite(D0, LOW); digitalWrite(D1, HIGH); digitalWrite(LED_D0, LOW); digitalWrite(LED_D1, HIGH); } Serial.println("- STOP SHADE!"); digitalWrite(LED_D0, LOW); digitalWrite(LED_D1, LOW); stop_shade(); shade_state = true; } /** Stops the shade from moving up or down @param none @return none */ void stop_shade() { digitalWrite(D0, LOW); digitalWrite(D1, LOW); } /** Prints local Wi-Fi network IP and MAC address @param none @return none */ void printWifiData() { // Display network IP IPAddress ip = WiFi.localIP(); Serial.print("- IP address: "); Serial.println(ip); // Display MAC address byte mac[6]; WiFi.macAddress(mac); Serial.print("- MAC address: "); Serial.print(mac[5], HEX); Serial.print(":"); Serial.print(mac[4], HEX); Serial.print(":"); Serial.print(mac[3], HEX); Serial.print(":"); Serial.print(mac[2], HEX); Serial.print(":"); Serial.print(mac[1], HEX); Serial.print(":"); Serial.println(mac[0], HEX); } /** Prints connected Wi-Fi network SSID, BSSID, RSSI and encryption type @param none @return none */ void printCurrentNet() { // Display network SSID Serial.println(WiFi.SSID()); // Display network BSSID byte bssid[6]; WiFi.BSSID(bssid); Serial.print("- BSSID: "); Serial.print(bssid[5], HEX); Serial.print(":"); Serial.print(bssid[4], HEX); Serial.print(":"); Serial.print(bssid[3], HEX); Serial.print(":"); Serial.print(bssid[2], HEX); Serial.print(":"); Serial.print(bssid[1], HEX); Serial.print(":"); Serial.println(bssid[0], HEX); // Display network RSSI long rssi = WiFi.RSSI(); Serial.print("- Signal strength (RSSI): "); Serial.println(rssi); // Display network encryption byte encryption = WiFi.encryptionType(); Serial.print("- Encryption type: "); Serial.println(encryption, HEX); }

Jak użyć tych języków do Twoich projektów?

Zawsze mówiłem, żeby natychmiast monetyzować umiejętności, których się uczymy. Wiele osób uczy się danej umiejętności, ale na tym nie zarabia! o ile pozyskać wiedzę o danym języku np.: Ladder od razu spróbuj znaleźć rzeczywisty projekt, gdzie sprawdzisz swoje umiejętności za pieniądze. Przy rozwijaniu Twojego projektu w automatyce ważne, żeby zdefiniować swój standard programowania. Zadaj sobie pytania:

  • w jakim języku będą budowane programy główne?
  • w jakim języku będziesz budował bloki funkcyjne?
  • w jakim języku będziesz budował funkcje etc.
  • Dobrze skonstruowany standard programowania zaowocuje sukcesami w przyszłości.

Maciej Kurantowicz

Dowiedz się więcej na temat programowania sterowników PLC w języku tekstowym LAD przerabiając nasz kurs –> https://www.controlbyte.pl/s7lad

Idź do oryginalnego materiału