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.
Wymiana danych pomiędzy robotem Kawasaki Robotics a sterownikiem PLC
Zagadnienia podstawowe:
Wstęp: Integracja robota przemysłowego ze sterownikiem PLC i panelem HMI – dlaczego warto?1. Przesyłanie statusu połączenia i kodu błędów w czasie rzeczywistym.
2. Przesyłanie danych robota (typ, numer seryjny, godziny pracy i zużyta energia).
3. Przesyłanie dedykowanych sygnałów wejściowych i wyjściowych.
4. Przesyłanie parametrów ruchu w czasie rzeczywistym i informacji o wykonanym programie.
5. Przesyłanie aktualnej pozycji i dystansu do kolejnego punktu.
Zagadnienia zaawansowane:
6. Ogólna modyfikacja komunikacji i zmiana typu danych.7. Przesyłanie dużych ilości danych przy użyciu ograniczonej liczby zajętych bitów – zwielokrotnianie danych.
8. Wysyłanie zmiennej tekstowej za pośrednictwem standardowego protokołu komunikacyjnego.
9. Odbieranie zmiennej tekstowej za pośrednictwem standardowego protokołu komunikacyjnego.
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.