pamięć nie rdzewieje

May 31, 2014 58 Replies

W dniu 2014-06-01 07:30, J.F. pisze:

A nowa maszyna będzie najwcześniej za rok, oczywiście jak się dostawca wyrobi. No i nie ma wyjścia, trzeba sznurkiem wiązać starocia.

Na tym samym co ten drabinkowy? Np. jakiś StructuredText. Wyboru nie ma za dużego, chodzi o to że prewną klasę problemów wygodniej opisać czymś innym niż "proste drabinki".

PS. Mam w ręku urządzenie mierzące moc. Ma ono dwa przyciski do konfiguracji. Ponieważ opcji jest dziesiątki a wyswietlacz 7-seg, to programowanie tymi dwoma przyciskami trwa godzinę bo co chwile się mylisz. Ale przeciez nie można sobie wyobrazić nic prostszego niż dwa przyciski, prawda? To to samo co z drabinkami. Nic prostszego nie ma. To ilustruje problem.

Drabinka jest dobra gdy na przykład ma być spełnione wiele "bitowych" warunków. Mogą być zapisane w jednym wierszu w postaci schematu ze stykami. Wygodnie się monitoruje stan pracy przy uruchamianiu. Od razu widać które styki zwarte, a które rozwarte i na czym ci się zatrzymało urządzenie. W ST można oczywiście zapisać: If A=True and B=True And (C=False OR D=True) .... Then E:=True; End_If

Ale w ST gorzej to obserwować online. Poza tym w LD wygodniej wprowadzać reakcję na zbocze i wygodnie można ustawiać i kasować bity przez cewki Set i Reset. ST jest dobre przy pracach na tablicach i przy operacjach matematycznych. Z kolei CFC jest wygodne gdy masz jakieś bloki funkcyjne (biblioteczne lub własne) i karmisz je dużą ilością parametrów. Ale z kolei nie jest przyjemnie składać w nim wiele prostych warunków bitowych wspomnianych poprzednio. Przy bardziej złożonych programach z reguły używam obok siebie bloków LD, ST i CFC

Porównanie trochę od czapy. Nie trzeba od razu stosować LD do operowania na tablicach, wyliczania średniej i odchylenia standardowego z próbek pomiarowych i zapisywania tego w postaci pliku CSV. Wspomniane przez ciebie 2 przyciski może nie nadają się do urządzenia z wieloma parametrami, ale wystarczą do zegarka ręcznego z ustawianą datą i godziną. W tym przypadku pełna klawiatura byłaby bez sensu. A poza tym spotykam się raczej z 4 przyciskami w urządzeniach. W miarę sprawnie można nawigować po menu w warunkach "przemysłowych" np wisząc na szelkach :) Ale często urządzenia mają interfejs programujący i środowisko do konfigurowania z PC. Czyli twój wybór, jakie narzędzie wykorzystasz. Albo okoliczności decydują.

Teraz już rozumiesz o co mi chodzi. Automatyk wybrał drabinki ponieważ są *proste* zapominając że nie powstały do tego do czego je zastosował. Podobnie jakiś idiota wybrał *dwa* przyciski mimo że miał skomplikowane UI do obslugi. Oba przykłady są z automatyki. Oba nietrafione. I teraz najlepsze: oboje (koleś i firma od miernika) twierdzą że to był sukces. Koleś że w ogóle dał radę, a firma że stworzyła "prosty i przejrzysty interfejs". I wszyscy są szczęśliwi.

Pech, najzwyczajniej w świecie.

Jesteś pewny że z tyłu nie było gniazdka do podłączenia pecetowej

5Voltowej klawiatury PS/2 lub stary DIN? Albo jakiś RS232 do terminala? Front z dwoma przyciskami jest bardzo wygodny do poprawienia czegoś tam jednego - np. zamiast tego zrób to, ale do pełnej konfiguracji od zera zwykle używa się terminala znakowego po RS232 lub chociaż pecetowej klawiatury. Nasze najnowsze urządzenie ma prosty interface z ekranem dotykowym 7" ale pełna konfiguracja ma od ciula i trochę opcji i byłoby to ciężko zrobić na tym ekraniku obsługiwanym grubym paluchem więc do tego zrobiliśmy interface przez WebBrowser po Ethernecie, zostawiając tylko proste rzeczy do ustawiania od frontu lokalnie na ekranie dotykowym urządzenia.

Ależ oczywiście że jest, modbus. Pisalem soft obsługujacy to cudo. Ale zanim cokolwiek powalczysz z rs422 to - niestety - musisz to g... najpierw skonfigurować do pracy w tym trybie.

Przy czym mam poważne wątpliwości czy nie skusił bym się jednak na tą godzinkę przyciskami, bo po odpaleniu softu na Windowsie o mały włos nie umarłem ze śmiechu.

Ja wiem o co ci chodzi. Jadnak aby przyznać, że gość źle dobrał narzędzie do zadania to musiałbym mieć możliwość ocenić sam ten przypadek. Ty jako programista c++ możesz mieć skłonność do oceny, że ten przypadek (jak pewnie i każdy inny dla ciebie) jest doskonały do języka tego typu. A problem może w tym, że po prostu nie bardzo wiedział jak pisać program :)

Jak się wdroży projekt nawet z półrocznym opóźnieniem to też jest sukces. Jeśli nie trzeba płacić kar umownych :)

W dniu 2014-06-01 14:11, Pszemol pisze:

Zgadzam się, o ile to później nastąpi. Iluż może być chętnych na

4-letnią płytę główną dwie generacje techniczne wstecz?

W dniu 2014-05-31 16:00, Sebastian Biały pisze:

Pisałem w ubiegłym roku "drabinkowy" program na sterownik Kinco K3. Zadanie było proste: wykonać w określonej kolejności kilka ruchów silnikiem krokowym z ustalonymi parametrami (prędkość, odległość). Parametry ustawiane na module HMI z ekranem dotykowym. Sekwencja ruchów silnika bardzo prosta: szukanie położenia końcowego (z czujnikiem krańcowym), przejazd o wartość D1, pauza, N przejazdów o wartość D2, powrót. Pisanie (poprzedzone studiowaniem języka drabinkowego) zajęło trochę czasu, a powstały program w zasadzie był emulatorem interpretera języka sekwencyjnego...

Czyli zamiast napisać:

1) włącz silnik aż do znalezienia położenia krańcowego 2) włącz D1 impulsów silnika 3) for i:=1 to n { włącz D2 impulsów silnika } 4) wróć do położenia krańcowego 5) idź do 1

napisałem (w uproszczeniu!) mniej więcej coś takiego:

1) jeśli (pierwszy_cykl == TRUE) to { nr_stanu = 1 }

2) jeśli (nr_stanu == 1 lub nr_stanu == 4) to włącz szukanie położenia krańcowego

3) jeśli (nr_stanu == 1 oraz znaleziono_stan_krańcowy) to { nr_stanu = 2 }

4) jeśli (nr_stanu == 4 oraz znaleziono_stan_krańcowy) to { nr_stanu = 5 }

5) jeśli (nr_stanu == 2) to włącz D1 impulsów silnika

6) jeśli (nr_stanu == 2 ORAZ wykryto_koniec_ruchu_silnika) to { nr_stanu = 3; licznik = n }

7) jeśli (nr_stanu == 3) to flaga1 = (licznik>0)

8) jeśli (nr_stanu == 3 ORAZ flaga1 == TRUE ) to włącz D2 impulsów silnika

9) jeśli (nr_stanu == 3 ORAZ flaga1 == FALSE ) to { nr_stanu = 4 }

10) jeśli (nr_stanu == 3 ORAZ wykryto_koniec_ruchu_silnika} to { nr_stanu = 3a }

11) jeśli (nr_stanu == 3a) to { zmniejsz licznik o 1 }

12) jeśli (nr_stanu == 3a) to { nr_stanu = 3 }

13) jeśli (nr_stanu == 4 ORAZ znaleziono_stan_krańcowy) to { nr_stanu = 1 }

To oczywiście takie proste nie było, bo trzeba jeszcze czytać parametry z HMI i przenosić do "modułu" obsługującego silnik. A moduł mógł wystąpić tylko jeden raz w całym programie drabinkowym. Czyli zależnie od numeru_stanu trzeba było kopiować do niego różne parametry, a potem badać sumę logiczną wszystkich warunków, przy których silnik powinien się włączyć i takim sygnałem do aktywować.

Może ta drabinkowa koncepcja nadaje się do sterowania światłem na korytarzu, ale pisanie takiego kodu jest bardzo męczące.

P.

W dniu 2014-06-02 00:18, Piotrne pisze:

Możesz to ominąć stosując cewki -(S)- i -(R)- W dodatku nie rozumiem po co po kroku 4 wprowadzasz krok 5 będący przejściem na kroku 1 - szukania pozycji krańcowej skoro w kroku 4 dojechał do pozycji krańcowej.

Męczące dla kogoś przyzwyczajonego do C czy Pascala. Duża część poważnej przemysłowej automatyki jest na drabince, co by znaczyło, że ci co to robią uważają LD za wygodne narzędzie.

