Temat: LabVIEW - obsługa portu szeregowego

Do komunikacji szeregowej w środowisku LabVIEW wykorzystujemy bloczki z grupy Instrument I/O -> Serial lub Instrument I/O -> VISA. Aby bloczki te były dostępne, należy upewnić się, że zainstalowane zostały sterowniki Device Drivers.

Zaczynamy od umieszczenia na diagramie blokowym kontrolek realizujących nawiązanie oraz zamknięcię sesji połączenia z portem szeregowym. Są to odpowiednio VISA Open oraz VISA Close dostępne w palecie VISA -> VISA Advanced.

http://www.student.mvlab.pl/wiedza/img/m/2/t/p17ukc1li318lb55ilp11nje1i623.png
Rysunek 1 kontrolki realizujące połączenie z portem szeregowym

Zastosowanie powyższych kontrolek spowoduje nawiązanie połączenia z użyciem domyślnych parametrów (baud rate: 9600, data bits: 8, parity: none, stop bits: 1, flow control: none).

Jeżeli chcemy komunikować się z wykorzystaniem parametrów transmisji innych niż domyślne, zamiast z VISA Open możemy skorzystać z kontrolki VISA Configure Serial Port, dostępnej w palecie Serial.

http://www.student.mvlab.pl/wiedza/img/m/2/t/p17ukc1li411r6pt510pku1o2t54.png
Rysunek 2 Konfiguracja parametrów portu szeregowego

http://www.student.mvlab.pl/wiedza/img/m/2/t/p17ukc1li4f1j1c1j1qiq1qus1qf05.png
Rysunek 3 Odbieranie danych z portu szeregowego

Aby zrealizować odbieranie danych z portu szeregowego, pomiędzy kontrolki otwarcia i zamknięcia sesji wstawiamy pętlę while, w której będziemy sprawdzać, czy w buforze portu znajdują się dane gotowe do odczytu. W tym celu stosujemy bloczek Bytes at port, dostępny w palecie Serial. Jeżeli wartość zwrócona przez ten bloczek jest większa od 0, przekazujemy ją do kontrolki VISA Read, co spowoduje odczytanie z portu takiej liczby bajtów, jaka aktualnie znajduje się w nim do odczytu. Odczytany w ten sposób komunikat możemy wyświetlić lub przesłać do dalszego przetwarzania.

Stosujemy w tym przypadku standardowy szablon aplikacji z pętlą while, z okresem taktowania określonym przez kontrolkę Wait until nex ms multiple, warunkiem stopu aktywnym w momencie naciśnięcia przez użytkownika przycisku Stop na panelu frontowym.

Odporność na błędy

Praktyka pokazuje, że taki sposób odczytu danych z portu szeregowego nie jest odporny na mogące pojawić się w trakcie komunikacji zakłócenia. Na przykład możliwa jest sytuacja, w której komunikat o całkowitej długości 10 bajtów, pojawi się w buforze w dwóch partiach, po 6 i 4 bajty. Wówczas kontrolka Bytes at port zwróci najpierw wartość 6, a w kolejnej iteracji wartość 4, co spowoduje odczytanie i przesłanie przez program do dalszego przetwarzania dwóch osobnych fragmentów, zamiast całego komunikatu. Może to spowodować błąd lub niepoprawne rozpoznanie treści komunikatu przez kolejne bloczki.

Aby uchronić się przed taką sytuacją, stosujemy podczas odczytu z portu szeregowego dodatkowy bufor, w którym przechowujemy dane do momentu otrzymania kompletnego komunikatu. W tym celu konieczne jest określenie, jakim znakiem kończy się dany komunikat, najczęściej jest to znak końca linii ‘\n’.

Aby zrealizować doklejanie każdego nowo odczytanego napisu do bufora, stosujemy mechanizm rejestru przesuwnego. Przed uruchomieniem pętli while jako wartość początkową rejestru ustawiamy stałą będącą pustym napisem (Empty String Constant). Każdorazowo odczytane dane z portu szeregowego doklejamy do bufora przy pomocy kontrolki Concatenate Strings. Jednocześnie sprawdzamy, czy ostatni znak odczytanego napisu jest równy znakowi końca linii. W tym celu stosujemy kontrolkę String Subset, której jako offset podajemy długość napisu określoną przez bloczek String Length, a następnie pomniejszoną o 1, a jako length wartość 1. Jeżeli stwierdzimy, że otrzymaliśmy cały komunikat, wyświetlamy go lub przesyłamy do dalszego przetwarzania, a do rejestru przesuwnego przesyłamy pusty napis. Jeżeli komunikat jeszcze nie jest kompletny, aktualnie znajdujące się w buforze dane nie są przetwarzane, lecz przesyłane poprzez rejestr przesuwny na wejście kolejnej iteracji pętli while.

http://www.student.mvlab.pl/wiedza/img/m/2/t/p17ukc1li52gqti1nq91gbnt106.png
Rysunek 4 Odbieranie danych z wykorzystaniem bufora

Odbieranie oraz wysyłanie danych

Jeżeli chcemy w programie umożliwić oprócz odbierania danych również ich nadawanie poprzez wysyłanie wpisywanych przez użytkownika komunikatów, możemy do tego celu wykorzystać strukturę zdarzeniową Event Structure.
Do odbierania danych wykorzystujemy zdarzenie Timeout, którego parametr czasowy określamy, tak jak poprzednio ustawiony okres taktowania pętli while.

http://www.student.mvlab.pl/wiedza/img/m/2/t/p17ukc1li5qo1deoi801408jcc7.png
Rysunek 5 Zdarzeniowe odbieranie danych

Wysyłanie danych z kontrolki tekstowej Message będzie realizowane po naciśnięciu przez użytkownika przycisku Send. W tym celu dodajemy do listy zdarzeń struktury Event zdarzenie „Send” : Mouse up. Wewnątrz diagramu dla tego zdarzenia umieszczamy bloczek VISA Write, na którego wejście przesyłamy wpisany przez użytkownika komunikat z doklejonymi znakami powrotu karetki oraz końca linii: „\r\n”. Dodatkowo przed wysłaniem komunikatu sprawdzamy, czy nie jest on pusty przy pomocy kontrolki Empty String/Path?. W przypadku zaistnienia takiej sytuacji zapis nie zostanie zrealizowany.

http://www.student.mvlab.pl/wiedza/img/m/2/t/p17ukc1li5i0k1vlv280q581a7i8.png
Rysunek 6 Zdarzeniowe wysyłanie danych

Propozycje ćwiczeń i modyfikacji
1.    Zmodyfikować program tak, aby zamiast wyświetlania ostatnio odczytanego komunikatu, wyświetlana była cała historia komunikacji z automatycznym przewijaniem w miarę otrzymywania kolejnych komunikatów.
2.    Przetestować komunikację pomiędzy dwoma instancjami programu uruchomionymi na jednym komputerze z wykorzystaniem emulatora portów szeregowych COM0COM.
3.    Do sprawdzenia ostatniego znaku komunikatu wykorzystać bloczek Slice String, znajdujący się w bibliotece OpenG, instalowanej przez program VI Package Manager.

Załączniki posta

RS Terminal.vi 19.06 kB, 1189 pobrań od 2013-07-04