Strona główna ASTOR
Automatyka w praktyce

Połączenie terminalowe sterownika PLC Astraada One z robotem Kawasaki Robotics

Kontakt w sprawie artykułu: Konrad Sendrowicz - 2025-05-27

Z tego artykułu dowiesz się:

  • jak połączyć sterownik PLC Astraada One i robota Kawasaki Robotics za pośrednictwem protokołu TPC/IP,
  • jak przygotować program obsługujący komunikację dla sterownika Astraada One.

W nowoczesnych systemach automatyki bardzo często integruje się różne urządzenia oraz systemy do zarządzania procesem. Typowym przykładem może być komunikacja pomiędzy sterownikiem PLC a robotem przemysłowym.

W tym artykule pokażemy, jak w praktyce realizować połączenie pomiędzy sterownikiem PLC Astraada One, programowanym w środowisku Codesys, a robotem Kawasaki Robotics, z wykorzystaniem protokołu TCP. Takie rozwiązanie otwiera szerokie możliwości integracyjne – od przesyłania poleceń po pełną synchronizację działań maszyny i robota, a jednocześnie niweluje ograniczenia innych protokołów komunikacyjnych.

Protokół TCP/IP

Kluczowym elementem takiej integracji jest komunikacja sieciowa, a jednym z najczęściej stosowanych standardów w tym zakresie jest protokół TCP/IP.

TCP/IP (Transmission Control Protocol / Internet Protocol) to zestaw protokołów komunikacyjnych używanych do przesyłania danych w sieciach komputerowych – w tym również przemysłowych. Działa w modelu warstwowym, gdzie:

  • IP odpowiada za adresowanie i dostarczanie pakietów do odpowiedniego urządzenia w sieci,
  • TCP dba o niezawodność transmisji: kontroluje kolejność danych, potwierdzenia odbioru, retransmisje w przypadku utraty pakietów.

W automatyce przemysłowej protokół TCP/IP wykorzystywany jest m.in. w komunikacji między sterownikami, komputerami przemysłowymi, robotami, systemami SCADA oraz urządzeniami IoT.

Zalety TCP/IP w systemach automatyki:

1. Powszechność i kompatybilność.

  • Standard obsługiwany jest przez większość urządzeń na rynku – od sterowników PLC po roboty przemysłowe i serwery.
  • Umożliwia łączenie urządzeń różnych producentów bez potrzeby stosowania specjalnych konwerterów.

2. Niezawodność transmisji.

  • TCP gwarantuje dostarczenie danych w odpowiedniej kolejności i bez błędów.
  • Mechanizmy retransmisji oraz potwierdzeń (ACK) zapewniają bezpieczeństwo komunikacji nawet w trudnych warunkach sieciowych.

3. Łatwość testowania i diagnostyki.

  • Istnieje wiele narzędzi (np. Wireshark, netcat, Packet Sender), które pozwalają monitorować komunikację w czasie rzeczywistym.
  • Ułatwia analizę błędów i testowanie nowych rozwiązań.

W przypadku integracji sterownika PLC z robotem przemysłowym – np. Kawasaki Robotics – TCP/IP sprawdza się znakomicie jako warstwa transportowa:

  • umożliwia przesyłanie komend sterujących, parametrów procesu lub współrzędnych trajektorii robota,
  • zapewnia stałą synchronizację działań PLC i robota, co ma kluczowe znaczenie np. przy podawaniu detalu lub zsynchronizowanym ruchu,
  • dzięki standardowemu podejściu robot może być sterowany nie tylko z poziomu PLC, ale również z innych systemów – np. wizji maszynowej, aplikacji desktopowej, chmury.

Co więcej, komunikacja TCP może być zrealizowana bez konieczności zakupu dodatkowych licencji czy modułów – wystarczy dostęp do gniazda Ethernet oraz podstawowe funkcje socketowe w oprogramowaniu sterownika i robota.

Konfiguracja krok po kroku w programie Codesys

W środowisku Codesys dostępna jest biblioteka SysSocket, która zawiera funkcje do zdefiniowania parametrów komunikacji, a także funkcje do wysyłania i odbierania wiadomości.

