[Kurs Qt] Asynchroniczna komunikacja portów

W poprzedniej części tego kursu powiedzieliśmy sobie o synchronicznej wymianie informacji pomiędzy portami, które było całkiem przyjemne i odbywało się na zasadzie: wyślij_dane-odbierz_dane-wyślij_dane-…. Takie rozwiązanie nie zawsze jest praktyczne ponieważ zakłada że oczekiwać na dane będziemy jeżeli po wysłaniu jakiegoś sygnału.

Dzisiaj zajmiemy się asynchroniczną komunikacją pomiędzy portami, czyli taką która zakłada, że będziemy w stanie odebrać dane w dowolnej chwili działania programu.

 

Przygotowanie


Tradycyjnie przygotujmy sobie okienko naszego programu, którego zadaniem będzie mierzenie temperatury w losowych momentach + nasz program będzie mógł wysłać żądanie o zmierzenie jej w tym momencie. Jak można się domyśleć wykorzystam tutaj Arduino Uno, z którego korzystaliśmy ostatnim razem oraz czujnik temperatury LM35.

Nasze okienko jest maksymalnie proste, składa się z widgetu imitującego wyświetlacz LCD, który będzie pokazywał aktualną temperaturę, TimeEdit  do wyświetlania ostatniej aktualizacji (wyłączyłem możliwość edytowania czasu) oraz przycisku do natychmiastowego mierzenia czasu.

Wyjątkowo słowo komentarza do tego kodu: z racji, nie możemy pauzować programu za pomocą delay()  bo chcemy mieć możliwość w dowolnej chwili interakcję z programem, tzn. wymuszenie w każdej chwili pobrania temperatury, którą wyślemy jako string.

Tym razem jako znak specjalny dla arduino dostajemy !, co oznacza rozkaz podesłania temperatury oraz @ jako początek wiadomości i $ oznaczający koniec transmisji.

Nie zapomnijmy o dodaniu linii do pliku .pro:  QT += serialport w naszym projekcie.

 

Potrzebne funkcje, zmienne


Czyli coś w rodzaju, krótkiego przypomnienia tego co będziemy używać, a także wstępny wygląd plików nagłówkowych/źródłowych.

Na razie chyba nie potrzeba, żadnego komentarza ponieważ to wszystko znamy z poprzedniej lekcji.

Do tego całego pliku przyda się kilka słów wyjaśnienia.

Nie ukrywam, że znowu poszedłem na łatwiznę i aby nie zajmować się wyborem portu z menu, otwieraniem go, itp czyli zamiast zajmować się rzeczami, które zrobiliśmy ostatnio tak tutaj zakładam, że do laptopa mamy podłączone dokładnie 1 urządzenie, które może się w ten sposób komunikować inaczej dostajemy prośbę o podłączenie urządzenia lub w przypadku odmowy zamykamy program.

Pozostały kod powinien być jasny dlaczego pojawił się w tej, a nie innej formie. Czas na meritum tej lekcji.

Asynchroniczna komunikacja portów


W asynchronicznej komunikacji charakterystyczną cechą jest to, że bloki wiadomości posiadają znak początku i końca bloku, jest to o tyle ważne, że przy jej odpieraniu należy w odpowiedni sposób ją „skleić”, czyli musimy wiedzieć kiedy ona się zaczęła, a kiedy się kończy, np zdanie: „Hello World”, może być wysłane jako: „He” „ll” „o ” „Wor” „ld”, „Hello World”, albo na wiele innych sposobów, w momencie gdy mamy kilka wiadomości może się zdarzyć, że zostanie sklejone ze sobą kilka wiadomości.

Ta funkcja jest dość łatwa i zostaje wywołana już po zakończeniu wczytywania danych. Jest chyba dość trywialna więc zachęcam do samodzielnej analizy.

Ta funkcja ma za zadanie wczytanie całej liczby, jej konstrukcja jest już nam w jakiś sposób znana z poprzedniej lekcji. Zostaje ona uruchomiona przez sygnał.

Jej konstrukcja jest dość wadliwa bo zakłada, że zawsze pierwszym elementem jest @ (i tak powinno być, chyba że jakieś dane by się zagubiły), a ostatnim $, co już nie zawsze może się zdarzyć i można to nieco poprawić poprzez wyszukanie fraz zaczynających się od @ i kończących $ (możesz to potraktować jako zadanie domowe).

 

Podsumowanie


Dziś w tej nieco krótkiej lekcji wykonaliśmy program, który może komunikować się w sposób asynchroniczny z innym urządzeniem.

W kolejnej lekcji najprawdopodobniej odstawimy tymczasowo Arduino, bo zajmiemy się komunikacją z bazą danych (chyba że macie inną propozycję).

Jak zwykle w razie pytań do tej lekcji, problemów, albo po prostu chęci wyrażenia swojego zdania zapraszam do systemu komentarzy.

[GitHub]