Strona główna ASTOR
Automatyka w praktyce

Odbieranie zmiennej tekstowej za pośrednictwem standardowego protokołu komunikacyjnego
Wymiana danych pomiędzy robotem Kawasaki a sterownikiem PLC, odc. 9

Kontakt w sprawie artykułu: Konrad Sendrowicz - 2025-01-07

W tej części dowiesz się, jak odebrać zmienną tekstową od sterownika PLC, z którym robot komunikuje się standardowym protokołem komunikacyjnym, np. Ethernet/IP lub Profinet.

Wstęp

Jest to kontynuacja poprzedniej części poradnika, w której ciąg znaków przesyłany był z robota do PLC. W tej części dodamy do poprzedniego programu wysyłanie ciągu znaków w odwrotną stronę, czyli ze sterownika PLC do robota. Proces przesyłania będzie zorganizowany analogicznie jak poprzednio, tylko role urządzeń zostaną zamienione. PLC będzie przygotowywał zmienne i zarządzał komunikacją, a robot będzie działał reaktywnie, jedynie odczytując dane i przypisywał do właściwych zmiennych.

Proces przygotowania zmiennych będzie wyglądał jak w poprzedniej części, podzielony na dwa etapy: dzielenie i przygotowanie danych, a następnie wysłanie znak po znaku. Po dokładny opis warto sięgnąć do części 8 tego poradnika.

Ten typ komunikacji może być wykorzystywany do wybierania programu wykonywanego przez robota lub wybierania konkretnej funkcjonalności w robocie.

Modyfikacja programu robota  

Program w kontrolerze robota został przygotowany zgodnie z opisem powyżej i analogicznie do poprzedniej części dla sterownika PLC. Robot w momencie pojawienia się sygnału nadawania wiadomości zaczyna czytać każdy znak, dekodując go w kodzie ASCII, a po odczytaniu całości przypisuje do odpowiedniej zmiennej na podstawie ID przesyłanych danych. Do odbioru danych wystarczy tylko krótki kawałek kodu w programie PC, który został przedstawiony poniżej.  

W tej części zostanie dodana funkcja $CHR(), która jako parametr przyjmuje wartość dziesiętną litery w kodzie ASCII i zwraca odpowiadający jej znak. Np. $CHR(75) zwraca „k”.

Na początku należy przypisać nowe zmienne, które będą wykorzystywane do komunikacji:

;Output signals
  To_PLC_read_string = First_bit_Out + 8 * 21 + 3
; Input signals
  Data_string_8 = First_bit_In + 8 * 4 ; all 16 byte variable with each letter (byte 4-19)
  ID_data_str_8 = First_bit_In + 8 * 2
  Num_seq_8 = First_bit_In + 8 * 3
  PLC_data_ready= First_bit_In + 5
;Additional variables
  $Recieve_string = "" ; Add empty string
  String_num_seqence = 0 ; initialize variable

Główna część programu odczytująca dane z PLC będzie działać w wątku równoległym (PC Program) poprzednio modyfikowanym. Jeżeli dane przez PLC zostaną przygotowane, procedura odczytania wykona się, przypisując odpowiednie zmienne. Cała procedura znajduje się poniżej:

IF SIG(PLC_data_ready) == TRUE AND SIG(To_PLC_read_string) == FALSE AND BITS(Num_seq_8,8) > 0 THEN ; start reading each sign
      FOR c = 1 TO 16
        IF BITS(Data_string_8+(c-1)*8,8) == 255 THEN
          $Recieve_string=$Recieve_string + $CHR(32)
          GOTO Exit_for
        ELSE
         $Reinvesting = $Recieve_string + $CHR (BITS (Data_string_8 + (c-1) * 8, 8))
        END
      END
Exit_for:
      String_num_seqence= String_num_seqence + 1;
      SIGNAL To_PLC_read_string ; Finish reading 
      IF String_num_seqence == BITS(Num_seq_8,8) THEN
        String_num_seqence = 0
        ;Assign string to correct variable of string 
        CASE BITS(ID_data_str_8,8) OF
          VALUE 1:   ; Text 1
            $Info_from_PLC1= $Recieve_string
            PRINT $Info_from_PLC1
            $Recieve_string =""
          VALUE 2:   ; empty
            ;second
            $Recieve_string = ""
        END
      END
    ELSE
      IF  SIG(PLC_data_ready)== FALSE AND SIG(To_PLC_read_string) == TRUE THEN
        SIGNAL -To_PLC_read_string 
      END
    END

Program jest podzielony na dwie części, w pierwszej odczytywane są wszystkie znaki w sekwencji i przypisywane do tymczasowej zmiennej Recieve string. Następnie sprawdzany jest numer sekwencji, jeżeli jest ich więcej, cykl się powtarza, jeżeli to koniec, druga część przypisuje odczytany ciąg znaków do odpowiedniej zmiennej. Na końcu czyszczona jest zmienna tekstowa i zmienne statusowe, a robot gotowy jest na przyjęcie kolejnych informacji.  

Modyfikacja programu sterownika PLC

Program w sterowniku PLC będzie podzielony na dwie części, analogicznie do programu robota w poprzednim kroku. Pierwszy podprogram będzie odpowiedzialny za przygotowanie danych do wysłania, a druga część to modyfikacja poprzednio stworzonego programu do zarządzania przesyłanymi tekstami, aby przesyłał kolejne sekwencje tekstu do robota.

1) Aby w łatwy sposób zarządzać przesyłanymi zmiennymi ze znakami, stworzony zostanie dodatkowy podprogram, który będzie wywoływany w celu przygotowania do wysyłki ciągu znaków. Aby stworzyć nowy podprogram należy wybrać prawym przyciskiem myszy Application->Add Object-> POU

Następnie należy zdefiniować nazwę, typ programu wybrać jako funkcja, która zwraca wartość BOOL i kliknąć Add.

W tej funkcji możliwe jest dodanie parametrów wejściowych, w tym celu zdefiniujemy zmienne dwóch typów, przyjmowanych do funkcji:

Send_to_rob_string – przyjmująca ciąg znaku, który ma być przygotowany do wysłania,

ID_message – zmienna definiująca identyfikator zmiennych, dzięki czemu jedną funkcją użytkownik może przesłać różne typy danych.

Dodatkowo potrzebne będą zmienne globalne, w których będą przechowywane wartości bezpośrednio przypisane do ramki komunikacyjnej oraz wymieniane między podprogramami. Lista zmiennych, które należy dodać do Global Variable List GVL, znajduje się poniżej:

//Part 9
Send_string_ArryData:ARRAY[1..6] OF STRING; //16 byte part of string
ID_string:BYTE; //id for program to split 
Num_seqence:BYTE; //number of seqence for program to split
Stat_sending_string:BOOL; //general status of sending string 
Temp_index:BYTE; //temporary indext, just to start send sequence
To_Rob_Ready_string:BOOL; //status bit 
Robot_get_string:BOOL; 	//status bit 

To_Rob_ID_string:BYTE; 	//id of sending string data
To_Rob_Num_seq_string:BYTE; //number of sequence to send
To_Rob_string_Array:ARRAY[1..16]OF BYTE;  //data to send - each byte

2) Po utworzeniu zmiennych kolejnym krokiem jest napisanie podprogramu do przygotowania danych do wysłania. W tym celu musimy podzielić przesłany ciąg znaków na 16-znakowe odcinki, ponieważ tyle bajtów można przesłać jednocześnie. Podczas dzielenia dodatkowo definiowana jest liczba sekwencji wymagana, by przesłać cały ciąg znaków, a także identyfikator (ID) wiadomości. Po przygotowaniu danych, ustawiany jest sygnał Stat_sending_string na wysoki i wysyłanie zostanie rozpoczęte w programie dedykowanym do zarządzeniem przesyłania zmiennych typu string string_manage. Procedura znajduje się poniżej:

IF (LEN(Send_to_rob_string) MOD 16) >0 THEN 
	GVL.Num_seqence:=TO_BYTE(LEN(Send_to_rob_string)/16)+1;
ELSE 
	GVL.Num_seqence:=TO_BYTE(LEN(Send_to_rob_string)/16);
END_IF
FOR i:=1 TO GVL.Num_seqence DO
	GVL.Send_string_ArryData[i]:=MID(Send_to_rob_string,16,(i-1)*16+1);
END_FOR
gvl.ID_string:=ID_message; 
gvl.Stat_sending_string:=TRUE;
gvl.Temp_index:=1;
Send_String:=TRUE; 
RETURN;

Wynikiem działania tego podprogramu jest obliczona liczba sekwencji, zapisana do zmiennej num_sequence, wektor ciągów 16 znaków podzielonych na sekwencji Send_string_ArrayData[], a także indeks przesyłanej wiadomości ID_string.  

3) Po przygotowaniu danych należy przygotować program do wysyłania. Zmodyfikowany zostanie program string_manage, w którym zostanie dodana procedura odbioru danych od robota. Dokładnie jak poprzednio w robocie, algorytm w momencie wysyłki przypisze każdemu bajtowi wartość ASCII litery i wystawi sygnał gotowości. Gdy robot odbierze dane, przesyłany jest kolejny pakiet znaków i tak aż do momentu, gdy wszystkie sekwencje zostaną przesłane.

Dodatkowo do programu zostały dodane dwie zmienne lokalne b do zliczania ilości wykonania pętli FOR, oraz string_temp, aby przechowywać aktualnie przesyłany fragment ciągu znaków. Znacznie ułatwia to odczytanie kolejnych liter całego ciągu znaków.

/// PART 9 - sending string to robot 
IF GVL.Stat_sending_string=TRUE AND gvl.Num_seqence>0 AND gvl.To_Rob_Ready_string=FALSE AND gvl.Robot_get_string=FALSE THEN 
	IF gvl.Temp_index=1 THEN 
		gvl.To_Rob_ID_string:=gvl.ID_string;
		gvl.To_Rob_Num_seq_string:=gvl.Num_seqence;
	END_IF
	Variable_temp:=gvl.Send_string_ArryData[gvl.Temp_index];
	FOR b:=1 TO 16 DO 
		gvl.To_Rob_string_Array[b]:=Variable_temp[b-1];
	END_FOR
	gvl.To_Rob_Ready_string:=TRUE; 
	gvl.Temp_index:=gvl.Temp_index+1;
ELSIF gvl.To_Rob_Ready_string=TRUE AND gvl.Robot_get_string=TRUE THEN 
	gvl.To_Rob_Ready_string:=FALSE; 
	IF gvl.Temp_index=gvl.Num_seqence+1 THEN 
		GVL.Stat_sending_string:=FALSE; 
		gvl.Temp_index:=0;
		gvl.Num_seqence:=0;
	END_IF
END_IF

4) Ostatnim krokiem jest przypisanie zmiennych do ramki komunikacyjnej. Do robota będzie przesyłany: numer ID, liczba sekwencji, numer w kodzie ASCII 16 kolejnych znaków. Dodatkowo bit statusowy, że dane są gotowe i jeden wejściowy od robota z potwierdzeniem odczytania. W tym celu zarezerwowane zostaną bajty wyjściowe od numeru 3 do 20. Dodatkowo w bajcie pierwszym przypisany zostanie sygnał przekazywany do robota o gotowości danych.

Sygnał od robota w momencie doczytania informacji zostanie przypisany do 18 bajtu wejściowego, jak na obrazie poniżej:

Po powyższych zmianach aplikacja gotowa jest, aby wysyłać dane tekstowe ze sterownika PLC do kontrolera robota Kawasaki Robotics. Wystarczy wywołać w PLC funkcję Send_String(„tekst do wysłania”,1).

Działająca aplikacja

Aby przetestować aplikację, dodane zostaną dwa obiekty na wizualizacji, jeden aby wpisać tekst, który powinien być wysłany do robota, oraz przycisk aktywujący wysłanie danych.

Najpierw należy dodać trzy nowe zmienne do globalnej listy, aby móc obsłużyć dane na ekranie sterownika:

Text_to_robot_visu:STRING; // variable to write text on main screen
Send_visu_stat:BOOL; // bit to call send string function

Na ekranie głównym należy dodać dwa nowe elementy, pole tekstowe (1) oraz przycisk (2).

W polu tekstowym należy ustawić wybrany opis, w tym przypadku będzie to „Text to Robot: %s”, gdzie %s będzie to wyświetlany ciąg znaków przygotowany przez użytkownika do wysyłania. Następnie jako Input w zakładce OnMouseClick należy wybrać wpisanie zmiennej i wybranie klawiatury ekranowej. Pozwoli to na wpisanie przez użytkownika na ekranie tekstu który ma być przesłany do robota. W tym celu w polu Text variable zostanie również przypisana zmienna, która została wcześniej utworzona: GVL.Text_to_robot_visu.

Przycisk będzie służył do wyzwalania procesu wysyłania, nazwa przycisku została zdefiniowana jako „Send text”. Jako Input -> OnMouseClick przypisana została funkcja:

gvl.Send_visu_stat:=Send_String(gvl.Text_to_robot_visu,1);

która pobiera ciąg znaków z okna, w którym użytkownik go wpisał, a następnie przesyła do funkcji, którą stworzyliśmy w tej części poradnika z identyfikatorem. Dodatkowo została zdefinowana zmiana koloru przycisku w czasie wysyłania znaku, ToggleColor: GVL.Stat_sending_string.

W momencie pobrania całego ciągu znaków, robot wyświetli ten tekst w terminalu na teach pendancie, wysyłanie nie wpływa znacząco na częstotliwość odświeżania danych lub przesyłania innych informacji.

W rezultacie można zdefiniować ciąg znaków i łatwo przesłać go do robota:

W kolejnej części dowiesz się, jak połączyć poprzednie części poradnika dotyczące obsługi tekstów i przesłać nazwę programu, który ma być wykonywany oraz pobrać z robota całą listę opisów błędu, nie tylko kod błędu.

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: 0 / 5. Ilość ocen: 0

Ten artykuł nie był jeszcze oceniony.

Zadaj pytanie

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