Pierwszym krokiem jest dodanie biblioteki do tworzonego programu. Należy otworzyć zakładkę SysSocket i kliknąć przycisk Add Library, a następnie znaleźć SysSocket.

Biblioteka SysSocket pozwala na wykorzystanie funkcji do obsługi wszystkich typów połączeń, w tym przypadku będzie wykorzystane jedynie pięć z nich, które odpowiadają 5 etapom połączenia:

1. Syssockcreate: tworzenie gniazda komunikacyjnego w sterowniku PLC na podstawie zdefiniowanych parametrów. Funkcja zwraca wskaźnik gniazda (socket handle).

2. Syssockconnect: połączenie stworzonego w poprzednim kroku gniazda z serwerem TCP i synchronizacja połączenia. Funkcja zwraca status połączenia.

3. Syssocksend: wysyłanie danych (zapytania) do serwera. Wymaga przygotowania ciągu znaków do wysłania.

4. Syssockrecv: odbieranie danych od serwera. Po wysłaniu danych klient, w tym przypadku PLC, nasłuchuje odpowiedzi.

5. Syssockclose: zamknięcie połączenia i gniazda. Na koniec działania programu lub gdy potrzeba jest przełączenia się do innego gniazda, należy wykonać zamknięcie. Można to robić po każdym przesłaniu informacji, aby nie blokować połączenia.

Struktura całego programu będzie wyglądać jak na schemacie poniżej:

Kolejnym krokiem jest dodanie listy zmiennych do obsługi komunikacji, lista zostanie podzielona na 6 części, dla każdego etapu oraz zmienne ogólne.

PROGRAM Terminal_Kawasaki
VAR 
//General variable
	iStep : INT := 0; // Step of process sequence
	xStart : BOOL; //start communication
	xRecvBytes : BOOL; // state of receive data
	xSendData: BOOL; //start sending data
	xCloseSocket:BOOL; //close communication
	End_of_line:STRING; //additional sign, dedicated for Kawasaki Robotics
//Create socket	
	iecSocketId : syssocket_interfaces.RTS_IEC_HANDLE; // socket handle
	iecCreateResult : syssocket_interfaces.RTS_IEC_RESULT; // socket create result
	ipAddr : syssocket.SOCKADDRESS; // soket address
//Connect to server 
	sIpAddress : STRING:='127.0.0.1'; // server ip address
	wPort : WORD:=9105; // server listening port
	iecConnectResult : syssocket_interfaces.RTS_IEC_RESULT;  // socket connect result
//Send data
	sSending_buffor:STRING; // send data buffer
	xiSentBytes : __XINT;  // number of bytes sent
	iecSendResult : syssocket_interfaces.RTS_IEC_RESULT; // send result
//Receive data 	
	sDataRec : STRING(1524); // receive data buffer
	xiRecBytes : __XINT; // number of bytes recieved
	iecSRecResult : syssocket_interfaces.RTS_IEC_RESULT; // receive result
//Close socket	
	iecCloseResult : syssocket_interfaces.RTS_IEC_RESULT; // close result
END_VAR

Program będzie podzielony na kroki, by w łatwy sposób zarządzać procesem komunikacji, do tego zostanie wykorzystana struktura CASE, szkielet programu będzie wyglądał następująco:

CASE iStep OF 
	0: 
	//preparing data 
	1:
	// create the socket
	2: 
	// connect to socket server
	3: 
	// send date
	4: 
	//receive date
	5: 
	// close socket
END_CASE

W kroku zero zostaną przygotowane parametry to stworzenia gniazda i nawiązania komunikacji. Należy zdefiniować adres IP, port oraz rodzinę adresów serwera. W tym celu zostanie wykorzystana gotowa funkcja z biblioteki, która w łatwy sposób wypełni wymaganą strukturę do połączenia. Dodatkowo w tym kroku należy sprawdzić stan rozpoczęcia procesu.  

0: 
	//preparing data 
	IF xStart THEN
		syssocket.SysSockInetAddr(sIpAddress, ADR(ipAddr.sin_addr)); 
		ipAddr.sin_family := syssocket.SOCKET_AF_INET; 
		ipAddr.sin_port := syssocket.SysSockHtons(wPort);
		iStep:=1;
	END_IF

