Dobre praktyki programowania sterowników PLC

Ja również,chętnie zobaczę :slight_smile:

Przy zmianach programu stosuje marker oznaczony swoim imieniem przez co woem gdzie co ja zmienialem , usuwalem.

Dobra praktyka jest mapowanie IO w jednym miejscu podpinamy IO pod zmienne w efekcie pozniej jak mamy kolejny taki sam projekt to program jest ok tylkp przepinamy IO np w jednym FC

1 polubienie

Nie wymienione wyżej, a warte uwagi jest:

  • stworzenie osobnych zmiennych do wymiany danych z HMI

Dzięki temu mamy możliwość zmian w PLC nie wpływających na komunikację z HMI, oszczędza to klepanie tego samego w dwóch miejscach :slight_smile:

2 polubienia

Jeśli tworzymy osobne zmienne to jest to dublowanie, więc nie rozumiem jak dzięki temu możemy oszczędzić “klepanie tego samego w dwóch miejscach” :wink:
Zawsze mam kłopot z wymianą danych między HMI/SCADA, bo wpływa na to dużo czynników:

  • zmienne symboliczne (w Siemensie zoptymalizowane) czy stara szkoła i odnoszenie się do adresu zmiennej - część paneli kiepsko radzi sobie z adresowaniem symbolicznym,
  • jeśli zmienne symboliczne to nazwa musi być krótka, bo panele HMI łatwiej radzą sobie z takimi,
  • część połączeń HMI przy adresowaniu symbolicznym lepiej radzi sobie ze strukturami ( czyt. np. Rockwell), a inna część nie obsługuje struktur,
  • tak jak kolega powyżej poruszył temat: lepiej komunikację z HMI wydzielać na osobne zmienne i osobne miejsce w programie czy obsługiwać z resztą kodu obsługi urządzeń i algorytmu automatyki? Jeśli osobno to jest to uciążliwe, ale ładniejsze. Jeśli razem to prostsze, ale mniej czytelne i komunikacja z HMI ginie w reszcie kodu.
    Ogólnie podsumowując moim zdaniem prze… :grinning:

Wystarczy stworzyć osobny blok kodu (FC/Routine/POU) w którym zawarte jest mapowanie pomiędzy zmiennymi wykorzystanymi w programie, a zmiennymi dla HMI.
Dlaczego nam to oszczędza roboty?
Wiadomo jak jest ze zmianami i przykładowo: pozycja jest sygnalizowana przez styki typu NO to zmiana tego wymagana jest na wizualizacji i w programie, lecz jeżeli jest to rozdzielone to logika zmienia się tylko w programie i wizualizacja tego nie odczuwa

1 polubienie

Tak jak pisałem jeśli zrobimy to w osobnym bloku kodu to zajmuje to więcej pracy. Jeśli chcemy, żeby ktoś się w tym odnalazł to wypadałoby odwzorować szkielet programu jaki mamy w algorytmie sterowania automatycznego w tym osobnym bloku dla HMI - tak, żeby zachować czytelność programu, więc może powodować to niepotrzebne rozbudowanie programu.
Obie opcje mają wady i zalety. Moim zdaniem trzeba wybrać 1 z nich, konsekwentnie się trzymać i dbać o czytelność programu.
Poza tym z logiką dla HMI na sterowniku jest taki problem, że gdy sterownik nie pracuje - przykładowo po załączeniu maszyny, a HMI szybciej się odpali to panel pokazuje nam głupoty i źle to wygląda.
Moim zdaniem zawsze warto brać pod uwagę wartość domyślną, żeby później nie mieć przykładowo niepotrzebnych alarmów na HMI w buforze historycznym.

Owszem zajmuje więcej pracy, ale przy pierwszym podejściu, zmiany są łatwiejsze i tu nadrabiamy poprzedni naddatek.
Pamiętać też trzeba, że kod więcej czytamy niż piszemy - dlatego powinien być czytelny i prosty ponad optymalizacje

1 polubienie

A co najważniejsze wystarczy zrobić jednego snapshota zeby uchronić się przed reincjalizacja. Dawanie zmiennych które sa sterowane z panelu HMI do osobnego DB jest jak najlepsza praktyka. Kto dużo pracował z SIemensem to na pewno potwierdzi

3 polubienia

Pytanie bardziej konkretne:
Jak radzicie sobie z danymi IO w Siemensie S7-1200/S7-1500?
Ja dane trzymam tylko w DB. Markerów używam przy 2 okazjach: system and clock memory bits oraz dane IO. No i właśnie z danymi IO jest taki problem, że nie mogę ich w 100% ładnie uporządkować. Można zrobić tablice tag table - to pozwala na wygodne przeglądanie. Jednak jak chcę się odwołać w programie do konkretnej zmiennej to do tej pory miałem problem. Od pewnego czasu stosuję UDT jako typ danych zmiennych IO. Przykładowo jak komunikuję się z falownikiem to dzięki temu opisuję sobie poszczególne bity Status Word oraz Control Word, a jeśli zadana prędkość znajduje się na 2 wordach to mogę ją połączyć np. w 1 zmienną typu Dint. Podobnie robię ze zmiennymi IO modułów na sterowników oraz rozproszonych wejść/wyjść. Jeśli zmienne są dobrze zaplanowane na etapie projektu elektryki to fajnie to działa. Zamiast długich/dziwnych nazw zmiennych można stosować “miejsce na maszynie.sygnał”
Ktoś jeszcze tak robi? Są jakieś wady tej praktyki z których mogę sobie nie zdawać sprawy? :stuck_out_tongue:

Nie rozumiem trochę. Dlaczego nie używasz DB? Masz falownik czy cokolwiek z rozpisaną ramką do komunikacji to tworzysz db input i db output rozpisujesz w nich odpowiednio ramki i już. Inputa odczutujesz na początku cyklu outputa wysyłasz na koniec i wszystko śmiga bez markerów. Też z nich nie korzystam.

Wiem, że tak można. Przeważnie w blokach do komunikacji z falownikami od producentów stosowane jest takie rozwiązanie. Nie pasuje mi w nim to, że zmienne są ukryte wewnątrz bloku. Wolę, żeby Inputy i Outputy były wymieniane przez interfejsy bloku, a nie przez instrukcję wewnątrz.
Jednak IO nie po profinecie/profibusie a z modułów sterownika nie odczytasz w ten sposób?

Nie do końca się z Tobą zgadzam. Podczas analizy czyjegoś kodu, niezbyt mnie interesuje co programista miał na myśli, tylko co zawiera/realizuje poniższy kod, tak abym mógł go szybko zrozumieć. Sam tak robię, każdy rung/network komentuje. Komentarz zawiera informację jak działa poniższy kod i co robi.

Jeszcze jedna ważna rzecz o której nikt nie wspomniał, uważam iż należy nazywać zmienne oraz pisać komentarze w języku angielskim. W polskim źle to wygląda.
Nazwy tagów urządzeń powinny być takie jak na schemacie P&ID. Porządne nazwy a nie jakieś z dupy jak to nie raz bywa.

Chodzi mi o to, że jak wiesz, co programista ma na myśli to nie musisz analizować każdego networku styk po styku tylko możesz część kodu pomijać wnioskując z komentarzy, co realizuje.

3 posts were split to a new topic: 10 porad programowania sterowników PLC na bazie GX Works od Mitsubishi Electric

Jacku, czy mógłbyś podzielić się treścią tego przewodnika?

Witam, czy jest możliwość wglądu do tego przewodnika który otrzymałeś? Pozdrawiam

  1. Ktore rozwiazanie uwazacie za lepsze w momencie np. gdy chcemy wysterowac trzy cewki, nie mowie o jakis bardziej skomplikowanych networkach, tylko proste wyjscia, czy rozbiajcie to na linijki, czy wszytsko w jednej.
    image

  2. Czy tworzycie takie struktury dla np. przyciskow i uzywacie ich w kodzie ? Np. zbocz sa wygodne, wszystkie zmienne i wszystkie ich stany w jednym bloku, ale wtedy w kodzie zbocze juz nie jest dla obcej osoby odrazu widziane jako zbocze tylko musi dokladnie wczytac sie w nazwe, tak samo inversja jakiegos stanu moze byc mylaca. Czy uwazacie takie rozwiasanie za dobre, czy jednak daje wiecej szkody niz pożytku.
    image

1 polubienie
  1. Dla funkcjonowania i kodu to nie ma znaczenia ale Network 4 jest bardziej rozciągnięty na ekranie a 5 zwarty i pozwala jednym rzutem oka ogarnąć całość gdy jest więcej elementów, ja preferuje rozwiązanie Network 5.
  2. Struktury są jak bardziej wskazane, nawet bez komentarzy są dość oczywiste. Często używam tablic to pomaga gdy używasz zmienne w funkcjach gdzie logika jest powtarzalna -->
    idx=1;
    IF przycisk[idx]=1 AND one_shot[idx] AND warunek[idx]=1 THEN cewka[idx]=1 END;
    idx=2
    IF przycisk[idx]=1 AND one_shot[idx] AND warunek[idx]=1 THEN cewka[idx]=1 END; // //taki przykład może nie czytelny ale pokazujący ideę, taka prosta drabinka w kodzie
1 polubienie

Tak w teksie to widoczne odrazu, w drabince juz mniej. If lepiej w teksie, ale jednak staramy sie mieszac, uzywac tego tak aby bylo to z jednej strony wydaje i optymalne, a z drugiej czytelne. Wiec tam gdzie drabinka sie sprawdza tam zostanie. Mieszanie tych nazw tez chyba nie bedzie dobrym rozwiazaniem. I tutaj mam taka watpliwosc, jak wiadomo nadgorliwosc jest gorsza od faszyzmu.
image

polecam definiować stałe i używać ich zamiast wpisywania czystych wartości liczbowych w miejsca takie jak krok, faza, operacja

2 polubienia