Użytkownik Mario napisał: [..]

A od kiedy to "użytkownik" może wymuszać na producencie takie a nie inne rozwiązanie? Gdyby była konkurencja z innym rozwiązaniem do tego wystarczająco silna jakościowo i marketingowo by przebić się przez obecny standard to może coś by się zmieniło.

W dniu 2014-06-02 00:55, AlexY pisze:

Od zawsze. Użytkownikiem nie byli informatycy, ale ludzie którzy wcześniej robili automatykę przy pomocy przekaźników i kłębka drutu. Ladder został stworzony dla nich żeby im przypominał schematy sieci przekaźników.

Obecnie jest standardem, że sterownik możesz programować w LD, ST, CFC, SFC, FB. A czasami po prostu w C. Chcesz wprowadzać jeszcze jakieś inne rozwiązania?

W dniu 2014-06-02 00:47, Mario pisze:

To była uproszczona ogólna koncepcja. Po kroku 4 jeszcze były różne testy poprawności wykonania innych elementów procesu.

Natomiast numerowanie stanów nie było takie proste. Dla każdego stanu przewidziany był oddzielny bit ("przekaźnik"), który włączał się i wyłączał w odpowiednim momencie. Czyli jeśli maszyna ma 100 stanów, to zamiast jednego licznika 7-bitowego potrzeba 100 oddzielnych bitów - "przekaźników".

S oraz R też tam wielokrotnie używałem. Ale wciąż nie widzę możliwości uproszczenia takiego programu i spowodowania, żeby był bardziej czytelny. Nie pisałem wcześniej w LD, ale tu akurat innej możliwości nie było. Miałem tylko darmowe narzędzia. Może istnieją jakieś bardziej przyjazne dla programisty konwertery "normalnych" programów do LD? Bo to wyglądało jak np. pisanie mikroprogramów wykonujących instrukcje CPU...

P.

opisany powyżej przykład jest z "życia wzięty", jakieś 2 tygodnie temu. Ofiarą jest scalak a'la CMOS Siemensa.

W dniu 2014-06-01 22:48, Tomasz Wójtowicz pisze:

Na przykład ja. Pecet z portami PCI obsadzonymi trzema kartami pomiarowymi za 20kPLN sztuka, plus 4 porty COM, 2 LAN. No i się padło płycie.. O ile COM/LAN na PCI-e się przesiadasz to już z tymi pomiarowymi nie jest fajnie. Dasz po 4 latach znowu 60kPLN na takie same karty w wersji PCIe tylko dlatego, że posiadająca 3 porty PCI płyta główna jest 150zł droższa i 2 generacje do tyłu?

W dniu 2014-06-02 13:21, Piotrne pisze:

Rozumiem, że numerowanie nie było proste bo ktoś postanowił żeby nie było proste. Ja tam numeruję stany w zmiennej int.

Jak się człowiek nie zna na LD to może nie wydaje się czytelny. Oczywiście gdy silnik załączasz w danym kierunku przy kilku różnych wartościach stanu i jeszcze przy spełnieniu jakichś innych warunków to może być mało czytelne złożenie tego w jeden rozkaz sterujący silnikiem. Ale możesz sobie zdefiniować kilka komórek typu MotorLeft1, MotorLeft2 itd. Sterujesz je jako cewki w kolejnych stanach gdy trzeba wysterować silnik w lewo. A potem tylko załączasz wyjście fizycznie sterujące silnikiem jako sumę logiczną wspomnianych komórek. Niby trochępokombinowane ale z drugiej strony jak ci się załącza silnik to widzisz z jakiego powodu. Ja tam lubię LD w sterowaniu ruchem. Widzisz stan wejścia sterującego ruchem, stan czujki np krańcowej, przeciążenia, błędu hamulca czy falownika. Wszystko w jednej linii sterującej np danym kierunkiem.

Nie pisałem wcześniej w LD, ale tu akurat

LD można konwertować do Instruction List. Ten to dopiero wygląda jak asembler. Jeszcze w dodatku zapis sugeruje, że wrzucasz na stos w odpowiedniej kolejności rozkazy typu LD, ADD, MUL, AND i zmienne. Czujesz się jakbyś programował kalkulator programowalny HP z odwrotną notacją polską. Do programów sekwencyjnych jest specjalny język Sequential Flow Chart. Przyznam, że kilka razy próbowałem, ale wygodniej mi się robi to w LD. Kiedyś całe algorytmy robiłem w ST, ale okazało się, że jego odpowiednik w STEP7 - SCL ma na tyle inną składnię, że czułem się niekomfortowo gdy przechodziłem z projektu na Schneidera na Siemensa i z powrotem. Tak wiec teraz robię część pomiarową i obliczenia w ST a zwykłe sterowanie w LD.

W dniu 2014-06-02 20:35, Mario pisze:

To widocznie przeoczyłem możliwość aktywacji danej gałęzi przy spełnieniu warunku nr_stanu == n. Oczywiście taki warunek można poskładać z przekaźników i chcąc coś zrobić w stanie nr 10 podać jako warunek: (bit0 == wyłączony) ORAZ (bit1 == włączony) ORAZ (bit2 == wyłączony) ORAZ (bit3 == włączony) i podobnie ustawiać wartość nr_stanu w (prawie) każdej gałęzi, ale to jest jeszcze mniej czytelne od używania pojedynczych bitów. Operacje na liczbach też są uciążliwe

- trzeba użyć bloku z odpowiednim działaniem, podawać argumenty z określonej lokalizacji, wskazywać lokalizację wyniku, aktywować blok działania. Jeśli to jest coś bardziej skomplikowanego niż A+B, to potrzeba kilku bloków i robi się nieczytelne. Nawet nie próbowałem umieszczać tego w jednej gałęzi, tylko wykonywało się "po kolei".

Kalkulatora HP z odwrotną notacją polską dawno temu używałem i pisałem programiki! Był bardziej przyjazny niż LD.

To właściwie były równoważne zapisy programu - można przełączać "widok" między LD a IL. Czasem czytelniejszy jest IL. Tak mniej więcej wyglądał kod IL:

(* Network 8 *) (*Repetitions: wartość domyślna 10*) LD %Q0.7 OR %SM0.1 MOVE 10, %VW162 (* Network 9 *) (*Czas rozpędzania/hamowania silnika w ms): wartość domyślna 20*) LD %Q0.7 OR %SM0.1 MOVE 20, %VW104 (* Network 25 *) (*Obliczenie liczby kroków*) LD %SM0.0 MOVE %VD150, %VD140 MUL %VD136, %VD140 (* Network 26 *) (*Obliczenie liczby kroków - c.d.*) LD %SM0.0 DIV DI#10, %VD140 (* Network 33 *) LD %SM0.0 AND %Q0.5 PHOME 1, %M8.0, %V220.3, %V220.3, %VW110, %VW174, %VW100, %VW102, %VW104, %M16.0, %M0.2, %VB207

Adresy w pamięci trzeba było uzgadniać z innym urządzeniem

- panelem HMI, który komunikował się z PLC. Narzędzia do programowania nie były zintegrowane, można było np. przygotować bazę zmiennych z adresami i wymieniać ją między środowiskami.

Problemy były też z modułami obsługi silników krokowych, bo czasem po prostu nie włączały się. Doczytałem, że w razie wystąpienia "błędu" (chyba było to np. przedwczesne zatrzymanie innym blokiem, nazywanym STOP) trzeba resetować flagę błędu w określonej komórce. Niby logiczne, ale bez możliwości debugowania trudno czasem było ustalić, co się dzieje.

Całkiem możliwe, że da się to zrobić lepiej. Doczytam przed ewentualnym kolejnym programem w LD...

P.

W dniu 2014-06-03 01:41, Piotrne pisze:

Nie jest to dobre bo przechodząc do kolejnego stanu musisz kasować bit poprzedniego (czy poprzednich). Łatwo o pomyłkę. A jak masz zmienną STEP to przy warunku STEP=10 i np PozycjaKoncowa=True ustawiasz STEP na 11. Bloczki =, >, >=, <, <= ADD, MUL czy MOVE masz praktycznie w każdej implementacji Laddera.

Można umieszczać w jednym rungu tylko zazwyczaj nie da się do wyjścia z wynikiem operacji podpinać wejścia następnego bloczka matematycznego. Trzeba używać zmiennych pomocniczych co jest dość upierdliwe.

Dla m,nie czytelniejszy rysunek w ladderze. A szczególnie gdy monitoruję z laptopa realizację programu w PLC.

Teraz są zintegrowane. Ale to też nie musi być zaletą. W Schneiderze możesz używać wspólnych nazw w PLC (np M258) i HMI (Magelis). W protokole komunikacyjnym też są wysyłane nazwy zmiennych a nie odpowiadające im adresy. W efekcie przy panującej modzie na nadawanie długich nazw, transmisja jest zajęta głównie przesyłaniem nazw a nie wartości :) Przy dużej ilości zmiennych to może być problem.

W dniu 2014-06-02 19:49, Irokez pisze:

To trochę inny problem. Tak naprawdę to coś warte są te karty. Płyta i procesor to tylko "obudowa".

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required