W pierwszym kroku zostanie stworzone gniazdo (socket) na sterowniku PLC. Jeżeli zwrócony zostanie status błędu, proces wróci do pierwszego kroku i będzie oczekiwał na ponownie uruchomienie zmienną xStart.

1:
	// create the socket
	iecSocketId:=syssocket.SysSockCreate(syssocket.SOCKET_AF_INET,syssocket.SOCKET_STREAM, syssocket.SOCKET_IPPROTO_IP, ADR(iecCreateResult));
	IF iecSocketId = syssocket_interfaces.RTS_INVALID_HANDLE THEN
		xStart := FALSE;
		iStep := 0;
	ELSE
		iStep := 2;
	END_IF

Krok drugi to połączenie sterownika do serwera, w tym przypadku kontrolera robota Kawasaki.

2: 
	// connect to socket server
	iecConnectResult := syssocket.SysSockConnect(iecSocketId, ADR(ipAddr), SIZEOF(ipAddr)); 
	iStep := 3;
	xRecvBytes:=TRUE;

Krok trzeci obsługuje wysyłanie danych do serwera oraz automatycznie wyzwala odczyt danych odbieranych od serwera. Dlatego będą tutaj dwa warunki, które rozpoczną proces wysyłania lub zakończą proces i przejdą do kolejnego kroku.

3:
	// send data
	IF xSendData =TRUE THEN
		sEnd_of_line[0]:=16#0A;
		sSending_buffor:=CONCAT(sSending_buffor, End_of_line);
		xiSentBytes := syssocket.SysSockSend(iecSocketId,ADR(sSending_buffor),LEN(sSending_buffor), 0,ADR(iecSendResult));
		xRecvBytes := TRUE;
		xSendData:=FALSE; 
	ELSIF xCloseSocket =TRUE THEN 
		iStep := 5;
		xCloseSocket:=FALSE; 
	END_IF

Krok czwarty nie będzie znajdował się strukturze CASE, tylko poza nią, aby odczyt mógł działać niezależnie. Dlatego krok czwarty zostanie pusty, a całość funkcji odczytu, zostanie dodana poniżej. Odebrana wiadomość zostanie przypisana do zmiennej sDataRec.

IF xRecvBytes AND xStart THEN
	xiRecBytes := syssocket.SysSockRecvFrom(iecSocketId, ADR(sDataRec), SIZEOF(sDataRec), 0, ADR(ipAddr), SIZEOF(ipAddr), ADR(iecSRecResult)); 
	xRecvBytes := FALSE; 
	sSending_buffor:='';
END_IF

Ostatnim krokiem jest zamknięcie komunikacji i gniazda TCP.

5:
	// close socket
	IF NOT xiRecvBytes THEN
		iecCloseResult := syssocket.SysSockClose(iecSocketId);
		xStart := FALSE;
		iStep := 0;	
	END_IF

Przygotowany program jest gotowy do działania i wymaga jedynie ustawienia poprawnego adresu IP, portu oraz rozpoczęcia komunikacji. Aby wysłać informację, należy wpisać ciąg znaków do zmiennej sSending_buffor, a następnie zmienić wartość zmiennej xSendData na TRUE i zatwierdzić przyciskami CTRL+F7.

Dostosowanie programu do komunikacji z Kawasaki Robotics

Do komunikacji z serwerem Kawasaki Robotics należy wprowadzić drobne zmiany i dostosować wielkość buforów. Kawasaki przesyła długie ciągi znaków, które mogą przekroczyć domyślną długość zmiennych lub wydłużyć czas oczekiwania, aby cała wiadomość dotarła do sterownika PLC.

Pierwszym elementem będzie dodane drobnego opóźnienia w odczytywaniu wiadomości, w tym celu dodany zostanie timer z krótkim czasem wyzwolenia. Dodatkowe zmienna:

VAR
	timer: Standard.TON := (PT := TIME#50MS);
END_VAR

A w programie zostanie dodany timer przed strukturą CASE, dzięki czemu w momencie wywołania odczytu sterownik poczeka 50 ms.

timer();

IF timer.Q THEN
	xRecvBytes := TRUE;
	timer.IN := FALSE;
END_IF

Następnie wszędzie w programie, gdzie było bezpośrednie uruchomienie komunikacji, należy zamienić na wyzwolenie timera w taki sposób:

xRecvBytes := TRUE; –> timer.IN := TRUE;

Te kroki pozwolą sterownikowi niezależnie od połączonego kontrolera czy symulatora na oczytanie pełnej informacji.

Aby obsłużyć długie ciągi znaków wysyłane z robota Kawasaki Robotics, zostanie dodana nowa zmienna do przechowania odebranego ciągu znaków oraz prosta wizualizacja do obsługi komunikacji.

VAR
	sReceive_message:STRING(1524); 
	iCopyBuffer: DINT;
END_VAR

Następnie w programie w sekcji odbioru informacji należy dodać linijkę kodu, obsługującą skopiowanie odebranej wiadomości do zmiennej, która następnie zostanie wyświetlona. W tym celu najpierw zostanie wyczyszczony bufor, a następnie skopiowana cała długość odebranego ciągu znaków.

sReceive_message:= standard.DELETE(STR:= sReceive_message, LEN:= 1524, POS:= 1);

copyBuffer:= Stu.StrCpyA(pBuffer:= ADR(sReceive_message), iBufferSize:= TO_DINT(xiRecBytes)+1, pStr:= ADR(sDataRec));

Jeżeli po dodaniu tych linii kodu pojawiają się błędy w kompilatorze, oznacza to, że należy dodać bibliotekę obsługującą długie ciągi znaków, czyli StringUtils, w taki sam sposób, jak w punkcie pierwszym.

Wizualizacja

Ostatnim krokiem będzie dodanie prostej wizualizacji do obsługi komunikacji. W nowym oknie wizualizacji zostanie dodane pole tekstowe, w którym zostanie wyświetlona aktualna odpowiedź z kontrolera robota:

Następnie dodaj 3 przyciski które rozpoczną komunikację, zainicjują wysyłanie oraz zakończą komunikację. Należy przypisać do nich odpowiednie zmienne.

Do przycisku Stop należy dodać kod „Terminal_Kawasaki.xCloseSocket:=TRUE;” który w kroku trzecim wywoła zamknięcie się gniazda komunikacyjnego.

Natomiast przycisk Send powinien wywołać wysyłanie, dlatego zostanie wykorzystana funkcja Tap dla tego przycisku:

Ostatnim elementem jest pole tekstowe w którym wpisywana będzie treść wiadomości wysyłanej do robota. Jako zmienną należy użyć sSending_buffor.

Na gotowej wizualizacji możliwe jest uruchomienie komunikacji, zatrzymanie, wyświetlanie informacji zwrotnej oraz łatwe definiowane tekstu do wysłania do kontrolera. Należy pamiętać, że przy takim połączeniu robot zawsze poprosi o zalogowanie na początku, na które należy odpowiedzieć „as”. Po tym logowaniu możliwa jest pełna wymiana informacji. Przykład komunikacji można zobaczyć poniżej:

Podsumowanie

Dzięki tego typu komunikacji, która nie potrzebuje dodatkowej licencji czy karty komunikacyjnej w obu węzłach sieci, można w łatwy sposób rozszerzyć możliwości aplikacji. A brak konieczności przypisania na stałe wymienianych zmiennych, całkowicie eliminuje ograniczenia liczby bitów, które można przesłać w klasycznych protokołach (w Kawasaki Robotics aktualnie 960 bitów). Do wyżej przedstawionej procedury wystarczy dodać niewielką analizę danych i można odpytywać o wszystkie dane z robota. Przykładowo mogą to być: lista wszystkich programów oraz ich wybór, nadpisywanie punktów i ich modyfikacja, status robota, lista błędów i wiele innych informacji bez ograniczeń.

Newsletter Poradnika Automatyka

Czytaj trendy i inspiracje, podstawy automatyki, automatykę w praktyce

Please wait...

Dziękujemy za zapis do newslettera!

Czy ten artykuł był dla Ciebie przydatny?

Średnia ocena artykułu: 5 / 5. Ilość ocen: 1

Ten artykuł nie był jeszcze oceniony.

Zadaj pytanie

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *